From f89f25fa5f3d02cf2b2eb165d8b73a2a0481b723 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 27 Nov 2023 17:04:46 +0100 Subject: [PATCH 01/12] add toValue and fromValue to every provable --- lib/from-layout.ts | 99 +++++++++++++++++++++++++++++---- lib/generic.ts | 60 +++++++++++++------- lib/provable-generic.ts | 120 +++++++++++++++++++++++++++++++++------- 3 files changed, 228 insertions(+), 51 deletions(-) diff --git a/lib/from-layout.ts b/lib/from-layout.ts index 47b5e25f..9a3cb123 100644 --- a/lib/from-layout.ts +++ b/lib/from-layout.ts @@ -41,12 +41,19 @@ type TypeMapValues< [K in keyof TypeMap & keyof JsonMap]: BaseType; }; -type TypeMapProvable = { - [K in keyof TypeMap & keyof JsonMap]: GenericProvableExtended< - TypeMap[K], - JsonMap[K], - TypeMap['Field'] - >; +type TypeMapProvable< + TypeMap extends AnyTypeMap, + ValueMap extends AnyTypeMap, + JsonMap extends AnyTypeMap +> = { + [K in keyof TypeMap & keyof JsonMap]: K extends keyof ValueMap + ? GenericProvableExtended< + TypeMap[K], + ValueMap[K], + JsonMap[K], + TypeMap['Field'] + > + : never; }; type TypeMapSignable = { [K in keyof TypeMap & keyof JsonMap]: GenericSignable< @@ -284,17 +291,18 @@ function SignableFromLayout< function ProvableFromLayout< TypeMap extends AnyTypeMap, + ValueMap extends AnyTypeMap, JsonMap extends AnyTypeMap >( - TypeMap: TypeMapProvable, + TypeMap: TypeMapProvable, customTypes: Record< string, - GenericProvableExtended + GenericProvableExtended > ) { type Field = TypeMap['Field']; const Field = TypeMap.Field; - type BaseType = GenericProvableExtended; + type BaseType = GenericProvableExtended; type HashInput = { fields?: Field[]; packed?: [Field, number][] }; type Layout = GenericLayout; @@ -306,8 +314,17 @@ function ProvableFromLayout< function layoutFold(spec: FoldSpec, typeData: Layout, value?: T) { return genericLayoutFold(TypeMap, customTypes, spec, typeData, value); } + function layoutMap( + map: (typeData: BaseType, value: T) => R, + typeData: Layout, + value: T + ) { + return genericLayoutMap(TypeMap, customTypes, map, typeData, value); + } - function provableFromLayout(typeData: Layout) { + function provableFromLayout( + typeData: Layout + ): GenericProvableExtended { return { sizeInFields(): number { return sizeInFields(typeData); @@ -336,6 +353,12 @@ function ProvableFromLayout< empty(): T { return empty(typeData); }, + toValue(value: T): TValue { + return toValue(typeData, value); + }, + fromValue(value: TValue): T { + return fromValue(typeData, value); + }, }; } @@ -346,7 +369,7 @@ function ProvableFromLayout< return type.toFields(value); }, reduceArray(array) { - return array!.flat(); + return array.flat(); }, reduceObject(keys, object) { return keys.map((key) => object![key]).flat(); @@ -485,6 +508,22 @@ function ProvableFromLayout< ); } + function toValue(typeData: Layout, value: any) { + return layoutMap( + (type, value) => type.toValue(value), + typeData, + value + ); + } + + function fromValue(typeData: Layout, value: any) { + return layoutMap( + (type, value) => type.fromValue(value), + typeData, + value + ); + } + return { provableFromLayout, toJSONEssential, empty }; } @@ -591,6 +630,44 @@ function genericLayoutFold< return spec.map((TypeMap as any)[typeData.type], value, typeData.type); } +function genericLayoutMap< + BaseType, + T = any, + R = any, + TypeMap extends AnyTypeMap = AnyTypeMap, + JsonMap extends AnyTypeMap = AnyTypeMap +>( + TypeMap: TypeMapValues, + customTypes: Record, + map: (typeData: BaseType, value: T) => R, + typeData: GenericLayout, + value: T +): R { + return genericLayoutFold( + TypeMap, + customTypes, + { + map(type, value) { + return map(type, value!); + }, + reduceArray(array) { + return array; + }, + reduceObject(_, object) { + return object; + }, + reduceFlaggedOption(option) { + return option; + }, + reduceOrUndefined(value) { + return value; + }, + }, + typeData, + value + ); +} + // types type WithChecked = { diff --git a/lib/generic.ts b/lib/generic.ts index 21ed9124..6bd2f80d 100644 --- a/lib/generic.ts +++ b/lib/generic.ts @@ -19,19 +19,18 @@ export { EmptyVoid, }; -type GenericProvable = { +type GenericProvable = { toFields: (x: T) => Field[]; toAuxiliary: (x?: T) => any[]; fromFields: (x: Field[], aux: any[]) => T; sizeInFields(): number; check: (x: T) => void; + toValue: (x: T) => TValue; + fromValue: (x: TValue) => T; }; -interface GenericProvablePure extends GenericProvable { - toFields: (x: T) => Field[]; - toAuxiliary: (x?: T) => any[]; +interface GenericProvablePure + extends GenericProvable { fromFields: (x: Field[]) => T; - sizeInFields(): number; - check: (x: T) => void; } type GenericSignable = { @@ -41,11 +40,16 @@ type GenericSignable = { empty: () => T; }; -type GenericProvableExtended = GenericProvable & +type GenericProvableExtended = GenericProvable< + T, + TValue, + Field +> & GenericSignable; -type GenericProvableExtendedPure = GenericProvablePure< +type GenericProvableExtendedPure = GenericProvablePure< T, + TValue, Field > & GenericSignable; @@ -57,14 +61,14 @@ type GenericSignableField = (( Binable & { sizeInBytes: number }; type GenericField = GenericSignableField & - GenericProvable; + GenericProvable; type GenericSignableBool = ((value: boolean) => Bool) & GenericSignable & Binable & { sizeInBytes: number }; type GenericBool = GenericSignableBool & - GenericProvable; + GenericProvable; type GenericHashInput = { fields?: Field[]; packed?: [Field, number][] }; @@ -78,6 +82,8 @@ const emptyType = { toJSON: () => null, fromJSON: () => null, empty: () => null, + toValue: () => null, + fromValue: () => null, }; const undefinedType = { @@ -86,31 +92,41 @@ const undefinedType = { toJSON: () => null, fromJSON: () => undefined, empty: () => undefined, + toValue: () => undefined, + fromValue: () => undefined, }; let primitiveTypes = new Set(['number', 'string', 'null']); -function EmptyNull(): GenericProvableExtended & - GenericProvablePure { +function EmptyNull(): GenericProvableExtendedPure< + null, + null, + null, + Field +> { return emptyType; } -function EmptyUndefined(): GenericProvableExtended< +function EmptyUndefined(): GenericProvableExtendedPure< + undefined, undefined, null, Field -> & - GenericProvablePure { +> { return undefinedType; } -function EmptyVoid(): GenericProvableExtended & - GenericProvablePure { +function EmptyVoid(): GenericProvableExtendedPure< + void, + void, + null, + Field +> { return undefinedType; } type PrimitiveTypeMap = { - number: GenericProvableExtended; - string: GenericProvableExtended; - null: GenericProvableExtended; + number: GenericProvableExtended; + string: GenericProvableExtended; + null: GenericProvableExtended; }; const primitiveTypeMap: PrimitiveTypeMap = { @@ -121,6 +137,8 @@ const primitiveTypeMap: PrimitiveTypeMap = { fromJSON: (value) => value, fromFields: (_, [value]) => value, empty: () => 0, + toValue: (value) => value, + fromValue: (value) => value, }, string: { ...emptyType, @@ -129,6 +147,8 @@ const primitiveTypeMap: PrimitiveTypeMap = { fromJSON: (value) => value, fromFields: (_, [value]) => value, empty: () => '', + toValue: (value) => value, + fromValue: (value) => value, }, null: emptyType, }; diff --git a/lib/provable-generic.ts b/lib/provable-generic.ts index c4e6d103..39c528e4 100644 --- a/lib/provable-generic.ts +++ b/lib/provable-generic.ts @@ -25,19 +25,19 @@ type ProvableConstructor = ( ) => InferredProvable; type SignableConstructor = (typeObj: A) => InferredSignable; +let complexTypes = new Set(['object', 'function']); +let primitives = new Set([Number, String, Boolean, BigInt, null, undefined]); + function createDerivers(): { provable: ProvableConstructor; signable: SignableConstructor; } { - let complexTypes = new Set(['object', 'function']); - let primitives = new Set([Number, String, Boolean, BigInt, null, undefined]); - type Signable = GenericSignable; - type ProvableExtended = GenericProvableExtended< + type ProvableExtended< T, - TJson, - Field - >; + TValue = any, + TJson = JSONValue + > = GenericProvableExtended; type HashInput = GenericHashInput; const HashInput = createHashInput(); @@ -46,6 +46,7 @@ function createDerivers(): { options?: { isPure?: boolean } ): InferredProvable { type T = InferProvable; + type V = InferValue; type J = InferJson; let objectKeys = typeof typeObj === 'object' && typeObj !== null @@ -146,6 +147,9 @@ function createDerivers(): { ); } + const toValue = createMap('toValue'); + const fromValue = createMap('fromValue'); + let { empty, fromJSON, toJSON, toInput } = signable(typeObj); type S = InferSignable; @@ -157,12 +161,18 @@ function createDerivers(): { toAuxiliary: () => [], fromFields: (fields: Field[]) => fromFields(typeObj, fields, [], true) as T, + check: (obj: T) => check(typeObj, obj, true), + toValue(x) { + return toValue(typeObj, x); + }, + fromValue(v) { + return fromValue(typeObj, v); + }, toInput: (obj: T) => toInput(obj as S), toJSON: (obj: T) => toJSON(obj as S) satisfies J, fromJSON: (json: J) => fromJSON(json) as T, - check: (obj: T) => check(typeObj, obj, true), empty: () => empty() as T, - } satisfies ProvableExtended as InferredProvable; + } satisfies ProvableExtended as InferredProvable; } return { sizeInFields: () => sizeInFields(typeObj), @@ -170,12 +180,18 @@ function createDerivers(): { toAuxiliary: (obj?: T) => toAuxiliary(typeObj, obj, true), fromFields: (fields: Field[], aux: any[]) => fromFields(typeObj, fields, aux, true) as T, + check: (obj: T) => check(typeObj, obj, true), + toValue(x) { + return toValue(typeObj, x); + }, + fromValue(v) { + return fromValue(typeObj, v); + }, toInput: (obj: T) => toInput(obj as S), toJSON: (obj: T) => toJSON(obj as S) satisfies J, fromJSON: (json: J) => fromJSON(json) as T, - check: (obj: T) => check(typeObj, obj, true), empty: () => empty() as T, - } satisfies ProvableExtended as InferredProvable; + } satisfies ProvableExtended as InferredProvable; } function signable(typeObj: A): InferredSignable { @@ -276,6 +292,20 @@ function createDerivers(): { return { provable, signable }; } +function createMap(name: S) { + function map(typeObj: any, obj: any): any { + if (primitives.has(typeObj)) return obj; + if (!complexTypes.has(typeof typeObj)) + throw Error(`provable: unsupported type "${typeObj}"`); + if (Array.isArray(typeObj)) return typeObj.map((t, i) => map(t, obj[i])); + if (name in typeObj) return typeObj[name](obj); + return Object.fromEntries( + Object.keys(typeObj).map((k) => [k, map(typeObj[k], obj[k])]) + ); + } + return map; +} + function createHashInput() { type HashInput = GenericHashInput; return { @@ -301,7 +331,12 @@ type JSONValue = | Array | { [key: string]: JSONValue }; -type Struct = GenericProvableExtended, any, Field> & +type Struct = GenericProvableExtended< + NonMethods, + any, + any, + Field +> & Constructor & { _isStruct: true }; type NonMethodKeys = { @@ -333,6 +368,21 @@ type InferPrimitive

= P extends typeof String : P extends undefined ? undefined : any; + +type InferPrimitiveValue

= P extends typeof String + ? string + : P extends typeof Number + ? number + : P extends typeof Boolean + ? boolean + : P extends typeof BigInt + ? bigint + : P extends null + ? null + : P extends undefined + ? undefined + : any; + type InferPrimitiveJson

= P extends typeof String ? string : P extends typeof Number @@ -348,20 +398,24 @@ type InferPrimitiveJson

= P extends typeof String : JSONValue; type InferProvable = A extends Constructor - ? A extends GenericProvable + ? A extends GenericProvable ? U : A extends Struct ? U : InferProvableBase : InferProvableBase; -type InferProvableBase = A extends GenericProvable +type InferProvableBase = A extends GenericProvable< + infer U, + any, + Field +> ? U : A extends Primitive ? InferPrimitive : A extends Tuple ? { - [I in keyof A]: InferProvable; + [I in keyof A & number]: InferProvable; } : A extends (infer U)[] ? InferProvable[] @@ -371,6 +425,22 @@ type InferProvableBase = A extends GenericProvable } : never; +type InferValue = A extends GenericProvable + ? U + : A extends Primitive + ? InferPrimitiveValue + : A extends Tuple + ? { + [I in keyof A & number]: InferValue; + } + : A extends (infer U)[] + ? InferValue[] + : A extends Record + ? { + [K in keyof A]: InferValue; + } + : never; + type WithJson = { toJSON: (x: any) => J }; type InferJson = A extends WithJson @@ -379,7 +449,7 @@ type InferJson = A extends WithJson ? InferPrimitiveJson : A extends Tuple ? { - [I in keyof A]: InferJson; + [I in keyof A & number]: InferJson; } : A extends WithJson[] ? U[] @@ -391,9 +461,9 @@ type InferJson = A extends WithJson type IsPure = IsPureBase extends true ? true : false; -type IsPureBase = A extends GenericProvablePure +type IsPureBase = A extends GenericProvablePure ? true - : A extends GenericProvable + : A extends GenericProvable ? false : A extends Primitive ? false @@ -406,8 +476,18 @@ type IsPureBase = A extends GenericProvablePure : false; type InferredProvable = IsPure extends true - ? GenericProvableExtendedPure, InferJson, Field> - : GenericProvableExtended, InferJson, Field>; + ? GenericProvableExtendedPure< + InferProvable, + InferValue, + InferJson, + Field + > + : GenericProvableExtended< + InferProvable, + InferValue, + InferJson, + Field + >; // signable From 1fbc1996f2c3cf2e20885b8e80823f946f4bb9e2 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 27 Nov 2023 17:36:12 +0100 Subject: [PATCH 02/12] adapt transaction.ts manually --- lib/generic.ts | 3 +- lib/provable-bigint.ts | 16 +------- lib/provable-generic.ts | 1 + mina-transaction/derived-leaves.ts | 9 ++++- mina-transaction/gen/transaction.ts | 61 +++++++++++++++++++++++------ 5 files changed, 61 insertions(+), 29 deletions(-) diff --git a/lib/generic.ts b/lib/generic.ts index 6bd2f80d..dcfcd338 100644 --- a/lib/generic.ts +++ b/lib/generic.ts @@ -67,8 +67,9 @@ type GenericSignableBool = ((value: boolean) => Bool) & GenericSignable & Binable & { sizeInBytes: number }; +// TODO make `boolean` the value type type GenericBool = GenericSignableBool & - GenericProvable; + GenericProvable; type GenericHashInput = { fields?: Field[]; packed?: [Field, number][] }; diff --git a/lib/provable-bigint.ts b/lib/provable-bigint.ts index 0774a7ef..95e12b6e 100644 --- a/lib/provable-bigint.ts +++ b/lib/provable-bigint.ts @@ -1,27 +1,15 @@ import { bigIntToBytes } from '../crypto/bigint-helpers.js'; import { createDerivers } from './provable-generic.js'; -import { - GenericHashInput, - GenericProvableExtended, - GenericSignable, -} from './generic.js'; +import { GenericHashInput, GenericSignable } from './generic.js'; import { BinableWithBits, defineBinable, withBits } from './binable.js'; -export { - signable, - ProvableExtended, - ProvableBigint, - BinableBigint, - HashInput, - Signable, -}; +export { signable, ProvableBigint, BinableBigint, HashInput, Signable }; type Field = bigint; let { signable } = createDerivers(); type Signable = GenericSignable; -type ProvableExtended = GenericProvableExtended; type HashInput = GenericHashInput; function ProvableBigint< diff --git a/lib/provable-generic.ts b/lib/provable-generic.ts index 39c528e4..10482cbb 100644 --- a/lib/provable-generic.ts +++ b/lib/provable-generic.ts @@ -15,6 +15,7 @@ export { NonMethods, InferProvable, InferJson, + InferValue, InferredProvable, IsPure, }; diff --git a/mina-transaction/derived-leaves.ts b/mina-transaction/derived-leaves.ts index cd45ec45..10ce24e5 100644 --- a/mina-transaction/derived-leaves.ts +++ b/mina-transaction/derived-leaves.ts @@ -123,7 +123,7 @@ function createTokenSymbol< Field, Base extends GenericSignable, any, Field> >(base: Base, Field: GenericSignableField) { - return { + let self = { ...(base as Omit), toInput({ field }: TokenSymbol): GenericHashInput { return { packed: [[field, 48]] }; @@ -139,7 +139,14 @@ function createTokenSymbol< ); return { symbol, field: prefixToField(Field, symbol) }; }, + toValue(t: TokenSymbol): string { + return self.toJSON(t); + }, + fromValue(s: string): TokenSymbol { + return self.fromJSON(s); + }, }; + return self; } type AuthRequired = { diff --git a/mina-transaction/gen/transaction.ts b/mina-transaction/gen/transaction.ts index 55718a48..2030f670 100644 --- a/mina-transaction/gen/transaction.ts +++ b/mina-transaction/gen/transaction.ts @@ -21,6 +21,7 @@ import { import { GenericProvableExtended } from '../../lib/generic.js'; import { ProvableFromLayout, GenericLayout } from '../../lib/from-layout.js'; import * as Json from './transaction-json.js'; +import * as Value from './transaction-bigint.js'; import { jsLayout } from './js-layout.js'; export { customTypes, ZkappCommand, AccountUpdate, Account }; @@ -40,7 +41,11 @@ type TypeMap = { }; const TypeMap: { - [K in keyof TypeMap]: ProvableExtended; + [K in keyof TypeMap]: ProvableExtended< + TypeMap[K], + Value.TypeMap[K], + Json.TypeMap[K] + >; } = { PublicKey, UInt64, @@ -52,7 +57,12 @@ const TypeMap: { Sign, }; -type ProvableExtended = GenericProvableExtended; +type ProvableExtended = GenericProvableExtended< + T, + TValue, + TJson, + Field +>; type Layout = GenericLayout; type CustomTypes = { @@ -61,6 +71,7 @@ type CustomTypes = { data: string; hash: Field; }, + string, string >; TokenSymbol: ProvableExtended< @@ -68,14 +79,20 @@ type CustomTypes = { symbol: string; field: Field; }, + string, string >; - StateHash: ProvableExtended; + StateHash: ProvableExtended< + Field, + Value.TypeMap['Field'], + Json.TypeMap['Field'] + >; Events: ProvableExtended< { data: Field[][]; hash: Field; }, + Value.TypeMap['Field'][][], Json.TypeMap['Field'][][] >; Actions: ProvableExtended< @@ -83,11 +100,24 @@ type CustomTypes = { data: Field[][]; hash: Field; }, + Value.TypeMap['Field'][][], Json.TypeMap['Field'][][] >; - ActionState: ProvableExtended; - VerificationKeyHash: ProvableExtended; - ReceiptChainHash: ProvableExtended; + ActionState: ProvableExtended< + Field, + Value.TypeMap['Field'], + Json.TypeMap['Field'] + >; + VerificationKeyHash: ProvableExtended< + Field, + Value.TypeMap['Field'], + Json.TypeMap['Field'] + >; + ReceiptChainHash: ProvableExtended< + Field, + Value.TypeMap['Field'], + Json.TypeMap['Field'] + >; }; let customTypes: CustomTypes = { ZkappUri, @@ -101,6 +131,7 @@ let customTypes: CustomTypes = { }; let { provableFromLayout, toJSONEssential, empty } = ProvableFromLayout< TypeMap, + Value.TypeMap, Json.TypeMap >(TypeMap, customTypes); @@ -313,9 +344,11 @@ type ZkappCommand = { memo: string; }; -let ZkappCommand = provableFromLayout( - jsLayout.ZkappCommand as any -); +let ZkappCommand = provableFromLayout< + ZkappCommand, + Value.ZkappCommand, + Json.ZkappCommand +>(jsLayout.ZkappCommand as any); type AccountUpdate = { body: { @@ -514,9 +547,11 @@ type AccountUpdate = { }; }; -let AccountUpdate = provableFromLayout( - jsLayout.AccountUpdate as any -); +let AccountUpdate = provableFromLayout< + AccountUpdate, + Value.AccountUpdate, + Json.AccountUpdate +>(jsLayout.AccountUpdate as any); type Account = { publicKey: PublicKey; @@ -564,6 +599,6 @@ type Account = { }; }; -let Account = provableFromLayout( +let Account = provableFromLayout( jsLayout.Account as any ); From 6b09dc6c610e10828a70268b9c3998340d694ac3 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 27 Nov 2023 17:55:47 +0100 Subject: [PATCH 03/12] fixup derived leaves --- lib/provable-snarky.ts | 7 +++++-- mina-transaction/derived-leaves.ts | 8 +++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/provable-snarky.ts b/lib/provable-snarky.ts index 3d2c2ab8..727a81d8 100644 --- a/lib/provable-snarky.ts +++ b/lib/provable-snarky.ts @@ -31,9 +31,12 @@ type ProvableExtension = { fromJSON: (x: TJson) => T; empty: () => T; }; -type ProvableExtended = Provable & +type ProvableExtended = Provable & ProvableExtension; -type ProvableExtendedPure = ProvablePure & +type ProvableExtendedPure = ProvablePure< + T, + TValue +> & ProvableExtension; type InferProvable = GenericInferProvable; diff --git a/mina-transaction/derived-leaves.ts b/mina-transaction/derived-leaves.ts index 10ce24e5..14f4402e 100644 --- a/mina-transaction/derived-leaves.ts +++ b/mina-transaction/derived-leaves.ts @@ -217,11 +217,17 @@ function createZkappUri( return Hash.hashWithPrefix(prefixes.zkappUri, packed); } - return dataAsHash({ + return dataAsHash({ empty() { let hash = Hash.hashWithPrefix(prefixes.zkappUri, [Field(0), Field(0)]); return { data: '', hash }; }, + toValue(data: string) { + return data; + }, + fromValue(value: string) { + return { data: value, hash: hashZkappUri(value) }; + }, toJSON(data: string) { return data; }, From 07d117ed3c364febf417f1c42b3da6b14a985f55 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 27 Nov 2023 18:08:57 +0100 Subject: [PATCH 04/12] fixup tuple inference --- lib/provable-generic.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/provable-generic.ts b/lib/provable-generic.ts index 10482cbb..c524d46b 100644 --- a/lib/provable-generic.ts +++ b/lib/provable-generic.ts @@ -416,7 +416,7 @@ type InferProvableBase = A extends GenericProvable< ? InferPrimitive : A extends Tuple ? { - [I in keyof A & number]: InferProvable; + [I in keyof A]: InferProvable; } : A extends (infer U)[] ? InferProvable[] @@ -432,7 +432,7 @@ type InferValue = A extends GenericProvable ? InferPrimitiveValue : A extends Tuple ? { - [I in keyof A & number]: InferValue; + [I in keyof A]: InferValue; } : A extends (infer U)[] ? InferValue[] @@ -450,7 +450,7 @@ type InferJson = A extends WithJson ? InferPrimitiveJson : A extends Tuple ? { - [I in keyof A & number]: InferJson; + [I in keyof A]: InferJson; } : A extends WithJson[] ? U[] From 4fb53e4676676b0a78ac31ea0e42f05692a98095 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 27 Nov 2023 20:13:04 +0100 Subject: [PATCH 05/12] flexible fromValue --- lib/from-layout.ts | 2 +- lib/generic.ts | 2 +- mina-transaction/derived-leaves.ts | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/from-layout.ts b/lib/from-layout.ts index 9a3cb123..14327c57 100644 --- a/lib/from-layout.ts +++ b/lib/from-layout.ts @@ -356,7 +356,7 @@ function ProvableFromLayout< toValue(value: T): TValue { return toValue(typeData, value); }, - fromValue(value: TValue): T { + fromValue(value: TValue | T): T { return fromValue(typeData, value); }, }; diff --git a/lib/generic.ts b/lib/generic.ts index dcfcd338..c6ff4752 100644 --- a/lib/generic.ts +++ b/lib/generic.ts @@ -26,7 +26,7 @@ type GenericProvable = { sizeInFields(): number; check: (x: T) => void; toValue: (x: T) => TValue; - fromValue: (x: TValue) => T; + fromValue: (x: T | TValue) => T; }; interface GenericProvablePure extends GenericProvable { diff --git a/mina-transaction/derived-leaves.ts b/mina-transaction/derived-leaves.ts index 14f4402e..a4447423 100644 --- a/mina-transaction/derived-leaves.ts +++ b/mina-transaction/derived-leaves.ts @@ -142,8 +142,11 @@ function createTokenSymbol< toValue(t: TokenSymbol): string { return self.toJSON(t); }, - fromValue(s: string): TokenSymbol { - return self.fromJSON(s); + fromValue(s: string | TokenSymbol): TokenSymbol { + if (typeof s === 'string') { + return self.fromJSON(s); + } + return s; }, }; return self; From 53f9f9c532430b6f3929e00c3ec60706329d94b8 Mon Sep 17 00:00:00 2001 From: Gregor Date: Mon, 27 Nov 2023 20:32:28 +0100 Subject: [PATCH 06/12] make boolean the js type for Bool --- lib/binable.unit-test.ts | 6 +++--- lib/generic.ts | 3 +-- lib/provable-bigint.ts | 25 ++++++++++++++++++++++++- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/lib/binable.unit-test.ts b/lib/binable.unit-test.ts index 5b674e39..bb468b35 100644 --- a/lib/binable.unit-test.ts +++ b/lib/binable.unit-test.ts @@ -95,10 +95,10 @@ test.negative(Random.field, (field) => FieldWithFailingCheck.fromBytes(FieldWithFailingCheck.toBytes(field)) ); -let notABool = Random.map(Random.uint32, (x) => x + 2n); +let notABool = Random.map(Random.uint32, (x) => Number(x) + 2); test.negative(notABool, (bool) => // should fail to decode when check fails - Bool.fromBytes(Bool.toBytes(bool as Bool)) + Bool.fromBytes([bool]) ); // record combinator @@ -133,7 +133,7 @@ test(randomAccountBalance, (accountBalance) => { let MessedUpBool = defineBinable({ toBytes: Bool.toBytes, readBytes(bytes, offset) { - let value = BigInt(bytes[offset++]) as Bool; + let value = !!bytes[offset++]; return [value, offset + 1]; // by accident, offset is incremented twice }, }); diff --git a/lib/generic.ts b/lib/generic.ts index c6ff4752..a1ee54f2 100644 --- a/lib/generic.ts +++ b/lib/generic.ts @@ -67,9 +67,8 @@ type GenericSignableBool = ((value: boolean) => Bool) & GenericSignable & Binable & { sizeInBytes: number }; -// TODO make `boolean` the value type type GenericBool = GenericSignableBool & - GenericProvable; + GenericProvable; type GenericHashInput = { fields?: Field[]; packed?: [Field, number][] }; diff --git a/lib/provable-bigint.ts b/lib/provable-bigint.ts index 95e12b6e..6f97270b 100644 --- a/lib/provable-bigint.ts +++ b/lib/provable-bigint.ts @@ -3,7 +3,14 @@ import { createDerivers } from './provable-generic.js'; import { GenericHashInput, GenericSignable } from './generic.js'; import { BinableWithBits, defineBinable, withBits } from './binable.js'; -export { signable, ProvableBigint, BinableBigint, HashInput, Signable }; +export { + signable, + ProvableBigint, + BinableBigint, + BinableBool, + HashInput, + Signable, +}; type Field = bigint; @@ -62,3 +69,19 @@ function BinableBigint( sizeInBits ); } + +function BinableBool(check: (x: number) => void): BinableWithBits { + return withBits( + defineBinable({ + toBytes(x) { + return [x ? 1 : 0]; + }, + readBytes(bytes, start) { + let byte = bytes[start]; + check(byte); + return [byte === 1, start + 1]; + }, + }), + 1 + ); +} From fcfb73b806f9da3f2dc5a7d0ce1885982e950816 Mon Sep 17 00:00:00 2001 From: Gregor Mitscha-Baude Date: Tue, 28 Nov 2023 00:56:16 +0100 Subject: [PATCH 07/12] fix conversion to mina-signer --- lib/generic.ts | 4 ++-- mina-transaction/derived-leaves.ts | 16 ++++------------ mina-transaction/gen/transaction.ts | 20 ++++++++++++++++---- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/lib/generic.ts b/lib/generic.ts index a1ee54f2..ba7b75e6 100644 --- a/lib/generic.ts +++ b/lib/generic.ts @@ -55,10 +55,10 @@ type GenericProvableExtendedPure = GenericProvablePure< GenericSignable; type GenericSignableField = (( - value: number | string | bigint + value: number | string | bigint | Field ) => Field) & GenericSignable & - Binable & { sizeInBytes: number }; + Binable & { sizeInBytes: number; toBigint: (x: Field) => bigint }; type GenericField = GenericSignableField & GenericProvable; diff --git a/mina-transaction/derived-leaves.ts b/mina-transaction/derived-leaves.ts index a4447423..b63e2647 100644 --- a/mina-transaction/derived-leaves.ts +++ b/mina-transaction/derived-leaves.ts @@ -139,15 +139,6 @@ function createTokenSymbol< ); return { symbol, field: prefixToField(Field, symbol) }; }, - toValue(t: TokenSymbol): string { - return self.toJSON(t); - }, - fromValue(s: string | TokenSymbol): TokenSymbol { - if (typeof s === 'string') { - return self.fromJSON(s); - } - return s; - }, }; return self; } @@ -225,11 +216,11 @@ function createZkappUri( let hash = Hash.hashWithPrefix(prefixes.zkappUri, [Field(0), Field(0)]); return { data: '', hash }; }, - toValue(data: string) { + toValue(data) { return data; }, - fromValue(value: string) { - return { data: value, hash: hashZkappUri(value) }; + fromValue(value) { + return value; }, toJSON(data: string) { return data; @@ -237,5 +228,6 @@ function createZkappUri( fromJSON(json: string) { return { data: json, hash: hashZkappUri(json) }; }, + Field, }); } diff --git a/mina-transaction/gen/transaction.ts b/mina-transaction/gen/transaction.ts index 2030f670..a63910ed 100644 --- a/mina-transaction/gen/transaction.ts +++ b/mina-transaction/gen/transaction.ts @@ -71,7 +71,10 @@ type CustomTypes = { data: string; hash: Field; }, - string, + { + data: string; + hash: bigint; + }, string >; TokenSymbol: ProvableExtended< @@ -79,7 +82,10 @@ type CustomTypes = { symbol: string; field: Field; }, - string, + { + symbol: string; + field: bigint; + }, string >; StateHash: ProvableExtended< @@ -92,7 +98,10 @@ type CustomTypes = { data: Field[][]; hash: Field; }, - Value.TypeMap['Field'][][], + { + data: bigint[][]; + hash: bigint; + }, Json.TypeMap['Field'][][] >; Actions: ProvableExtended< @@ -100,7 +109,10 @@ type CustomTypes = { data: Field[][]; hash: Field; }, - Value.TypeMap['Field'][][], + { + data: bigint[][]; + hash: bigint; + }, Json.TypeMap['Field'][][] >; ActionState: ProvableExtended< From f9d7a9d254aad7b6de9f30f23a99905b9a8ccbac Mon Sep 17 00:00:00 2001 From: Gregor Mitscha-Baude Date: Tue, 28 Nov 2023 01:46:06 +0100 Subject: [PATCH 08/12] deeply flexible input type --- lib/provable-generic.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/provable-generic.ts b/lib/provable-generic.ts index c524d46b..b4b4f493 100644 --- a/lib/provable-generic.ts +++ b/lib/provable-generic.ts @@ -18,6 +18,7 @@ export { InferValue, InferredProvable, IsPure, + DeepValueOrProvable, }; type ProvableConstructor = ( @@ -513,3 +514,21 @@ type InferredSignable = GenericSignable< InferJson, Field >; + +// deep union type for flexible fromValue + +type DeepValueOrProvable = A extends GenericProvable + ? InferProvable | InferValue + : A extends Primitive + ? InferPrimitiveValue + : A extends Tuple + ? { + [I in keyof A]: DeepValueOrProvable; + } + : A extends (infer U)[] + ? DeepValueOrProvable[] + : A extends Record + ? { + [K in keyof A]: DeepValueOrProvable; + } + : never; From 9bcf4e3f9dbaae8c7e006bd229852fc01b8afff0 Mon Sep 17 00:00:00 2001 From: Gregor Date: Tue, 28 Nov 2023 09:31:28 +0100 Subject: [PATCH 09/12] use more flexible from() methods for inference --- lib/provable-generic.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/provable-generic.ts b/lib/provable-generic.ts index b4b4f493..63b7ce8f 100644 --- a/lib/provable-generic.ts +++ b/lib/provable-generic.ts @@ -18,7 +18,7 @@ export { InferValue, InferredProvable, IsPure, - DeepValueOrProvable, + DeepProvableOrValue, }; type ProvableConstructor = ( @@ -517,18 +517,24 @@ type InferredSignable = GenericSignable< // deep union type for flexible fromValue -type DeepValueOrProvable = A extends GenericProvable +type DeepProvableOrValue = A extends { + from: (x: infer U) => any; +} & GenericProvable + ? U | InferProvable + : A extends { fromValue: (x: infer U) => any } + ? U + : A extends GenericProvable ? InferProvable | InferValue : A extends Primitive ? InferPrimitiveValue : A extends Tuple ? { - [I in keyof A]: DeepValueOrProvable; + [I in keyof A]: DeepProvableOrValue; } : A extends (infer U)[] - ? DeepValueOrProvable[] + ? DeepProvableOrValue[] : A extends Record ? { - [K in keyof A]: DeepValueOrProvable; + [K in keyof A]: DeepProvableOrValue; } : never; From b33010443544d39a8f05bee59ee9550b52708030 Mon Sep 17 00:00:00 2001 From: Gregor Date: Tue, 28 Nov 2023 11:39:40 +0100 Subject: [PATCH 10/12] revert hijacking of from() --- lib/provable-generic.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/provable-generic.ts b/lib/provable-generic.ts index 63b7ce8f..86ec8a04 100644 --- a/lib/provable-generic.ts +++ b/lib/provable-generic.ts @@ -18,7 +18,7 @@ export { InferValue, InferredProvable, IsPure, - DeepProvableOrValue, + From, }; type ProvableConstructor = ( @@ -517,24 +517,22 @@ type InferredSignable = GenericSignable< // deep union type for flexible fromValue -type DeepProvableOrValue = A extends { - from: (x: infer U) => any; +type From = A extends { + fromValue: (x: infer U) => any; } & GenericProvable ? U | InferProvable - : A extends { fromValue: (x: infer U) => any } - ? U : A extends GenericProvable ? InferProvable | InferValue : A extends Primitive ? InferPrimitiveValue : A extends Tuple ? { - [I in keyof A]: DeepProvableOrValue; + [I in keyof A]: From; } : A extends (infer U)[] - ? DeepProvableOrValue[] + ? From[] : A extends Record ? { - [K in keyof A]: DeepProvableOrValue; + [K in keyof A]: From; } : never; From d7e194f29f720f62f70b5ca9d6d449fa0cd28947 Mon Sep 17 00:00:00 2001 From: Gregor Date: Wed, 17 Apr 2024 16:53:23 +0200 Subject: [PATCH 11/12] fix build --- mina-transaction/gen/transaction.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mina-transaction/gen/transaction.ts b/mina-transaction/gen/transaction.ts index 355bf840..5c1f6b9c 100644 --- a/mina-transaction/gen/transaction.ts +++ b/mina-transaction/gen/transaction.ts @@ -67,7 +67,11 @@ type ProvableExtended = GenericProvableExtended< type Layout = GenericLayout; type CustomTypes = { - TransactionVersion: ProvableExtended; + TransactionVersion: ProvableExtended< + UInt32, + Value.TypeMap['UInt32'], + Json.TypeMap['UInt32'] + >; ZkappUri: ProvableExtended< { data: string; From d8c860a164b2a594823e28ee42a3e1ad9e9fb732 Mon Sep 17 00:00:00 2001 From: Gregor Mitscha-Baude Date: Fri, 19 Apr 2024 08:15:46 +0200 Subject: [PATCH 12/12] regenerate tx type --- mina-transaction/gen/transaction.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mina-transaction/gen/transaction.ts b/mina-transaction/gen/transaction.ts index 5c1f6b9c..d70c915a 100644 --- a/mina-transaction/gen/transaction.ts +++ b/mina-transaction/gen/transaction.ts @@ -79,7 +79,7 @@ type CustomTypes = { }, { data: string; - hash: bigint; + hash: Value.TypeMap['Field']; }, string >; @@ -90,7 +90,7 @@ type CustomTypes = { }, { symbol: string; - field: bigint; + field: Value.TypeMap['Field']; }, string >; @@ -105,8 +105,8 @@ type CustomTypes = { hash: Field; }, { - data: bigint[][]; - hash: bigint; + data: Value.TypeMap['Field'][][]; + hash: Value.TypeMap['Field']; }, Json.TypeMap['Field'][][] >; @@ -116,8 +116,8 @@ type CustomTypes = { hash: Field; }, { - data: bigint[][]; - hash: bigint; + data: Value.TypeMap['Field'][][]; + hash: Value.TypeMap['Field']; }, Json.TypeMap['Field'][][] >;