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
TypeScript
/**
* 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;