@waku/rln 0.1.1-fa49e29 → 0.1.2-126bce3

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 (93) hide show
  1. package/README.md +26 -2
  2. package/bundle/assets/rln_wasm_bg-a503e304.wasm +0 -0
  3. package/bundle/index.js +69844 -44998
  4. package/dist/codec.d.ts +7 -4
  5. package/dist/codec.js +15 -5
  6. package/dist/codec.js.map +1 -1
  7. package/dist/{constants.js → contract/constants.js} +3 -3
  8. package/dist/contract/constants.js.map +1 -0
  9. package/dist/contract/index.d.ts +2 -0
  10. package/dist/contract/index.js +3 -0
  11. package/dist/contract/index.js.map +1 -0
  12. package/dist/{rln_contract.d.ts → contract/rln_contract.d.ts} +13 -11
  13. package/dist/{rln_contract.js → contract/rln_contract.js} +50 -33
  14. package/dist/contract/rln_contract.js.map +1 -0
  15. package/dist/create.d.ts +2 -0
  16. package/dist/create.js +8 -0
  17. package/dist/create.js.map +1 -0
  18. package/dist/identity.d.ts +9 -0
  19. package/dist/identity.js +24 -0
  20. package/dist/identity.js.map +1 -0
  21. package/dist/index.d.ts +8 -5
  22. package/dist/index.js +8 -12
  23. package/dist/index.js.map +1 -1
  24. package/dist/keystore/cipher.js +1 -1
  25. package/dist/keystore/cipher.js.map +1 -1
  26. package/dist/keystore/credential_validation_generated.js.map +1 -1
  27. package/dist/keystore/index.d.ts +2 -0
  28. package/dist/keystore/index.js.map +1 -1
  29. package/dist/keystore/keystore.d.ts +11 -11
  30. package/dist/keystore/keystore.js +33 -21
  31. package/dist/keystore/keystore.js.map +1 -1
  32. package/dist/keystore/keystore_validation_generated.js.map +1 -1
  33. package/dist/keystore/schema_validator.js.map +1 -1
  34. package/dist/keystore/types.d.ts +25 -5
  35. package/dist/message.d.ts +1 -1
  36. package/dist/message.js +7 -4
  37. package/dist/message.js.map +1 -1
  38. package/dist/proof.d.ts +21 -0
  39. package/dist/proof.js +49 -0
  40. package/dist/proof.js.map +1 -0
  41. package/dist/resources/verification_key.d.ts +9 -9
  42. package/dist/resources/witness_calculator.js.map +1 -0
  43. package/dist/rln.d.ts +55 -46
  44. package/dist/rln.js +135 -174
  45. package/dist/rln.js.map +1 -1
  46. package/dist/root_tracker.js +5 -2
  47. package/dist/root_tracker.js.map +1 -1
  48. package/dist/utils/bytes.d.ts +20 -0
  49. package/dist/utils/bytes.js +64 -0
  50. package/dist/utils/bytes.js.map +1 -0
  51. package/dist/utils/epoch.js.map +1 -0
  52. package/dist/utils/hash.d.ts +2 -0
  53. package/dist/utils/hash.js +13 -0
  54. package/dist/utils/hash.js.map +1 -0
  55. package/dist/utils/index.d.ts +4 -0
  56. package/dist/utils/index.js +5 -0
  57. package/dist/utils/index.js.map +1 -0
  58. package/dist/utils/metamask.d.ts +2 -0
  59. package/dist/utils/metamask.js +12 -0
  60. package/dist/utils/metamask.js.map +1 -0
  61. package/dist/zerokit.d.ts +19 -0
  62. package/dist/zerokit.js +105 -0
  63. package/dist/zerokit.js.map +1 -0
  64. package/package.json +22 -27
  65. package/src/codec.ts +18 -9
  66. package/src/create.ts +9 -0
  67. package/src/identity.ts +27 -0
  68. package/src/index.ts +10 -19
  69. package/src/message.ts +5 -5
  70. package/src/proof.ts +67 -0
  71. package/src/rln.ts +219 -260
  72. package/src/root_tracker.ts +4 -1
  73. package/src/zerokit.ts +181 -0
  74. package/bundle/assets/rln_wasm_bg-6f96f821.wasm +0 -0
  75. package/dist/.tsbuildinfo +0 -1
  76. package/dist/byte_utils.d.ts +0 -7
  77. package/dist/byte_utils.js +0 -33
  78. package/dist/byte_utils.js.map +0 -1
  79. package/dist/constants.js.map +0 -1
  80. package/dist/epoch.js.map +0 -1
  81. package/dist/rln_contract.js.map +0 -1
  82. package/dist/witness_calculator.js.map +0 -1
  83. package/src/byte_utils.ts +0 -49
  84. package/src/constants.ts +0 -68
  85. package/src/epoch.ts +0 -30
  86. package/src/rln_contract.ts +0 -346
  87. package/src/witness_calculator.d.ts +0 -8
  88. package/src/witness_calculator.js +0 -335
  89. /package/dist/{constants.d.ts → contract/constants.d.ts} +0 -0
  90. /package/dist/{witness_calculator.d.ts → resources/witness_calculator.d.ts} +0 -0
  91. /package/dist/{witness_calculator.js → resources/witness_calculator.js} +0 -0
  92. /package/dist/{epoch.d.ts → utils/epoch.d.ts} +0 -0
  93. /package/dist/{epoch.js → utils/epoch.js} +0 -0
