UNPKG

o1js

Version:

TypeScript framework for zk-SNARKs and zkApps

200 lines (186 loc) 5.18 kB
import { Provable, ProvableHashable, ProvablePure, ProvableType, ToProvable, } from './provable-intf.js'; import type { Field } from '../wrapped.js'; import { createDerivers, NonMethods, InferProvable as GenericInferProvable, InferJson, InferredProvable as GenericInferredProvable, IsPure as GenericIsPure, NestedProvable as GenericNestedProvable, createHashInput, Constructor, InferValue, InferJsonNested, InferValueNested, InferProvableNested, } from '../../../bindings/lib/provable-generic.js'; import { Tuple } from '../../util/types.js'; import { GenericHashInput } from '../../../bindings/lib/generic.js'; // external API export { ProvableExtended, ProvableInferPureFrom, provable, provablePure, provableTuple, provableFromClass, provableExtends, }; // internal API export { NonMethods, HashInput, InferProvable, InferProvableType, InferJson, InferredProvable, IsPure, NestedProvable, mapValue, }; type ProvableExtension<T, TJson = any> = { toInput: (x: T) => { fields?: Field[]; packed?: [Field, number][] }; toJSON: (x: T) => TJson; fromJSON: (x: TJson) => T; empty: () => T; }; type ProvableExtended<T, TValue = any, TJson = any> = Provable<T, TValue> & ProvableExtension<T, TJson>; type ProvablePureExtended<T, TValue = any, TJson = any> = ProvablePure<T, TValue> & ProvableExtension<T, TJson>; type InferProvable<T> = GenericInferProvable<T, Field>; type InferProvableType<T extends ProvableType> = InferProvable<ToProvable<T>>; type InferredProvable<T> = GenericInferredProvable<T, Field>; type IsPure<T> = GenericIsPure<T, Field>; type ProvableInferPureFrom<A, T, V> = IsPure<A> extends true ? ProvablePure<T, V> : Provable<T, V>; type HashInput = GenericHashInput<Field>; const HashInput = createHashInput<Field>(); type NestedProvable = GenericNestedProvable<Field>; const { provable } = createDerivers<Field>(); function provablePure<A>( typeObj: A ): ProvablePureExtended<InferProvable<A>, InferValue<A>, InferJson<A>> { return provable(typeObj, { isPure: true }) as any; } function provableTuple<T extends Tuple<any>>(types: T): InferredProvable<T> { return provable(types) as any; } function provableFromClass< A extends NestedProvable, T extends InferProvableNested<Field, A>, V extends InferValueNested<Field, A>, J extends InferJsonNested<Field, A>, >( Class: Constructor<T> & { check?: (x: T) => void; empty?: () => T }, typeObj: A ): IsPure<A> extends true ? ProvablePureExtended<T, V, J> : ProvableExtended<T, V, J> { let raw: ProvableExtended<T, V, J> = provable(typeObj) as any; return { sizeInFields: raw.sizeInFields, toFields: raw.toFields, toAuxiliary: raw.toAuxiliary, fromFields(fields, aux) { return construct(Class, raw.fromFields(fields, aux)); }, check(value) { if (Class.check !== undefined) { Class.check(value); } else { raw.check(value); } }, toValue: raw.toValue, fromValue(x) { return construct(Class, raw.fromValue(x)); }, toInput: raw.toInput, toJSON: raw.toJSON, fromJSON(x) { return construct(Class, raw.fromJSON(x)); }, empty() { return Class.empty !== undefined ? Class.empty() : construct(Class, raw.empty()); }, } satisfies ProvableExtended<T, V, J> as any; } function construct<Raw, T extends Raw>(Class: Constructor<T>, value: Raw): T { let instance = Object.create(Class.prototype); return Object.assign(instance, value); } function provableExtends<A extends ProvableHashable<any>, T extends InferProvable<A>, S extends T>( S: new (t: T) => S, base: A ) { return { sizeInFields() { return base.sizeInFields(); }, toFields(value: S | T) { return base.toFields(value); }, toAuxiliary(value?: S | T) { return base.toAuxiliary(value); }, fromFields(fields, aux) { return new S(base.fromFields(fields, aux)); }, check(value: S | T) { base.check(value); }, toValue(value: S | T) { return base.toValue(value); }, fromValue(value) { return new S(base.fromValue(value)); }, empty() { return new S(base.empty()); }, toInput(value: S | T) { return base.toInput(value); }, } satisfies ProvableHashable<S, InferValue<A>>; } function mapValue< A extends ProvableHashable<any>, V extends InferValue<A>, W, T extends InferProvable<A>, >(provable: A, there: (x: V) => W, back: (x: W | T) => V | T): ProvableHashable<T, W> { return { sizeInFields() { return provable.sizeInFields(); }, toFields(value) { return provable.toFields(value); }, toAuxiliary(value) { return provable.toAuxiliary(value); }, fromFields(fields, aux) { return provable.fromFields(fields, aux); }, check(value) { provable.check(value); }, toValue(value) { return there(provable.toValue(value)); }, fromValue(value) { return provable.fromValue(back(value)); }, empty() { return provable.empty(); }, toInput(value) { return provable.toInput(value); }, }; }