mina-attestations
Version:
Private Attestations on Mina
228 lines (227 loc) • 10.2 kB
TypeScript
import { FeatureFlags, Field, PrivateKey, Provable, ProvableType, PublicKey, Signature, UInt32, Unconstrained, VerificationKey } from 'o1js';
import { Spec, type Input, type Claims } from './program-spec.ts';
import { type Program } from './program.ts';
import { type CredentialSpec, type StoredCredential } from './credential.ts';
import { type NetworkId, type WalletDerivedContext, type HttpsInputContext, type HttpsWalletContext, type ZkAppInputContext } from './context.ts';
export { PresentationRequest, HttpsRequest, ZkAppRequest, Presentation, ProvablePresentation, };
export { type PresentationRequestType, pickCredentials };
type PresentationRequestType = 'no-context' | 'zk-app' | 'https';
type PresentationRequest<RequestType extends PresentationRequestType = PresentationRequestType, Output = any, Inputs extends Record<string, Input> = Record<string, Input>, InputContext = any, WalletContext = any> = {
type: RequestType;
spec: Spec<Output, Inputs>;
claims: Claims<Inputs>;
inputContext: InputContext;
program?: unknown;
verificationKey?: VerificationKey;
deriveContext(
/**
* Context that is passed in from the input request / server-side
*/
inputContext: InputContext,
/**
* Application-specific context that is passed in from the wallet / client-side
*/
walletContext: WalletContext,
/**
* Context automatically (re-)derived on the client
*/
derivedContext: WalletDerivedContext): Field;
};
type CompiledRequest<Output, Inputs extends Record<string, Input>> = {
spec: Spec<Output, Inputs>;
program: Program<Output, Inputs>;
verificationKey: VerificationKey;
ProvablePresentation: typeof ProvablePresentation<Output, Inputs> & {
from(input: Presentation): ProvablePresentation<Output, Inputs>;
provable: Provable<ProvablePresentation<Output, Inputs>, Presentation<Output, Inputs>>;
};
};
declare const PresentationRequest: {
https<Output, Inputs extends Record<string, Input>>(spec: Spec<Output, Inputs>, claims: Claims<Inputs>, context: {
action: string;
}): HttpsRequest<Output, Inputs>;
httpsFromCompiled<Output, Inputs extends Record<string, Input>>(compiled: CompiledRequest<Output, Inputs>, claims: Claims<Inputs>, context: {
action: string;
}): HttpsRequest<Output, Inputs>;
zkApp<Output, Inputs extends Record<string, Input>>(spec: Spec<Output, Inputs>, claims: Claims<Inputs>, context: {
publicKey: PublicKey;
tokenId?: Field;
methodName: string;
network: NetworkId;
nonce?: UInt32;
}): ZkAppRequest<Output, Inputs>;
zkAppFromCompiled<Output, Inputs extends Record<string, Input>>(compiled: CompiledRequest<Output, Inputs>, claims: Claims<Inputs>, context: {
publicKey: PublicKey;
tokenId?: Field;
methodName: string;
network?: NetworkId;
nonce?: UInt32;
}): ZkAppRequest<Output, Inputs>;
noContext<Output, Inputs extends Record<string, Input>>(spec: Spec<Output, Inputs>, claims: Claims<Inputs>): NoContextRequest<Output, Inputs>;
toJSON(request: PresentationRequest): string;
fromJSON<R extends RequestFromType<K>, K extends PresentationRequestType = PresentationRequestType>(expectedType: K, json: string): R;
};
type Presentation<Output = any, Inputs extends Record<string, Input> = Record<string, Input>> = {
version: 'v0';
claims: Claims<Inputs>;
outputClaim: Output;
serverNonce: Field;
clientNonce: Field;
proof: {
proof: string;
maxProofsVerified: 0 | 1 | 2;
};
};
type Output<R> = R extends PresentationRequest<any, infer O> ? O : never;
type Inputs<R> = R extends PresentationRequest<any, any, infer I> ? I : never;
type WalletContext<R> = R extends PresentationRequest<any, any, any, any, infer W> ? W : never;
declare const Presentation: {
precompile<Output, Inputs extends Record<string, Input>>(spec: Spec<Output, Inputs>): Promise<CompiledRequest<Output, Inputs>>;
compile<R extends PresentationRequest>(request: R): Promise<Omit<R, "program"> & {
program: Program<Output<R>, Inputs<R>>;
verificationKey: VerificationKey;
}>;
/**
* Create a presentation, given the request, context, and credentials.
*
* The first argument is the private key of the credential's owner, which is needed to sign credentials.
*/
create: typeof createPresentation;
/**
* Prepare a presentation, given the request, context, and credentials
*
* This way creating the presentation doesn't require the private key of the owner but
* instead lets the wallet to handle the signing process
*/
prepare: typeof preparePresentation;
/**
* Finalize presentation given request, signature, and prepared data from preparePresentation
*/
finalize: typeof finalizePresentation;
/**
* Verify a presentation against a request and context.
*
* Returns the verified output claim of the proof, to be consumed by application-specific logic.
*/
verify: typeof verifyPresentation;
/**
* Serialize a presentation to JSON.
*/
toJSON: typeof toJSON;
/**
* Deserialize a presentation from JSON.
*/
fromJSON: typeof fromJSON;
};
declare function preparePresentation<R extends PresentationRequest>({ request, context: walletContext, credentials, }: {
request: R;
context: WalletContext<R>;
credentials: (StoredCredential & {
key?: string;
})[];
}): Promise<{
context: Field;
messageFields: string[];
credentialsUsed: Record<string, StoredCredential>;
serverNonce: Field;
clientNonce: Field;
compiledRequest: CompiledRequest<Output<R>, Inputs<R>>;
}>;
declare function finalizePresentation<R extends PresentationRequest>(request: R, ownerSignature: Signature, preparedData: {
serverNonce: Field;
clientNonce: Field;
context: Field;
credentialsUsed: Record<string, StoredCredential>;
compiledRequest: {
program: Program<Output<R>, Inputs<R>>;
};
}): Promise<Presentation<Output<R>, Inputs<R>>>;
declare function createPresentation<R extends PresentationRequest>(ownerKey: PrivateKey, params: {
request: R;
context: WalletContext<R>;
credentials: (StoredCredential & {
key?: string;
})[];
}): Promise<Presentation<Output<R>, Inputs<R>>>;
declare function verifyPresentation<R extends PresentationRequest>(request: R, presentation: Presentation<any, Record<string, any>>, context: WalletContext<R>): Promise<Output<R>>;
declare function toJSON<Output, Inputs extends Record<string, Input>>(presentation: Presentation<Output, Inputs>): string;
declare function fromJSON(presentationJson: string): Presentation;
declare function pickCredentials(spec: Spec, [...credentials]: (StoredCredential & {
key?: string;
})[]): {
credentialsUsed: Record<string, StoredCredential>;
credentialsAndSpecs: (StoredCredential & {
spec: CredentialSpec;
})[];
};
type RequestFromType<Type extends PresentationRequestType, Output = any, Inputs extends Record<string, Input> = Record<string, Input>> = Type extends 'no-context' ? NoContextRequest<Output, Inputs> : Type extends 'zk-app' ? ZkAppRequest<Output, Inputs> : Type extends 'https' ? HttpsRequest<Output, Inputs> : never;
type NoContextRequest<Output = any, Inputs extends Record<string, Input> = Record<string, Input>> = PresentationRequest<'no-context', Output, Inputs, undefined, undefined>;
type HttpsRequest<Output = any, Inputs extends Record<string, Input> = Record<string, Input>> = PresentationRequest<'https', Output, Inputs, HttpsInputContext, HttpsWalletContext>;
type ZkAppRequest<Output = any, Inputs extends Record<string, Input> = Record<string, Input>> = PresentationRequest<'zk-app', Output, Inputs, ZkAppInputContext, undefined>;
declare function HttpsRequest<Output, Inputs extends Record<string, Input>>(request: {
spec: Spec<Output, Inputs>;
claims: Claims<Inputs>;
inputContext: HttpsInputContext;
program?: Program<Output, Inputs>;
verificationKey?: VerificationKey;
}): HttpsRequest<Output, Inputs>;
declare function ZkAppRequest<Output, Inputs extends Record<string, Input>>(request: {
spec: Spec<Output, Inputs>;
claims: Claims<Inputs>;
inputContext: ZkAppInputContext;
program?: Program<Output, Inputs>;
verificationKey?: VerificationKey;
}): ZkAppRequest<Output, Inputs>;
/**
* Presentation that can be verified inside a zkApp.
*
* Create a subclass for your presentation as follows:
*
* ```ts
* let compiled = await Presentation.precompile(spec);
* class ProvablePresentation extends compiled.ProvablePresentation {}
* ```
*/
declare class ProvablePresentation<Output = any, Inputs extends Record<string, Input> = any> {
claims: Claims<Inputs>;
outputClaim: Output;
clientNonce: Field;
serverNonce: Unconstrained<bigint>;
proof: Unconstrained<string>;
constructor(input: {
claims: Claims<Inputs>;
outputClaim: Output;
clientNonce: Field;
serverNonce: Unconstrained<bigint>;
proof: Unconstrained<string>;
});
compiledRequest(): {
claimsType: ProvableType<Claims<Inputs>>;
outputClaimType: ProvableType<Output>;
tagName: string;
verificationKey: VerificationKey;
maxProofsVerified: 0 | 1 | 2;
featureFlags: FeatureFlags;
};
/**
* Verify presentation in a provable context.
*
* Input is the zkApp which this presentation is verified in.
*
* Pass in the public key, token id and current method of your zkapp to make sure
* you don't accept presentations that were intended for a different context.
*
* Optionally, you can further restrict context by passing in the network and nonce.
*/
verify(context: {
publicKey: PublicKey;
tokenId: Field;
methodName: string;
network?: NetworkId;
nonce?: UInt32;
}): {
claims: Claims<Inputs>;
outputClaim: Output;
};
static get provable(): Provable<ProvablePresentation, Presentation<any, any>>;
}