import { Snarky } from '../../bindings.js';
import { ConstraintSystemSummary } from '../provable/core/provable-context.js';
import { InferProvable } from '../provable/types/provable-derivers.js';
import { ProvableTypePure } from '../provable/types/provable-intf.js';
import { Field } from '../provable/wrapped.js';
import { Get, Tuple } from '../util/types.js';
import { TupleToInstances } from './zkprogram.js';
export { KimchiJsonProof, KimchiProof, KimchiVerificationKey, ZkFunction };
type PublicInput<Config extends ZkFunctionConfig> = InferProvable<Get<Config, 'publicInputType'>>;
type PrivateInputs<Config extends ZkFunctionConfig> = TupleToInstances<Config['privateInputTypes']>;
type ZkFunctionConfig = {
    name: string;
    publicInputType?: ProvableTypePure;
    privateInputTypes: Tuple<ProvableTypePure>;
    lazyMode?: boolean;
};
type MainType<PublicInput, PrivateInputs extends Tuple<ProvableTypePure>> = PublicInput extends undefined ? (...args: TupleToInstances<PrivateInputs>) => void : (publicInput: InferProvable<PublicInput>, ...args: TupleToInstances<PrivateInputs>) => void;
type InferMainType<Config extends ZkFunctionConfig> = MainType<Get<Config, 'publicInputType'>, Config['privateInputTypes']>;
type ProveMethodType<Config extends ZkFunctionConfig> = Get<Config, 'publicInputType'> extends undefined ? (...args: PrivateInputs<Config>) => Promise<KimchiProof> : (publicInput: PublicInput<Config>, ...args: PrivateInputs<Config>) => Promise<KimchiProof>;
declare function ZkFunction<Config extends ZkFunctionConfig>(config: Config & {
    main: InferMainType<Config>;
}): {
    /**
     * Generates and stores a proving key and a verification key for this circuit(ZkFunction).
     *
     * @returns The generated verification key.
     *
     * @example
     * ```ts
     * const { verificationKey } = await zkf.compile();
     * ```
     * @warning Must be called before `prove` or `analyzeMethod`.
     */
    compile(): Promise<{
        verificationKey: KimchiVerificationKey;
    }>;
    /**
     * Returns a low-level JSON representation of the constraint system (gates)
     *
     * @throws If compile() has not been called yet.
     *
     * @example
     * ```ts
     * await zkf.compile();
     * const cs = zkf.analyzeMethod();
     * console.log(cs);
     * ```
     */
    analyzeMethod(): Omit<ConstraintSystemSummary, 'digest'>;
    /**
     * Proves a statement using the public input and private inputs of the circuit(ZkFunction).
     *
     * @param publicInput The public input to the circuit if it exists.
     * @param privateInputs The private inputs to the circuit.
     * @returns The generated proof.
     *
     * @throws If `compile` has not been called.
     *
     * @example
     * ```ts
     * const { verificationKey } = await zkf.compile();
     * const proof = await zkf.prove(publicInput, privateInput1, privateInput2);
     * ```
     */
    prove(...args: Parameters<ProveMethodType<Config>>): Promise<KimchiProof>;
    /**
     * Verifies a proof using the verification key of the circuit(ZkFunction).
     *
     * @param proof The proof to verify.
     * @param verificationKey The key to verify against.
     *
     * @returns `true` if the proof is valid, otherwise `false`.
     *
     * @example
     * ```ts
     * const { verificationKey } = await zkf.compile();
     * const proof = await zkf.prove(publicInput, privateInput1, privateInput2);
     * const isValid = await zkf.verify(proof, verificationKey);
     * ```
     */
    verify(proof: KimchiProof, verificationKey: KimchiVerificationKey): Promise<boolean>;
};
/**
 * Serializable representation of a Kimchi proof, useful for caching compiled proofs.
 */
type KimchiJsonProof = {
    /** Array of string, where each string is a `Field` in the publicInputFields of this proof */
    publicInputFields: string[];
    /** The proof itself, encoded as a Base64 string */
    proof: string;
};
/**
 * Encapsulates a {@link ZkFunction} proof together with its public input fields.
 *
 * Generated by {@link ZkFunction.prove}, it wraps the raw `Snarky.Proof`
 * and the array of `Field` inputs used for verification.
 *
 * You can call `verify` on a `Proof` to check its validity against a
 * {@link VerificationKey}.
 */
declare class KimchiProof {
    value: Snarky.Proof;
    publicInputFields: Field[];
    constructor(value: Snarky.Proof, publicInputFields: Field[]);
    toJSON(): KimchiJsonProof;
    static fromJSON(json: KimchiJsonProof): KimchiProof;
    /**
     * Verifies this proof using the provided verification key.
     * @param verificationKey The key to verify against.
     * @returns A promise that resolves to `true` if valid, otherwise `false`.
     */
    verify(verificationKey: KimchiVerificationKey): Promise<boolean>;
}
/**
 * A verification key is used to verify a {@link Proof}.
 */
declare class KimchiVerificationKey {
    value: Snarky.VerificationKey;
    constructor(value: Snarky.VerificationKey);
    toString(): string;
    static fromString(base64: string): KimchiVerificationKey;
}
