UNPKG

@cryptkeeperzk/rlnjs

Version:

Client library for generating and using RLN ZK proofs, is a forked repo from main Rate-Limiting-Nullifier/rlnjs to make it work with Cryptkeeper Browser Extension using `@cryptkeeperzk/snarkjs` and `@cryptkeeperzk/ffjavascript`

329 lines (328 loc) 14.1 kB
import { Identity } from '@semaphore-protocol/identity'; import { VerificationKey } from './types'; import { IRLNRegistry } from './registry'; import { EvaluatedProof, ICache } from './cache'; import { IMessageIDCounter } from './message-id-counter'; import { RLNFullProof } from './circuit-wrapper'; import { ethers } from 'ethers'; export interface IRLN { /** * Register the user to the registry. * @param userMessageLimit The message limit of the user. * @param messageIDCounter The messageIDCounter is used to **safely** generate the latest messageID for the user. * If not provided, a new `MemoryMessageIDCounter` is created. */ register(userMessageLimit: bigint, messageIDCounter?: IMessageIDCounter): Promise<void>; /** * Withdraw the user from the registry. */ withdraw(): Promise<void>; /** * Slash the user with the given secret. * @param secretToBeSlashed The secret to be slashed. * @param receiver The address of the slash reward receiver. If not provided, * the signer will receive the reward. */ slash(secretToBeSlashed: bigint, receiver?: string): Promise<void>; /** * Create a proof for the given epoch and message. * @param epoch the timestamp of the message * @param message the message to be proved */ createProof(epoch: bigint, message: string): Promise<RLNFullProof>; /** * Verify a RLNFullProof * @param epoch the timestamp of the message * @param message the message to be proved * @param proof the RLNFullProof to be verified */ verifyProof(epoch: bigint, message: string, proof: RLNFullProof): Promise<boolean>; /** * Save a proof to the cache and check if it's a spam. * @param proof the RLNFullProof to save and detect spam * @returns result of the check. It could be VALID if the proof hasn't been seen, * or DUPLICATE if the proof has been seen before, else BREACH means it could be spam. */ saveProof(proof: RLNFullProof): Promise<EvaluatedProof>; } /** * RLN handles all operations for a RLN user, including registering, withdrawing, creating proof, verifying proof. * Please use `RLN.create` or `RLN.createWithContractRegistry` to create a RLN instance instead of * using the constructor. */ export declare class RLN implements IRLN { readonly rlnIdentifier: bigint; readonly identity: Identity; private prover?; private verifier?; private registry; private cache; messageIDCounter?: IMessageIDCounter; constructor(args: { /** Required */ /** * The unique identifier of the app using RLN. The identifier must be unique for every app. */ rlnIdentifier: bigint; /** * `IRegistry` that stores the registered users. If not provided, a new `ContractRLNRegistry` is created. * @see {@link ContractRLNRegistry} */ registry: IRLNRegistry; /** * `ICache` that stores proofs added by the user with `addProof`, and detect spams automatically. * If not provided, a new `MemoryCache` is created. * @see {@link MemoryCache} */ cache: ICache; /** * Semaphore identity of the user. If not provided, a new `Identity` is created. */ identity: Identity; /** Optional */ /** * File path of the RLN wasm file. If not provided, `createProof` will not work. * @see {@link https://github.com/Rate-Limiting-Nullifier/circom-rln/blob/main/circuits/rln.circom} */ wasmFilePath?: string | Uint8Array; /** * File path of the RLN final zkey file. If not provided, `createProof` will not work. * @see {@link https://github.com/Rate-Limiting-Nullifier/circom-rln/blob/main/circuits/rln.circom} */ finalZkeyPath?: string | Uint8Array; /** * Verification key of the RLN circuit. If not provided, `verifyProof` and `saveProof` will not work. * @see {@link https://github.com/Rate-Limiting-Nullifier/circom-rln/blob/main/circuits/rln.circom} */ verificationKey?: VerificationKey; }); /** * Create RLN instance with a custom registry */ static create(args: { /** Required */ /** * The unique identifier of the app using RLN. The identifier must be unique for every app. */ rlnIdentifier: bigint; /** * `IRegistry` that stores the registered users. * @see {@link IRegistry} */ registry: IRLNRegistry; /** Optional */ /** * Semaphore identity of the user. If not provided, a new `Identity` is created. */ identity?: Identity; /** * Tree depth of the merkle tree used by the circuit. If not provided, the default value will be used. * @default 20 */ treeDepth?: number; /** * The maximum number of epochs that the cache can store. If not provided, the default value will be used. * This is only used when `cache` is not provided. * @default 100 * @see {@link MemoryCache} */ cacheSize?: number; /** * `ICache` that stores proofs added by the user with `addProof`, and detect spams automatically. * If not provided, a new `MemoryCache` is created. * @see {@link MemoryCache} */ cache?: ICache; /** * If all of `wasmFilePath`, `finalZkeyPath`, and `verificationKey` are not given, default ones according to * the `treeDepth` are used. */ /** * File path of the RLN wasm file. If not provided, `createProof` will not work. * @see {@link https://github.com/Rate-Limiting-Nullifier/circom-rln/blob/main/circuits/rln.circom} */ wasmFilePath?: string | Uint8Array; /** * File path of the RLN final zkey file. If not provided, `createProof` will not work. * @see {@link https://github.com/Rate-Limiting-Nullifier/circom-rln/blob/main/circuits/rln.circom} */ finalZkeyPath?: string | Uint8Array; /** * Verification key of the RLN circuit. If not provided, `verifyProof` and `saveProof` will not work. * @see {@link https://github.com/Rate-Limiting-Nullifier/circom-rln/blob/main/circuits/rln.circom} */ verificationKey?: VerificationKey; }): Promise<RLN>; /** * Create RLN instance, using a deployed RLN contract as registry. */ static createWithContractRegistry(args: { /** Required */ /** * The unique identifier of the app using RLN. The identifier must be unique for every app. */ rlnIdentifier: bigint; /** * The ethers provider that is used to interact with the RLN contract. * @see {@link https://docs.ethers.io/v5/api/providers/} */ provider: ethers.Provider; /** * The address of the RLN contract. */ contractAddress: string; /** Optional */ /** * The ethers signer that is used to interact with the RLN contract. If not provided, * user can only do read-only operations. Functions like `register` and `withdraw` will not work * since they need to send transactions to interact with the RLN contract. * @see {@link https://docs.ethers.io/v5/api/signer/#Signer} */ signer?: ethers.Signer; /** * The block number where the RLN contract is deployed. If not provided, `0` will be used. * @default 0 * @see {@link https://docs.ethers.io/v5/api/providers/provider/#Provider-getLogs} */ contractAtBlock?: number; /** * Semaphore identity of the user. If not provided, a new `Identity` is created. */ identity?: Identity; /** * File path of the RLN wasm file. If not provided, `createProof` will not work. * @see {@link https://github.com/Rate-Limiting-Nullifier/circom-rln/blob/main/circuits/rln.circom} */ wasmFilePath?: string | Uint8Array; /** * File path of the RLN final zkey file. If not provided, `createProof` will not work. * @see {@link https://github.com/Rate-Limiting-Nullifier/circom-rln/blob/main/circuits/rln.circom} */ finalZkeyPath?: string | Uint8Array; /** * Verification key of the RLN circuit. If not provided, `verifyProof` will not work. * @see {@link https://github.com/Rate-Limiting-Nullifier/circom-rln/blob/main/circuits/rln.circom} */ verificationKey?: VerificationKey; /** * Tree depth of the merkle tree used by the circuit. If not provided, the default value will be used. * @default 20 */ treeDepth?: number; /** * File path of the wasm file for withdraw circuit. If not provided, `withdraw` will not work. * @see {@link https://github.com/Rate-Limiting-Nullifier/circom-rln/blob/main/circuits/withdraw.circom} */ withdrawWasmFilePath?: string | Uint8Array; /** * File path of the final zkey file for withdraw circuit. If not provided, `withdraw` will not work. * @see {@link https://github.com/Rate-Limiting-Nullifier/circom-rln/blob/main/circuits/withdraw.circom} */ withdrawFinalZkeyPath?: string | Uint8Array; /** Others */ /** * `ICache` that stores proofs added by the user with `addProof`, and detect spams automatically. * If not provided, a new `MemoryCache` is created. * @see {@link MemoryCache} */ cache?: ICache; /** * The maximum number of epochs that the cache can store. If not provided, the default value will be used. * This is only used when `cache` is not provided. * @default 100 * @see {@link MemoryCache} */ cacheSize?: number; }): Promise<RLN>; /** * Set a custom messageIDCounter * @param messageIDCounter The custom messageIDCounter */ setMessageIDCounter(messageIDCounter?: IMessageIDCounter): Promise<void>; /** * Set a custom cache * @param cache The custom cache */ setCache(cache: ICache): void; /** * Set a custom registry * @param registry The custom registry */ setRegistry(registry: IRLNRegistry): void; /** * Get the latest merkle root of the registry. * @returns the latest merkle root of the registry */ getMerkleRoot(): Promise<bigint>; /** * Get the identity commitment of the user. */ get identityCommitment(): bigint; private get identitySecret(); /** * Get the rate commitment of the user, i.e. hash(identitySecret, messageLimit) * @returns the rate commitment */ getRateCommitment(): Promise<bigint>; /** * @returns the user has been registered or not */ isRegistered(): Promise<boolean>; /** * @returns all rate commitments in the registry */ getAllRateCommitments(): Promise<bigint[]>; /** * User registers to the registry. * @param userMessageLimit the maximum number of messages that the user can send in one epoch * @param messageIDCounter the messageIDCounter that the user wants to use. If not provided, a new `MemoryMessageIDCounter` is created. */ register(userMessageLimit: bigint, messageIDCounter?: IMessageIDCounter): Promise<void>; /** * User withdraws from the registry. User will not receive the funds immediately, * they need to wait `freezePeriod + 1` blocks and call `releaseWithdrawal` to get the funds. */ withdraw(): Promise<void>; /** * Release the funds from the pending withdrawal requested by `withdraw`. */ releaseWithdrawal(): Promise<void>; /** * Slash a user by its identity secret. * @param secretToBeSlashed the identity secret of the user to be slashed * @param receiver the receiver of the slashed funds. If not provided, the funds will be sent to * the `signer` given in the constructor. */ slash(secretToBeSlashed: bigint, receiver?: string): Promise<void>; /** * Create a proof for the given epoch and message. * @param epoch the epoch to create the proof for * @param message the message to create the proof for * @returns the RLNFullProof */ createProof(epoch: bigint, message: string): Promise<RLNFullProof>; /** * Verify a proof is valid and indeed for `epoch` and `message`. * @param epoch the epoch to verify the proof for * @param message the message to verify the proof for * @param proof the RLNFullProof to verify * @returns true if the proof is valid, false otherwise */ verifyProof(epoch: bigint, message: string, proof: RLNFullProof): Promise<boolean>; /** * Save a proof to the cache and check if it's a spam. * @param proof the RLNFullProof to save and detect spam * @returns result of the check. `status` could be status.VALID if the proof is not a spam or invalid. * Otherwise, it will be status.DUPLICATE or status.BREACH. */ saveProof(proof: RLNFullProof): Promise<EvaluatedProof>; private checkProof; /** * Clean up the worker threads used by the prover and verifier in snarkjs * This function should be called when the user is done with the library * and wants to clean up the worker threads. * * Ref: https://github.com/iden3/snarkjs/issues/152#issuecomment-1164821515 */ static cleanUp(): void; }