import { Field } from '../wrapped.js'; import { provableTuple, HashInput, NonMethods } from './provable-derivers.js'; import type { InferJson, InferProvable, InferredProvable, IsPure } from './provable-derivers.js'; import { Provable } from '../provable.js'; import { ProvablePure, ProvableType } from './provable-intf.js'; import { From, InferValue } from '../../../bindings/lib/provable-generic.js'; export { ProvableExtended, ProvablePureExtended, Struct, FlexibleProvable, FlexibleProvablePure, FlexibleProvableType, }; export { provableTuple, AnyConstructor, cloneCircuitValue, circuitValueEquals, InferProvable, HashInput, InferJson, InferredProvable, StructNoJson, }; type ProvableExtension = { toInput: (x: T) => { fields?: Field[]; packed?: [Field, number][]; }; toJSON: (x: T) => TJson; fromJSON: (x: TJson) => T; empty: () => T; }; type ProvableExtended = Provable & ProvableExtension; type ProvablePureExtended = ProvablePure & ProvableExtension; type Struct = ProvableExtended> & Constructor & { _isStruct: true; }; type StructPure = ProvablePureExtended> & Constructor & { _isStruct: true; }; type FlexibleProvable = Provable | Struct; type FlexibleProvablePure = ProvablePure | StructPure; type FlexibleProvableType = ProvableType | Struct; type Constructor = new (...args: any) => T; type AnyConstructor = Constructor; /** * `Struct` lets you declare composite types for use in o1js circuits. * * These composite types can be passed in as arguments to smart contract methods, used for on-chain state variables * or as event / action types. * * @example * Here's an example of creating a "Voter" struct, which holds a public key and a collection of votes on 3 different proposals: * ```ts * let Vote = { hasVoted: Bool, inFavor: Bool }; * * class Voter extends Struct({ * publicKey: PublicKey, * votes: [Vote, Vote, Vote] * }) {} * * // use Voter as SmartContract input: * class VoterContract extends SmartContract { * \@method register(voter: Voter) { * // ... * } * } * ``` * In this example, there are no instance methods on the class. This makes `Voter` type-compatible with an anonymous object of the form * `{ publicKey: PublicKey, votes: Vote[] }`. * This mean you don't have to create instances by using `new Voter(...)`, you can operate with plain objects: * ```ts * voterContract.register({ publicKey, votes }); * ``` * * On the other hand, you can also add your own methods: * ```ts * class Voter extends Struct({ * publicKey: PublicKey, * votes: [Vote, Vote, Vote] * }) { * vote(index: number, inFavor: Bool) { * let vote = this.votes[i]; * vote.hasVoted = Bool(true); * vote.inFavor = inFavor; * } * } * ``` * * In this case, you'll need the constructor to create instances of `Voter`. It always takes as input the plain object: * ```ts * let emptyVote = { hasVoted: Bool(false), inFavor: Bool(false) }; * let voter = new Voter({ publicKey, votes: Array(3).fill(emptyVote) }); * voter.vote(1, Bool(true)); * ``` * * In addition to creating types composed of Field elements, you can also include auxiliary data which does not become part of the proof. * This, for example, allows you to reuse the same type outside o1js methods, where you might want to store additional metadata. * * To declare non-proof values of type `string`, `number`, etc, you can use the built-in objects `String`, `Number`, etc. * Here's how we could add the voter's name (a string) as auxiliary data: * ```ts * class Voter extends Struct({ * publicKey: PublicKey, * votes: [Vote, Vote, Vote], * fullName: String * }) {} * ``` * * Again, it's important to note that this doesn't enable you to prove anything about the `fullName` string. * From the circuit point of view, it simply doesn't exist! * * **Note**: Ensure you do not use or extend `Struct` as a type directly. Instead, always call it as a function to construct a type. `Struct` is not a valid provable type itself, types created with `Struct(...)` are. * * @param type Object specifying the layout of the `Struct` * @returns Class which you can extend */ declare function Struct = InferProvable, V extends InferValue = InferValue, J extends InferJson = InferJson, Pure extends boolean = IsPure>(type: A): (new (value: T) => T) & { _isStruct: true; } & (Pure extends true ? ProvablePure : Provable) & { fromValue: (value: From) => T; toInput: (x: T) => { fields?: Field[] | undefined; packed?: [Field, number][] | undefined; }; toJSON: (x: T) => J; fromJSON: (x: J) => T; empty: () => T; }; declare function StructNoJson = InferProvable, Pure extends boolean = IsPure>(type: A): (new (value: T) => T) & { _isStruct: true; } & (Pure extends true ? ProvablePure : Provable) & { toInput: (x: T) => { fields?: Field[] | undefined; packed?: [Field, number][] | undefined; }; empty: () => T; }; declare function cloneCircuitValue(obj: T): T; declare function circuitValueEquals(a: T, b: T): boolean;