package/src/rln.ts CHANGED
@@ -1,35 +1,32 @@
1
- import type { IRateLimitProof } from "@waku/interfaces";
2
- import { default as init } from "@waku/zerokit-rln-wasm";
1
+ import { createDecoder, createEncoder } from "@waku/core";
2
+ import type {
3
+ ContentTopic,
4
+ IDecodedMessage,
5
+ EncoderOptions as WakuEncoderOptions
6
+ } from "@waku/interfaces";
7
+ import init from "@waku/zerokit-rln-wasm";
3
8
  import * as zerokitRLN from "@waku/zerokit-rln-wasm";
4
-
5
- import { buildBigIntFromUint8Array, writeUIntLE } from "./byte_utils.js";
6
- import { dateToEpoch, epochIntToBytes } from "./epoch.js";
9
+ import { ethers } from "ethers";
10
+
11
+ import {
12
+ createRLNDecoder,
13
+ createRLNEncoder,
14
+ type RLNDecoder,
15
+ type RLNEncoder
16
+ } from "./codec.js";
17
+ import { RLNContract, SEPOLIA_CONTRACT } from "./contract/index.js";
18
+ import { IdentityCredential } from "./identity.js";
19
+ import { Keystore } from "./keystore/index.js";
20
+ import type {
21
+ DecryptedCredentials,
22
+ EncryptedCredentials
23
+ } from "./keystore/index.js";
24
+ import { KeystoreEntity, Password } from "./keystore/types.js";
7
25
  import verificationKey from "./resources/verification_key.js";
8
- import * as wc from "./witness_calculator.js";
9
- import { WitnessCalculator } from "./witness_calculator.js";
10
-
11
- /**
12
- * Concatenate Uint8Arrays
13
- * @param input
14
- * @returns concatenation of all Uint8Array received as input
15
- */
16
- function concatenate(...input: Uint8Array[]): Uint8Array {
17
- let totalLength = 0;
18
- for (const arr of input) {
19
- totalLength += arr.length;
20
- }
21
- const result = new Uint8Array(totalLength);
22
- let offset = 0;
23
- for (const arr of input) {
24
- result.set(arr, offset);
25
- offset += arr.length;
26
- }
27
- return result;
28
- }
29
-
30
- const stringEncoder = new TextEncoder();
31
-
32
- const DEPTH = 20;
26
+ import * as wc from "./resources/witness_calculator.js";
27
+ import { WitnessCalculator } from "./resources/witness_calculator.js";
28
+ import { extractMetaMaskSigner } from "./utils/index.js";
29
+ import { Zerokit } from "./zerokit.js";
33
30
 
