UNPKG

@waku/rln

Version:

RLN (Rate Limiting Nullifier) implementation for Waku

111 lines (108 loc) 4.99 kB
import { createEncoder, createDecoder } from '../../core/dist/lib/message/version_0.js'; import '../../core/dist/lib/filter/filter.js'; import '../../core/dist/lib/light_push/light_push.js'; import '../../core/dist/lib/store/store.js'; import '../../core/dist/lib/connection_manager/connection_manager.js'; import '../../interfaces/dist/protocols.js'; import '../../interfaces/dist/connection_manager.js'; import '../../interfaces/dist/health_status.js'; import '../../../node_modules/multiformats/dist/src/bases/base10.js'; import '../../../node_modules/multiformats/dist/src/bases/base16.js'; import '../../../node_modules/multiformats/dist/src/bases/base2.js'; import '../../../node_modules/multiformats/dist/src/bases/base256emoji.js'; import '../../../node_modules/multiformats/dist/src/bases/base32.js'; import '../../../node_modules/multiformats/dist/src/bases/base36.js'; import '../../../node_modules/multiformats/dist/src/bases/base58.js'; import '../../../node_modules/multiformats/dist/src/bases/base64.js'; import '../../../node_modules/multiformats/dist/src/bases/base8.js'; import '../../../node_modules/multiformats/dist/src/bases/identity.js'; import '../../../node_modules/multiformats/dist/src/codecs/json.js'; import { Logger } from '../../utils/dist/logger.js'; import '../../core/dist/lib/metadata/metadata.js'; import __wbg_init, { init_panic_hook, newRLN } from '../../../node_modules/@waku/zerokit-rln-wasm/rln_wasm.js'; import { createRLNEncoder, createRLNDecoder } from './codec.js'; import { DEFAULT_RATE_LIMIT } from './contract/constants.js'; import { RLNCredentialsManager } from './credentials_manager.js'; import verificationKey from './resources/verification_key.js'; import { builder } from './resources/witness_calculator.js'; import { Zerokit } from './zerokit.js'; const log = new Logger("waku:rln"); class RLNInstance extends RLNCredentialsManager { zerokit; /** * Create an instance of RLN * @returns RLNInstance */ static async create() { try { // eslint-disable-next-line @typescript-eslint/no-explicit-any await __wbg_init?.(); init_panic_hook(); const witnessCalculator = await RLNInstance.loadWitnessCalculator(); const zkey = await RLNInstance.loadZkey(); const stringEncoder = new TextEncoder(); const vkey = stringEncoder.encode(JSON.stringify(verificationKey)); const DEPTH = 20; const zkRLN = newRLN(DEPTH, zkey, vkey); const zerokit = new Zerokit(zkRLN, witnessCalculator, DEFAULT_RATE_LIMIT); return new RLNInstance(zerokit); } catch (error) { log.error("Failed to initialize RLN:", error); throw error; } } constructor(zerokit) { super(zerokit); this.zerokit = zerokit; } async createEncoder(options) { const { credentials: decryptedCredentials } = await RLNInstance.decryptCredentialsIfNeeded(options.credentials); const credentials = decryptedCredentials || this.credentials; if (!credentials) { throw Error("Failed to create Encoder: missing RLN credentials. Use createRLNEncoder directly."); } await this.verifyCredentialsAgainstContract(credentials); return createRLNEncoder({ encoder: createEncoder(options), rlnInstance: this, index: credentials.membership.treeIndex, credential: credentials.identity }); } createDecoder(contentTopic) { return createRLNDecoder({ rlnInstance: this, decoder: createDecoder(contentTopic) }); } static async loadWitnessCalculator() { try { const url = new URL("./resources/rln.wasm", import.meta.url); const response = await fetch(url); if (!response.ok) { throw new Error(`Failed to fetch witness calculator: ${response.status} ${response.statusText}`); } return await builder(new Uint8Array(await response.arrayBuffer()), false); } catch (error) { log.error("Error loading witness calculator:", error); throw new Error(`Failed to load witness calculator: ${error instanceof Error ? error.message : String(error)}`); } } static async loadZkey() { try { const url = new URL("./resources/rln_final.zkey", import.meta.url); const response = await fetch(url); if (!response.ok) { throw new Error(`Failed to fetch zkey: ${response.status} ${response.statusText}`); } return new Uint8Array(await response.arrayBuffer()); } catch (error) { log.error("Error loading zkey:", error); throw new Error(`Failed to load zkey: ${error instanceof Error ? error.message : String(error)}`); } } } export { RLNInstance };