UNPKG

minauth-erc721-timelock-plugin

Version:

This package contains an implementation of a MinAuth plugin that combines zero-knowledge Merkle "membership" proofs with the ability to register into to a Merkle tree with locking an Ethereum NFT.

102 lines (101 loc) 4.49 kB
/** * This module contains a prover counter-part to the Minauth ERC721 time-lock plugin. * It interacts with an Ethereum smart contract pointed by the plugin (the verifier) * to obtain public inputs for the zkproof used as the Minauth authorization mean. */ import { Field, JsonProof } from 'o1js'; import * as ZkProgram from './merkle-membership-program.js'; import { IMinAuthProver } from 'minauth/dist/plugin/plugintype.js'; import { TsInterfaceType } from 'minauth/dist/plugin/interfacekind.js'; import { VerificationKey } from 'minauth/dist/common/verificationkey.js'; import { Logger } from 'minauth/dist/plugin/logger.js'; import { IErc721TimeLock } from './erc721timelock.js'; import { BrowserProvider, JsonRpcProvider } from 'ethers'; import { UserCommitmentHex, UserSecretInput } from './commitment-types.js'; import { PluginRouter } from 'minauth/dist/plugin/pluginrouter.js'; /** * Configuration for the prover. */ export type Erc721TimelockProverConfiguration = { pluginRoutes: PluginRouter; ethereumProvider: BrowserProvider | JsonRpcProvider; logger: Logger; }; /** * The part of the proof inputs that can be automatically fetched. * NOTE: The Merkle tree root is the only public information that the proof will reveal. */ type ProofAutoInput = { merkleRoot: Field; treeWitness: ZkProgram.TreeWitness; }; /** * This is the hash that corresponds to the secret preimage. * It will not be revealed by the proof nor send anywhere. * * TODO: this is a symptopm of a bad design of the prover interface, * to be addressed later. */ export type Erc721TimelockProverPublicInputArgs = { userCommitment: UserCommitmentHex; }; /** * With this class you can build proofs and interact with `Erc721TimelockPlugin`. * The plugin monitors the state of an Ethereum contract. * The Ethereum contract implements an NFT timelock scheme. * One can lock an NFT for a given period of time along with a hash. * All the hashes behind the locked NFTs are stored in a merkle tree. * The plugin allows one to prove that they have the preimage of the hash * and thus have the right to get the authorization. * When use against suffiently large merkle tree provides a level * of privacy - the proof does not reveal which hash nor the merkle witness * for the hash. * Some care must be taken to avoid timing attacks. */ export declare class Erc721TimelockProver implements IMinAuthProver<TsInterfaceType, Erc721TimelockProverPublicInputArgs, ProofAutoInput, UserSecretInput> { protected readonly logger: Logger; protected readonly ethContract: IErc721TimeLock; /** This class uses the functionl style interface of the plugin. */ readonly __interface_tag = "ts"; /** * Build a proof for given inputs. * In order to obtain the secret hash use `buildSecretHash` from a secret user string. * NOTE that even though TreeWitness is passed as public input, it should not be known to the verifier. * TODO fix the above */ prove(autoInput: ProofAutoInput, userSecretInput: UserSecretInput): Promise<JsonProof>; buildInputAndProve(userSecretInput: UserSecretInput): Promise<JsonProof>; fetchEligibleCommitments(): Promise<{ commitments: UserCommitmentHex[]; }>; /** * Fetch the data necessary to build the proof inputs. * In this case these are Merkle trees related to the roots * passed as arguments. */ fetchPublicInputs(args: Erc721TimelockProverPublicInputArgs): Promise<ProofAutoInput>; /** * The plugin provides an auxiliary method to lock an NFT along with a commitment, * indirectly via the Ethereum contract. */ lockNft(commitment: UserCommitmentHex, tokenId: number): Promise<void>; /** * The plugin provides an auxiliary method to unlock a locked NFT after * the lock-up period is over. */ unlockNft(index: number): Promise<void>; constructor(logger: Logger, ethContract: IErc721TimeLock); static readonly __interface_tag = "ts"; /** Compile the underlying zk circuit */ static compile(): Promise<{ verificationKey: VerificationKey; }>; get ethereumProvider(): string; get lockContractAddress(): string; get erc721ContractAddress(): string; /** Initialize the prover */ static initialize(cfg: Erc721TimelockProverConfiguration, { compile }?: { compile?: boolean | undefined; }): Promise<Erc721TimelockProver>; } export default Erc721TimelockProver;