34
31
  async function loadWitnessCalculator(): Promise<WitnessCalculator> {
35
32
  const url = new URL("./resources/rln.wasm", import.meta.url);
@@ -48,280 +45,242 @@ async function loadZkey(): Promise<Uint8Array> {
48
45
  * @returns RLNInstance
49
46
  */
50
47
  export async function create(): Promise<RLNInstance> {
51
- await init();
48
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
+ await (init as any)?.();
52
50
  zerokitRLN.init_panic_hook();
51
+
53
52
  const witnessCalculator = await loadWitnessCalculator();
54
53
  const zkey = await loadZkey();
54
+
55
+ const stringEncoder = new TextEncoder();
55
56
  const vkey = stringEncoder.encode(JSON.stringify(verificationKey));
57
+
58
+ const DEPTH = 20;
56
59
  const zkRLN = zerokitRLN.newRLN(DEPTH, zkey, vkey);
57
- return new RLNInstance(zkRLN, witnessCalculator);
58
- }
60
+ const zerokit = new Zerokit(zkRLN, witnessCalculator);
59
61
 
60
- export class IdentityCredential {
61
- constructor(
62
- public readonly IDTrapdoor: Uint8Array,
63
- public readonly IDNullifier: Uint8Array,
64
- public readonly IDSecretHash: Uint8Array,
65
- public readonly IDCommitment: Uint8Array,
66
- public readonly IDCommitmentBigInt: bigint
67
- ) {}
68
-
69
- static fromBytes(memKeys: Uint8Array): IdentityCredential {
70
- const idTrapdoor = memKeys.subarray(0, 32);
71
- const idNullifier = memKeys.subarray(32, 64);
72
- const idSecretHash = memKeys.subarray(64, 96);
73
- const idCommitment = memKeys.subarray(96);
74
- const idCommitmentBigInt = buildBigIntFromUint8Array(idCommitment);
75
-
76
- return new IdentityCredential(
77
- idTrapdoor,
78
- idNullifier,
79
- idSecretHash,
80
- idCommitment,
81
- idCommitmentBigInt
82
- );
83
- }
62
+ return new RLNInstance(zerokit);
84
63
  }
85
64
 
86
- const proofOffset = 128;
87
- const rootOffset = proofOffset + 32;
88
- const epochOffset = rootOffset + 32;
89
- const shareXOffset = epochOffset + 32;
90
- const shareYOffset = shareXOffset + 32;
91
- const nullifierOffset = shareYOffset + 32;
92
- const rlnIdentifierOffset = nullifierOffset + 32;
93
-
94
- export class ProofMetadata {
95
- constructor(
96
- public readonly nullifier: Uint8Array,
97
- public readonly shareX: Uint8Array,
98
- public readonly shareY: Uint8Array,
99
- public readonly externalNullifier: Uint8Array
100
- ) {}
101
- }
102
- export class Proof implements IRateLimitProof {
103
- readonly proof: Uint8Array;
104
- readonly merkleRoot: Uint8Array;
105
- readonly epoch: Uint8Array;
106
- readonly shareX: Uint8Array;
107
- readonly shareY: Uint8Array;
108
- readonly nullifier: Uint8Array;
109
- readonly rlnIdentifier: Uint8Array;
110
-
111
- constructor(proofBytes: Uint8Array) {
112
- if (proofBytes.length < rlnIdentifierOffset) throw "invalid proof";
113
- // parse the proof as proof<128> | share_y<32> | nullifier<32> | root<32> | epoch<32> | share_x<32> | rln_identifier<32>
114
- this.proof = proofBytes.subarray(0, proofOffset);
115
- this.merkleRoot = proofBytes.subarray(proofOffset, rootOffset);
116
- this.epoch = proofBytes.subarray(rootOffset, epochOffset);
117
- this.shareX = proofBytes.subarray(epochOffset, shareXOffset);
118
- this.shareY = proofBytes.subarray(shareXOffset, shareYOffset);
119
- this.nullifier = proofBytes.subarray(shareYOffset, nullifierOffset);
120
- this.rlnIdentifier = proofBytes.subarray(
121
- nullifierOffset,
122
- rlnIdentifierOffset
123
- );
124
- }
65
+ type StartRLNOptions = {
66
+ /**
67
+ * If not set - will extract MetaMask account and get signer from it.
68
+ */
69
+ signer?: ethers.Signer;
70
+ /**
71
+ * If not set - will use default SEPOLIA_CONTRACT address.
72
+ */
73
+ registryAddress?: string;
74
+ /**
75
+ * Credentials to use for generating proofs and connecting to the contract and network.
76
+ * If provided used for validating the network chainId and connecting to registry contract.
77
+ */
78
+ credentials?: EncryptedCredentials | DecryptedCredentials;
79
+ };
80
+
81
+ type RegisterMembershipOptions =
82
+ | { signature: string }
83
+ | { identity: IdentityCredential };
84
+
85
+ type WakuRLNEncoderOptions = WakuEncoderOptions & {
86
+ credentials: EncryptedCredentials | DecryptedCredentials;
87
+ };
125
88
 
126
- extractMetadata(): ProofMetadata {
127
- const externalNullifier = poseidonHash(this.epoch, this.rlnIdentifier);
128
- return new ProofMetadata(
129
- this.nullifier,
130
- this.shareX,
131
- this.shareY,
132
- externalNullifier
133
- );
134
- }
135
- }
89
+ export class RLNInstance {
90
+ private started = false;
91
+ private starting = false;
136
92
 
137
- export function proofToBytes(p: IRateLimitProof): Uint8Array {
138
- return concatenate(
139
- p.proof,
140
- p.merkleRoot,
141
- p.epoch,
142
- p.shareX,
143
- p.shareY,
144
- p.nullifier,
145
- p.rlnIdentifier
146
- );
147
- }
93
+ private _contract: undefined | RLNContract;
94
+ private _signer: undefined | ethers.Signer;
148
95
 
149
- export function poseidonHash(...input: Array<Uint8Array>): Uint8Array {
150
- const inputLen = writeUIntLE(new Uint8Array(8), input.length, 0, 8);
151
- const lenPrefixedData = concatenate(inputLen, ...input);
152
- return zerokitRLN.poseidonHash(lenPrefixedData);
153
- }
96
+ private keystore = Keystore.create();
97
+ private _credentials: undefined | DecryptedCredentials;
154
98
 
155
- export function sha256(input: Uint8Array): Uint8Array {
156
- const inputLen = writeUIntLE(new Uint8Array(8), input.length, 0, 8);
157
- const lenPrefixedData = concatenate(inputLen, input);
158
- return zerokitRLN.hash(lenPrefixedData);
159
- }
99
+ constructor(public zerokit: Zerokit) {}
160
100
 
161
- export class RLNInstance {
162
- constructor(
163
- private zkRLN: number,
164
- private witnessCalculator: WitnessCalculator
165
- ) {}
166
-
167
- generateIdentityCredentials(): IdentityCredential {
168
- const memKeys = zerokitRLN.generateExtendedMembershipKey(this.zkRLN); // TODO: rename this function in zerokit rln-wasm
169
- return IdentityCredential.fromBytes(memKeys);
101
+ public get contract(): undefined | RLNContract {
102
+ return this._contract;
170
103
  }
171
104
 
172
- generateSeededIdentityCredential(seed: string): IdentityCredential {
173
- const seedBytes = stringEncoder.encode(seed);
174
- // TODO: rename this function in zerokit rln-wasm
175
- const memKeys = zerokitRLN.generateSeededExtendedMembershipKey(
176
- this.zkRLN,
177
- seedBytes
178
- );
179
- return IdentityCredential.fromBytes(memKeys);
105
+ public get signer(): undefined | ethers.Signer {
106
+ return this._signer;
180
107
  }
181
108
 
182
- insertMember(idCommitment: Uint8Array): void {
183
- zerokitRLN.insertMember(this.zkRLN, idCommitment);
184
- }
185
-
186
- insertMembers(index: number, ...idCommitments: Array<Uint8Array>): void {
187
- // serializes a seq of IDCommitments to a byte seq
188
- // the order of serialization is |id_commitment_len<8>|id_commitment<var>|
189
- const idCommitmentLen = writeUIntLE(
190
- new Uint8Array(8),
191
- idCommitments.length,
192
- 0,
193
- 8
194
- );
195
- const idCommitmentBytes = concatenate(idCommitmentLen, ...idCommitments);
196
- zerokitRLN.setLeavesFrom(this.zkRLN, index, idCommitmentBytes);
197
- }
109
+ public async start(options: StartRLNOptions = {}): Promise<void> {
110
+ if (this.started || this.starting) {
111
+ return;
112
+ }
198
113
 
199
- deleteMember(index: number): void {
200
- zerokitRLN.deleteLeaf(this.zkRLN, index);
114
+ this.starting = true;
115
+
116
+ try {
117
+ const { credentials, keystore } =
118
+ await RLNInstance.decryptCredentialsIfNeeded(options.credentials);
119
+ const { signer, registryAddress } = await this.determineStartOptions(
120
+ options,
121
+ credentials
122
+ );
123
+
124
+ if (keystore) {
125
+ this.keystore = keystore;
126
+ }
127
+
128
+ this._credentials = credentials;
129
+ this._signer = signer!;
130
+ this._contract = await RLNContract.init(this, {
131
+ registryAddress: registryAddress!,
132
+ signer: signer!
133
+ });
134
+ this.started = true;
135
+ } finally {
136
+ this.starting = false;
137
+ }
201
138
  }
202
139
 
203
- getMerkleRoot(): Uint8Array {
204
- return zerokitRLN.getRoot(this.zkRLN);
205
- }
140
+ private async determineStartOptions(
141
+ options: StartRLNOptions,
142
+ credentials: KeystoreEntity | undefined
143
+ ): Promise<StartRLNOptions> {
144
+ let chainId = credentials?.membership.chainId;
145
+ const registryAddress =
146
+ credentials?.membership.address ||
147
+ options.registryAddress ||
148
+ SEPOLIA_CONTRACT.address;
149
+
150
+ if (registryAddress === SEPOLIA_CONTRACT.address) {
151
+ chainId = SEPOLIA_CONTRACT.chainId;
152
+ }
206
153
 
207
- serializeMessage(
208
- uint8Msg: Uint8Array,
209
- memIndex: number,
210
- epoch: Uint8Array,
211
- idKey: Uint8Array
212
- ): Uint8Array {
213
- // calculate message length
214
- const msgLen = writeUIntLE(new Uint8Array(8), uint8Msg.length, 0, 8);
154
+ const signer = options.signer || (await extractMetaMaskSigner());
155
+ const currentChainId = await signer.getChainId();
215
156
 
216
- // Converting index to LE bytes
217
- const memIndexBytes = writeUIntLE(new Uint8Array(8), memIndex, 0, 8);
157
+ if (chainId && chainId !== currentChainId) {
158
+ throw Error(
159
+ `Failed to start RLN contract, chain ID of contract is different from current one: contract-${chainId}, current network-${currentChainId}`
160
+ );
161
+ }
218
162
 
219
- // [ id_key<32> | id_index<8> | epoch<32> | signal_len<8> | signal<var> ]
220
- return concatenate(idKey, memIndexBytes, epoch, msgLen, uint8Msg);
163
+ return {
164
+ signer,
165
+ registryAddress
166
+ };
221
167
  }
222
168
 
223
- async generateRLNProof(
224
- msg: Uint8Array,
225
- index: number,
226
- epoch: Uint8Array | Date | undefined,
227
- idSecretHash: Uint8Array
228
- ): Promise<IRateLimitProof> {
229
- if (epoch == undefined) {
230
- epoch = epochIntToBytes(dateToEpoch(new Date()));
231
- } else if (epoch instanceof Date) {
232
- epoch = epochIntToBytes(dateToEpoch(epoch));
169
+ private static async decryptCredentialsIfNeeded(
170
+ credentials?: EncryptedCredentials | DecryptedCredentials
171
+ ): Promise<{ credentials?: DecryptedCredentials; keystore?: Keystore }> {
172
+ if (!credentials) {
173
+ return {};
233
174
  }
234
175
 
235
- if (epoch.length != 32) throw "invalid epoch";
236
- if (idSecretHash.length != 32) throw "invalid id secret hash";
237
- if (index < 0) throw "index must be >= 0";
176
+ if ("identity" in credentials) {
177
+ return { credentials };
178
+ }
238
179
 
239
- const serialized_msg = this.serializeMessage(
240
- msg,
241
- index,
242
- epoch,
243
- idSecretHash
244
- );
245
- const rlnWitness = zerokitRLN.getSerializedRLNWitness(
246
- this.zkRLN,
247
- serialized_msg
248
- );
249
- const inputs = zerokitRLN.RLNWitnessToJson(this.zkRLN, rlnWitness);
250
- const calculatedWitness = await this.witnessCalculator.calculateWitness(
251
- inputs,
252
- false
253
- ); // no sanity check being used in zerokit
254
-
255
- const proofBytes = zerokitRLN.generate_rln_proof_with_witness(
256
- this.zkRLN,
257
- calculatedWitness,
258
- rlnWitness
180
+ const keystore = Keystore.fromString(credentials.keystore);
181
+
182
+ if (!keystore) {
183
+ return {};
184
+ }
185
+
186
+ const decryptedCredentials = await keystore.readCredential(
187
+ credentials.id,
188
+ credentials.password
259
189
  );
260
190
 
261
- return new Proof(proofBytes);
191
+ return {
192
+ keystore,
193
+ credentials: decryptedCredentials
194
+ };
262
195
  }
263
196
 
264
- verifyRLNProof(
265
- proof: IRateLimitProof | Uint8Array,
266
- msg: Uint8Array
267
- ): boolean {
268
- let pBytes: Uint8Array;
269
- if (proof instanceof Uint8Array) {
270
- pBytes = proof;
271
- } else {
272
- pBytes = proofToBytes(proof);
197
+ public async registerMembership(
198
+ options: RegisterMembershipOptions
199
+ ): Promise<undefined | DecryptedCredentials> {
200
+ if (!this.contract) {
201
+ throw Error("RLN Contract is not initialized.");
273
202
  }
274
203
 
275
- // calculate message length
276
- const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
204
+ let identity = "identity" in options && options.identity;
277
205
 
278
- return zerokitRLN.verifyRLNProof(
279
- this.zkRLN,
280
- concatenate(pBytes, msgLen, msg)
281
- );
206
+ if ("signature" in options) {
207
+ identity = this.zerokit.generateSeededIdentityCredential(
208
+ options.signature
209
+ );
210
+ }
211
+
212
+ if (!identity) {
213
+ throw Error("Missing signature or identity to register membership.");
214
+ }
215
+
216
+ return this.contract.registerWithIdentity(identity);
217
+ }
218
+
219
+ /**
220
+ * Changes credentials in use by relying on provided Keystore earlier in rln.start
221
+ * @param id: string, hash of credentials to select from Keystore
222
+ * @param password: string or bytes to use to decrypt credentials from Keystore
223
+ */
224
+ public async useCredentials(id: string, password: Password): Promise<void> {
225
+ this._credentials = await this.keystore?.readCredential(id, password);
282
226
  }
283
227
 
284
- verifyWithRoots(
285
- proof: IRateLimitProof | Uint8Array,
286
- msg: Uint8Array,
287
- ...roots: Array<Uint8Array>
288
- ): boolean {
289
- let pBytes: Uint8Array;
290
- if (proof instanceof Uint8Array) {
291
- pBytes = proof;
292
- } else {
293
- pBytes = proofToBytes(proof);
228
+ public async createEncoder(
229
+ options: WakuRLNEncoderOptions
230
+ ): Promise<RLNEncoder> {
231
+ const { credentials: decryptedCredentials } =
232
+ await RLNInstance.decryptCredentialsIfNeeded(options.credentials);
233
+ const credentials = decryptedCredentials || this._credentials;
234
+
235
+ if (!credentials) {
236
+ throw Error(
237
+ "Failed to create Encoder: missing RLN credentials. Use createRLNEncoder directly."
238
+ );
294
239
  }
295
- // calculate message length
296
- const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
297
240
 
298
- const rootsBytes = concatenate(...roots);
241
+ await this.verifyCredentialsAgainstContract(credentials);
299
242
 
300
- return zerokitRLN.verifyWithRoots(
301
- this.zkRLN,
302
- concatenate(pBytes, msgLen, msg),
303
- rootsBytes
304
- );
243
+ return createRLNEncoder({
244
+ encoder: createEncoder(options),
245
+ rlnInstance: this,
246
+ index: credentials.membership.treeIndex,
247
+ credential: credentials.identity
248
+ });
305
249
  }
306
250
 
307
- verifyWithNoRoot(
308
- proof: IRateLimitProof | Uint8Array,
309
- msg: Uint8Array
310
- ): boolean {
311
- let pBytes: Uint8Array;
312
- if (proof instanceof Uint8Array) {
313
- pBytes = proof;
314
- } else {
315
- pBytes = proofToBytes(proof);
251
+ private async verifyCredentialsAgainstContract(
252
+ credentials: KeystoreEntity
253
+ ): Promise<void> {
254
+ if (!this._contract) {
255
+ throw Error(
256
+ "Failed to verify chain coordinates: no contract initialized."
257
+ );
316
258
  }
317
259
 
318
- // calculate message length
319
- const msgLen = writeUIntLE(new Uint8Array(8), msg.length, 0, 8);
260
+ const registryAddress = credentials.membership.address;
261
+ const currentRegistryAddress = this._contract.registry.address;
262
+ if (registryAddress !== currentRegistryAddress) {
263
+ throw Error(
264
+ `Failed to verify chain coordinates: credentials contract address=${registryAddress} is not equal to registryContract address=${currentRegistryAddress}`
265
+ );
266
+ }
320
267
 
321
- return zerokitRLN.verifyWithRoots(
322
- this.zkRLN,
323
- concatenate(pBytes, msgLen, msg),
324
- new Uint8Array()
325
- );
268
+ const chainId = credentials.membership.chainId;
269
+ const network = await this._contract.registry.provider.getNetwork();
270
+ const currentChainId = network.chainId;
271
+ if (chainId !== currentChainId) {
272
+ throw Error(
273
+ `Failed to verify chain coordinates: credentials chainID=${chainId} is not equal to registryContract chainID=${currentChainId}`
274
+ );
275
+ }
276
+ }
277
+
278
+ public createDecoder(
279
+ contentTopic: ContentTopic
280
+ ): RLNDecoder<IDecodedMessage> {
281
+ return createRLNDecoder({
282
+ rlnInstance: this,
283
+ decoder: createDecoder(contentTopic)
284
+ });
326
285
  }
327
286
  }
@@ -1,5 +1,8 @@
1
1
  class RootPerBlock {
2
- constructor(public root: Uint8Array, public blockNumber: number) {}
2
+ constructor(
3
+ public root: Uint8Array,
4
+ public blockNumber: number
5
+ ) {}
3
6
  }
4
7
 
5
8
  const maxBufferSize = 20;