UNPKG

o1js

Version:

TypeScript framework for zk-SNARKs and zkApps

162 lines (132 loc) 4.12 kB
import { Bool } from '../../provable/bool.js'; import { Field } from '../../provable/field.js'; import { Provable } from '../../provable/types/provable-intf.js'; import * as Bindings from '../../../bindings/mina-transaction/v2/index.js'; import { bytesToBits, stringToBytes } from '../../../bindings/lib/binable.js'; import { GenericHashInput } from '../../../bindings/lib/generic.js'; import { hashWithPrefix, packToFields } from '../../../lib/provable/crypto/poseidon.js'; import { prefixes } from '../../../bindings/crypto/constants.js'; import { Types } from '../../../bindings/mina-transaction/v1/types.js'; export { Option, Range, mapUndefined, Empty, Update, Compare, Eq, ToFields, Tuple, ProvableTuple, ProvableInstance, ProvableTupleInstances, TokenId, ZkappUri, mapObject, }; // boo typescript function mapObject<In extends { [key: string]: any }, Out extends { [key in keyof In]: any }>( object: In, f: <Key extends keyof In>(key: Key) => Out[Key] ): { [key in keyof In]: Out[key] } { const newObject: Partial<{ [key in keyof In]: Out[key] }> = {}; for (const key in object) { newObject[key] = f(key); } return newObject as { [key in keyof In]: Out[key] }; } const { Option, Range } = Bindings.Leaves; type Option<T> = Bindings.Leaves.Option<T>; type Range<T> = Bindings.Leaves.Range<T>; class ZkappUri { readonly data: string; readonly hash: Field; constructor(uri: string | { data: string; hash: Field }) { if (typeof uri === 'object') { this.data = uri.data; this.hash = uri.hash; } else { this.data = uri; let packed: Field[]; if (uri.length === 0) { packed = [new Field(0), new Field(0)]; } else { const bits = bytesToBits(stringToBytes(uri)); bits.push(true); const input: GenericHashInput<Field> = { packed: bits.map((b) => [new Field(Number(b)), 1]), }; packed = packToFields(input); } this.hash = hashWithPrefix(prefixes.zkappUri, packed); } } toJSON(): Types.Json.AccountUpdate['body']['update']['zkappUri'] { return this.data.toString(); } static empty(): ZkappUri { return new ZkappUri(''); } static from(uri: ZkappUri | string): ZkappUri { return uri instanceof ZkappUri ? uri : new ZkappUri(uri); } } class TokenId { // TODO: construct this from it's parts, don't pass in the raw Field directly constructor(public value: Field) {} equals(x: TokenId): Bool { return this.value.equals(x.value); } toString(): string { return this.value.toString(); } static MINA: TokenId = new TokenId(new Field(1)); } function mapUndefined<A, B>(value: A | undefined, f: (a: A) => B): B | undefined { return value === undefined ? undefined : f(value); } interface Empty<T> { empty: () => T; } interface Eq<T> { equals(x: T): Bool; } type Compare<T extends Compare<T>> = Eq<T> & { lessThan(x: T): Bool; lessThanOrEqual(x: T): Bool; greaterThan(x: T): Bool; greaterThanOrEqual(x: T): Bool; }; interface ToFields { toFields(): Field[]; } type Tuple<T> = [T, ...T[]] | []; type ProvableTuple = Tuple<Provable<any>>; type ProvableInstance<P> = P extends Provable<infer T> ? (unknown extends T ? T : never) : never; type ProvableTupleInstances<T extends ProvableTuple> = { [I in keyof T]: ProvableInstance<T[I]>; }; class Update<T> { constructor(public set: Bool, public value: T) {} toOption(): Option<T> { return { isSome: this.set, value: this.value }; } static fromOption<T>(option: Option<T>): Update<T> { return new Update(option.isSome, option.value); } static disabled<T>(defaultValue: T): Update<T> { return new Update(new Bool(false), defaultValue); } static set<T>(value: T): Update<T> { return new Update(new Bool(true), value); } static from<T>(value: Update<T> | T | undefined, defaultValue: T): Update<T> { if (value instanceof Update) { return value; } else if (value !== undefined) { return Update.set(value); } else { return Update.disabled(defaultValue); } } }