Skip to main content

BatchReducer

A reducer to process actions in fixed-size batches.

let batchReducer = new BatchReducer({ actionType: Action, batchSize: 5 });

// in contract: concurrent dispatching of actions
batchReducer.dispatch(action);

// reducer logic
// outside contract: prepare a list of { batch, proof } objects which cover all pending actions
let batches = await batchReducer.prepareBatches();

// in contract: process a single batch
// create one transaction that does this for each batch!
batchReducer.processBatch({ batch, proof }, (action, isDummy) => {
// ...
});

Extends​

  • BatchReducer\<ActionType, BatchSize, Action>

Type parameters​

• ActionType extends Actionable\<any>

• BatchSize extends number = number

• Action = InferProvable\<ActionType>

Constructors​

new BatchReducer()​

new BatchReducer<ActionType, BatchSize, Action>(__namedParameters: {
"actionType": ActionType;
"batchSize": BatchSize;
"maxActionsPerUpdate": number;
"maxUpdatesFinalProof": 100;
"maxUpdatesPerProof": 300;
}): BatchReducer<ActionType, BatchSize, Action>

Parameters​

• __namedParameters

• __namedParameters.actionType: ActionType

The provable type of actions submitted by this reducer.

• __namedParameters.batchSize: BatchSize

The number of actions in a batch. The idea is to process one batch per transaction, by calling processBatch().

The motivation for processing actions in small batches is to work around the protocol limit on the number of account updates. If every action should result in an account update, then you have to set the batch size low enough to not exceed the limit.

If transaction limits are no concern, the batchSize could be set based on amount of logic you do per action. A smaller batch size will make proofs faster, but you might need more individual transactions as more batches are needed to process all pending actions.

• __namedParameters.maxActionsPerUpdate?: number= undefined

The maximum number of actions dispatched in any of the zkApp methods on the contract.

Note: This number just has to be an upper bound of the actual maximum, but if it's the precise number, fewer constraints will be used. (The overhead of a higher number is fairly small though.)

A restriction is that the number has to be less or equal than the batchSize. The reason is that actions in one account update are always processed together, so if you'd have more actions in one than the batch size, we couldn't process them at all.

By default, this is set to Math.min(batchSize, 5) which should be sensible for most applications.

• __namedParameters.maxUpdatesFinalProof?: number= 100

The maximum number of action lists (= all actions on an account update) to process inside processBatch(), i.e. in your zkApp method.

Default: 100, which will take up about 3000 constraints.

The current default should be sensible for most applications, but here are some trade-offs to consider when changing it:

  • Using a smaller number means a smaller circuit, so proofs of your method will be faster.
  • Using a bigger number means it's more likely that you can prove all actions in the method call and won't need a recursive proof.

So, go lower if you expect very few actions, and higher if you expect a lot of actions.

• __namedParameters.maxUpdatesPerProof?: number= 300

The maximum number of action lists (= all actions on an account update) to process in a single recursive proof, in prepareBatches().

Default: 300, which will take up about 9000 constraints.

The current default should be sensible for most applications, but here are some trade-offs to consider when changing it:

  • Using a smaller number means a smaller circuit, so recursive proofs will be faster.
  • Using a bigger number means you'll need fewer recursive proofs in the case a lot of actions are pending.

So, go lower if you expect very few actions, and higher if you expect a lot of actions. (Note: A larger circuit causes longer compilation and proof times for your zkApp even if you never need a recursive proof)

Returns​

BatchReducer\<ActionType, BatchSize, Action>

Inherited from​

BatchReducer_.BatchReducer<ActionType, BatchSize, Action>.constructor

Source​

lib/mina/actions/batch-reducer.ts:75

Properties​

Batch​

Batch: (value: {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
}) => {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
} & {
"_isStruct": true;
} & Provable<{
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
}, {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": any;
"useOnchainStack": Bool;
"witnesses": ActionWitnesses;
}> & {
"empty": () => {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
};
"fromJSON": (x: {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": {
"_emptyHash": null | string;
"_innerProvable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"_nextHash": null | {};
"_provable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"empty": {};
"emptyHash": string;
"from": {};
"fromReverse": {};
"prototype": {
"Constructor": {
"_emptyHash": null | string;
"_innerProvable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"_nextHash": null | {};
"_provable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"emptyHash": string;
"prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; };
"create": ;
};
"data": {
"get": ;
"set": ;
"setTo": ;
"updateAsProver": ;
};
"hash": string;
"innerProvable": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"clone": ;
"forEach": ;
"isEmpty": ;
"lengthUnconstrained": ;
"nextHash": ;
"pop": ;
"popExn": ;
"popIf": ;
"popIfUnsafe": ;
"push": ;
"pushIf": ;
"startIterating": ;
"startIteratingFromLast": ;
"toArrayUnconstrained": ;
};
"provable": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"create": ;
};
"useOnchainStack": Bool;
"witnesses": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
}) => {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
};
"fromValue": (value: {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": any;
"useOnchainStack": Bool;
"witnesses": ActionWitnesses | Unconstrained<ActionWitnesses>;
}) => {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
};
"toInput": (x: {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
}) => {
"fields": Field[];
"packed": [Field, number][];
};
"toJSON": (x: {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
}) => {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": {
"_emptyHash": null | string;
"_innerProvable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"_nextHash": null | {};
"_provable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"empty": {};
"emptyHash": string;
"from": {};
"fromReverse": {};
"prototype": {
"Constructor": {
"_emptyHash": null | string;
"_innerProvable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"_nextHash": null | {};
"_provable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"emptyHash": string;
"prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; };
"create": ;
};
"data": {
"get": ;
"set": ;
"setTo": ;
"updateAsProver": ;
};
"hash": string;
"innerProvable": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"clone": ;
"forEach": ;
"isEmpty": ;
"lengthUnconstrained": ;
"nextHash": ;
"pop": ;
"popExn": ;
"popIf": ;
"popIfUnsafe": ;
"push": ;
"pushIf": ;
"startIterating": ;
"startIteratingFromLast": ;
"toArrayUnconstrained": ;
};
"provable": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"create": ;
};
"useOnchainStack": Bool;
"witnesses": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
};
};

Type declaration​

_isStruct​
_isStruct: true;

Type declaration​

empty()​
empty: () => {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
};
Returns​
{
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
}
isRecursive​
isRecursive: Bool = Bool;
onchainActionState​
onchainActionState: Field = Field;
onchainStack​
onchainStack: Field = Field;
processedActionState​
processedActionState: Field = Field;
stack​
stack: MerkleList<MerkleList<Hashed<any>>>;
useOnchainStack​
useOnchainStack: Bool = Bool;
witnesses​
witnesses: Unconstrained<ActionWitnesses>;
fromJSON()​
fromJSON: (x: {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": {
"_emptyHash": null | string;
"_innerProvable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"_nextHash": null | {};
"_provable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"empty": {};
"emptyHash": string;
"from": {};
"fromReverse": {};
"prototype": {
"Constructor": {
"_emptyHash": null | string;
"_innerProvable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"_nextHash": null | {};
"_provable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"emptyHash": string;
"prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; };
"create": ;
};
"data": {
"get": ;
"set": ;
"setTo": ;
"updateAsProver": ;
};
"hash": string;
"innerProvable": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"clone": ;
"forEach": ;
"isEmpty": ;
"lengthUnconstrained": ;
"nextHash": ;
"pop": ;
"popExn": ;
"popIf": ;
"popIfUnsafe": ;
"push": ;
"pushIf": ;
"startIterating": ;
"startIteratingFromLast": ;
"toArrayUnconstrained": ;
};
"provable": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"create": ;
};
"useOnchainStack": Bool;
"witnesses": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
}) => {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
};
Parameters​

• x

• x.isRecursive: boolean= Bool

• x.onchainActionState: string= Field

• x.onchainStack: string= Field

• x.processedActionState: string= Field

• x.stack= undefined

• x.stack._emptyHash: null | string

• x.stack._innerProvable: null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }

• x.stack._nextHash: null | {}

• x.stack._provable: null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }

• x.stack.empty

• x.stack.emptyHash: string

• x.stack.from

• x.stack.fromReverse

• x.stack.prototype

• x.stack.prototype.Constructor

• x.stack.prototype.Constructor._emptyHash: null | string

• x.stack.prototype.Constructor._innerProvable: null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }

• x.stack.prototype.Constructor._nextHash: null | {}

• x.stack.prototype.Constructor._provable: null | { "check": {}; "empty": {}; "fromFields": {}; "fromValue": {}; "toAuxiliary": {}; "toCanonical": null | {}; "toFields": {}; "toInput": {}; "toValue": {}; "sizeInFields": ; }

• x.stack.prototype.Constructor.emptyHash: string

• x.stack.prototype.Constructor.prototype: { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; }

• x.stack.prototype.Constructor.create

Create a Merkle list type

Optionally, you can tell create() how to do the hash that pushes a new list element, by passing a nextHash function.

Example

class MyList extends MerkleList.create(Field, (hash, x) =>
Poseidon.hashWithPrefix('custom', [hash, x])
) {}

• x.stack.prototype.data

• x.stack.prototype.data.get

Read an unconstrained value.

Note: Can only be called outside provable code.

• x.stack.prototype.data.set

Modify the unconstrained value.

• x.stack.prototype.data.setTo

Set the unconstrained value to the same as another Unconstrained.

• x.stack.prototype.data.updateAsProver

Update an Unconstrained by a witness computation.

• x.stack.prototype.hash: string

• x.stack.prototype.innerProvable

• x.stack.prototype.innerProvable.check

Add assertions to the proof to check if value is a valid member of type T. This function does not return anything, instead it creates any number of assertions to prove that value is a valid member of the type T.

For instance, calling check function on the type Bool asserts that the value of the element is either 1 or 0.

Param the element of type T to put assertions on.

• x.stack.prototype.innerProvable.empty

• x.stack.prototype.innerProvable.fromFields

A function that returns an element of type T from the given provable and "auxiliary" data.

This function is the reverse operation of calling toFields and toAuxilary methods on an element of type T.

Param an array of Field elements describing the provable data of the new T element.

Param an array of any type describing the "auxiliary" data of the new T element, optional.

• x.stack.prototype.innerProvable.fromValue

Convert provable type from a normal JS type.

• x.stack.prototype.innerProvable.toAuxiliary

A function that takes value (optional), an element of type T, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of value.

Param the element of type T to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned.

• x.stack.prototype.innerProvable.toCanonical?: null | {}

Optional method which transforms a provable type into its canonical representation.

This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations.

An example is the ForeignField class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error.

Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. toCanonical() converts any input into a safe form and enables us to handle cases like this generically.

Note: For most types, this method is the identity function. The identity function will also be used when the toCanonical() is not present on a type.

• x.stack.prototype.innerProvable.toFields

A function that takes value, an element of type T, as argument and returns an array of Field elements that make up the provable data of value.

Param the element of type T to generate the Field array from.

• x.stack.prototype.innerProvable.toInput

• x.stack.prototype.innerProvable.toValue

Convert provable type to a normal JS type.

• x.stack.prototype.innerProvable.sizeInFields

• x.stack.prototype.clone

• x.stack.prototype.forEach

Iterate through the list in a fixed number of steps any apply a given callback on each element.

Proves that the iteration traverses the entire list. Once past the last element, dummy elements will be passed to the callback.

Note: There are no guarantees about the contents of dummy elements, so the callback is expected to handle the isDummy flag separately.

• x.stack.prototype.isEmpty

• x.stack.prototype.lengthUnconstrained

• x.stack.prototype.nextHash

• x.stack.prototype.pop

Remove the last element from the list and return it.

If the list is empty, returns a dummy element.

• x.stack.prototype.popExn

Remove the last element from the list and return it.

This proves that the list is non-empty, and fails otherwise.

• x.stack.prototype.popIf

Return the last element, but only remove it if condition is true.

If the list is empty, returns a dummy element.

• x.stack.prototype.popIfUnsafe

Low-level, minimal version of pop() which lets the caller decide whether there is an element to pop.

I.e. this proves:

  • If the input condition is true, this returns the last element and removes it from the list.
  • If the input condition is false, the list is unchanged and the return value is garbage.

Note that if the caller passes true but the list is empty, this will fail. If the caller passes false but the list is non-empty, this succeeds and just doesn't pop off an element.

• x.stack.prototype.push

Push a new element to the list.

• x.stack.prototype.pushIf

Push a new element to the list, if the condition is true.

• x.stack.prototype.startIterating

• x.stack.prototype.startIteratingFromLast

• x.stack.prototype.toArrayUnconstrained

• x.stack.provable

• x.stack.provable.check

Add assertions to the proof to check if value is a valid member of type T. This function does not return anything, instead it creates any number of assertions to prove that value is a valid member of the type T.

For instance, calling check function on the type Bool asserts that the value of the element is either 1 or 0.

Param the element of type T to put assertions on.

• x.stack.provable.empty

• x.stack.provable.fromFields

A function that returns an element of type T from the given provable and "auxiliary" data.

This function is the reverse operation of calling toFields and toAuxilary methods on an element of type T.

Param an array of Field elements describing the provable data of the new T element.

Param an array of any type describing the "auxiliary" data of the new T element, optional.

• x.stack.provable.fromValue

Convert provable type from a normal JS type.

• x.stack.provable.toAuxiliary

A function that takes value (optional), an element of type T, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of value.

Param the element of type T to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned.

• x.stack.provable.toCanonical?: null | {}

Optional method which transforms a provable type into its canonical representation.

This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations.

An example is the ForeignField class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error.

Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. toCanonical() converts any input into a safe form and enables us to handle cases like this generically.

Note: For most types, this method is the identity function. The identity function will also be used when the toCanonical() is not present on a type.

• x.stack.provable.toFields

A function that takes value, an element of type T, as argument and returns an array of Field elements that make up the provable data of value.

Param the element of type T to generate the Field array from.

• x.stack.provable.toInput

• x.stack.provable.toValue

Convert provable type to a normal JS type.

• x.stack.provable.sizeInFields

• x.stack.create

Create a Merkle list type

Optionally, you can tell create() how to do the hash that pushes a new list element, by passing a nextHash function.

Example

class MyList extends MerkleList.create(Field, (hash, x) =>
Poseidon.hashWithPrefix('custom', [hash, x])
) {}

• x.useOnchainStack: boolean= Bool

• x.witnesses= undefined

• x.witnesses.check

Add assertions to the proof to check if value is a valid member of type T. This function does not return anything, instead it creates any number of assertions to prove that value is a valid member of the type T.

For instance, calling check function on the type Bool asserts that the value of the element is either 1 or 0.

Param the element of type T to put assertions on.

• x.witnesses.empty

• x.witnesses.fromFields

A function that returns an element of type T from the given provable and "auxiliary" data.

This function is the reverse operation of calling toFields and toAuxilary methods on an element of type T.

Param an array of Field elements describing the provable data of the new T element.

Param an array of any type describing the "auxiliary" data of the new T element, optional.

• x.witnesses.fromValue

Convert provable type from a normal JS type.

• x.witnesses.toAuxiliary

A function that takes value (optional), an element of type T, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of value.

Param the element of type T to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned.

• x.witnesses.toCanonical?: null | {}

Optional method which transforms a provable type into its canonical representation.

This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations.

An example is the ForeignField class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error.

Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. toCanonical() converts any input into a safe form and enables us to handle cases like this generically.

Note: For most types, this method is the identity function. The identity function will also be used when the toCanonical() is not present on a type.

• x.witnesses.toFields

A function that takes value, an element of type T, as argument and returns an array of Field elements that make up the provable data of value.

Param the element of type T to generate the Field array from.

• x.witnesses.toInput

• x.witnesses.toValue

Convert provable type to a normal JS type.

• x.witnesses.sizeInFields

Returns​
{
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
}
isRecursive​
isRecursive: Bool = Bool;
onchainActionState​
onchainActionState: Field = Field;
onchainStack​
onchainStack: Field = Field;
processedActionState​
processedActionState: Field = Field;
stack​
stack: MerkleList<MerkleList<Hashed<any>>>;
useOnchainStack​
useOnchainStack: Bool = Bool;
witnesses​
witnesses: Unconstrained<ActionWitnesses>;
fromValue()​
fromValue: (value: {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": any;
"useOnchainStack": Bool;
"witnesses": ActionWitnesses | Unconstrained<ActionWitnesses>;
}) => {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
};
Parameters​

• value

• value.isRecursive: boolean | Bool= Bool

• value.onchainActionState: string | number | bigint | Field= Field

• value.onchainStack: string | number | bigint | Field= Field

• value.processedActionState: string | number | bigint | Field= Field

• value.stack: any= undefined

• value.useOnchainStack: boolean | Bool= Bool

• value.witnesses: ActionWitnesses | Unconstrained\<ActionWitnesses>= undefined

Returns​
{
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
}
isRecursive​
isRecursive: Bool = Bool;
onchainActionState​
onchainActionState: Field = Field;
onchainStack​
onchainStack: Field = Field;
processedActionState​
processedActionState: Field = Field;
stack​
stack: MerkleList<MerkleList<Hashed<any>>>;
useOnchainStack​
useOnchainStack: Bool = Bool;
witnesses​
witnesses: Unconstrained<ActionWitnesses>;
toInput()​
toInput: (x: {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
}) => {
"fields": Field[];
"packed": [Field, number][];
};
Parameters​

• x

• x.isRecursive: Bool= Bool

• x.onchainActionState: Field= Field

• x.onchainStack: Field= Field

• x.processedActionState: Field= Field

• x.stack: MerkleList\<MerkleList\<Hashed\<any>>>= undefined

• x.useOnchainStack: Bool= Bool

• x.witnesses: Unconstrained\<ActionWitnesses>= undefined

Returns​
{
"fields": Field[];
"packed": [Field, number][];
}
fields?​
optional fields: Field[];
packed?​
optional packed: [Field, number][];
toJSON()​
toJSON: (x: {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": MerkleList<MerkleList<Hashed<any>>>;
"useOnchainStack": Bool;
"witnesses": Unconstrained<ActionWitnesses>;
}) => {
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": {
"_emptyHash": null | string;
"_innerProvable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"_nextHash": null | {};
"_provable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"empty": {};
"emptyHash": string;
"from": {};
"fromReverse": {};
"prototype": {
"Constructor": {
"_emptyHash": null | string;
"_innerProvable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"_nextHash": null | {};
"_provable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"emptyHash": string;
"prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; };
"create": ;
};
"data": {
"get": ;
"set": ;
"setTo": ;
"updateAsProver": ;
};
"hash": string;
"innerProvable": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"clone": ;
"forEach": ;
"isEmpty": ;
"lengthUnconstrained": ;
"nextHash": ;
"pop": ;
"popExn": ;
"popIf": ;
"popIfUnsafe": ;
"push": ;
"pushIf": ;
"startIterating": ;
"startIteratingFromLast": ;
"toArrayUnconstrained": ;
};
"provable": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"create": ;
};
"useOnchainStack": Bool;
"witnesses": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
};
Parameters​

• x

• x.isRecursive: Bool= Bool

• x.onchainActionState: Field= Field

• x.onchainStack: Field= Field

• x.processedActionState: Field= Field

• x.stack: MerkleList\<MerkleList\<Hashed\<any>>>= undefined

• x.useOnchainStack: Bool= Bool

• x.witnesses: Unconstrained\<ActionWitnesses>= undefined

Returns​
{
"isRecursive": Bool;
"onchainActionState": Field;
"onchainStack": Field;
"processedActionState": Field;
"stack": {
"_emptyHash": null | string;
"_innerProvable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"_nextHash": null | {};
"_provable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"empty": {};
"emptyHash": string;
"from": {};
"fromReverse": {};
"prototype": {
"Constructor": {
"_emptyHash": null | string;
"_innerProvable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"_nextHash": null | {};
"_provable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"emptyHash": string;
"prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; };
"create": ;
};
"data": {
"get": ;
"set": ;
"setTo": ;
"updateAsProver": ;
};
"hash": string;
"innerProvable": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"clone": ;
"forEach": ;
"isEmpty": ;
"lengthUnconstrained": ;
"nextHash": ;
"pop": ;
"popExn": ;
"popIf": ;
"popIfUnsafe": ;
"push": ;
"pushIf": ;
"startIterating": ;
"startIteratingFromLast": ;
"toArrayUnconstrained": ;
};
"provable": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"create": ;
};
"useOnchainStack": Bool;
"witnesses": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
}
isRecursive​
isRecursive: boolean = Bool;
onchainActionState​
onchainActionState: string = Field;
onchainStack​
onchainStack: string = Field;
processedActionState​
processedActionState: string = Field;
stack​
stack: {
"_emptyHash": null | string;
"_innerProvable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"_nextHash": null | {};
"_provable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"empty": {};
"emptyHash": string;
"from": {};
"fromReverse": {};
"prototype": {
"Constructor": {
"_emptyHash": null | string;
"_innerProvable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"_nextHash": null | {};
"_provable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"emptyHash": string;
"prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; };
"create": ;
};
"data": {
"get": ;
"set": ;
"setTo": ;
"updateAsProver": ;
};
"hash": string;
"innerProvable": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"clone": ;
"forEach": ;
"isEmpty": ;
"lengthUnconstrained": ;
"nextHash": ;
"pop": ;
"popExn": ;
"popIf": ;
"popIfUnsafe": ;
"push": ;
"pushIf": ;
"startIterating": ;
"startIteratingFromLast": ;
"toArrayUnconstrained": ;
};
"provable": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"create": ;
};
stack._emptyHash​
_emptyHash: null | string;
stack._innerProvable​
_innerProvable: null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
stack._nextHash​
_nextHash: null | {};
stack._provable​
_provable: null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
stack.empty​
empty: {};
stack.emptyHash​
emptyHash: string;
stack.from​
from: {};
stack.fromReverse​
fromReverse: {};
stack.prototype​
prototype: {
"Constructor": {
"_emptyHash": null | string;
"_innerProvable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"_nextHash": null | {};
"_provable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"emptyHash": string;
"prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; };
"create": ;
};
"data": {
"get": ;
"set": ;
"setTo": ;
"updateAsProver": ;
};
"hash": string;
"innerProvable": {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"clone": ;
"forEach": ;
"isEmpty": ;
"lengthUnconstrained": ;
"nextHash": ;
"pop": ;
"popExn": ;
"popIf": ;
"popIfUnsafe": ;
"push": ;
"pushIf": ;
"startIterating": ;
"startIteratingFromLast": ;
"toArrayUnconstrained": ;
};
stack.prototype.Constructor​
Constructor: {
"_emptyHash": null | string;
"_innerProvable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"_nextHash": null | {};
"_provable": null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
"emptyHash": string;
"prototype": { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; };
"create": ;
};
stack.prototype.Constructor._emptyHash​
_emptyHash: null | string;
stack.prototype.Constructor._innerProvable​
_innerProvable: null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
stack.prototype.Constructor._nextHash​
_nextHash: null | {};
stack.prototype.Constructor._provable​
_provable: null | {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
stack.prototype.Constructor.emptyHash​
emptyHash: string;
stack.prototype.Constructor.prototype​
prototype: { hash: string; data: { get: {}; set: {}; setTo: {}; updateAsProver: {}; }; isEmpty: {}; push: {}; pushIf: {}; popExn: {}; pop: {}; popIf: {}; popIfUnsafe: {}; clone: {}; forEach: {}; startIterating: {}; startIteratingFromLast: {}; ... 4 more ...; readonly innerProvable: { ...; }; };
stack.prototype.Constructor.create​
create;

Create a Merkle list type

Optionally, you can tell create() how to do the hash that pushes a new list element, by passing a nextHash function.

Example​
class MyList extends MerkleList.create(Field, (hash, x) =>
Poseidon.hashWithPrefix('custom', [hash, x])
) {}
stack.prototype.data​
data: {
"get": ;
"set": ;
"setTo": ;
"updateAsProver": ;
};
stack.prototype.data.get​
get;

Read an unconstrained value.

Note: Can only be called outside provable code.

stack.prototype.data.set​
set;

Modify the unconstrained value.

stack.prototype.data.setTo​
setTo;

Set the unconstrained value to the same as another Unconstrained.

stack.prototype.data.updateAsProver​
updateAsProver;

Update an Unconstrained by a witness computation.

stack.prototype.hash​
hash: string;
stack.prototype.innerProvable​
innerProvable: {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
stack.prototype.innerProvable.check​
check: {};

Add assertions to the proof to check if value is a valid member of type T. This function does not return anything, instead it creates any number of assertions to prove that value is a valid member of the type T.

For instance, calling check function on the type Bool asserts that the value of the element is either 1 or 0.

Param​

the element of type T to put assertions on.

stack.prototype.innerProvable.empty​
empty: {};
stack.prototype.innerProvable.fromFields​
fromFields: {};

A function that returns an element of type T from the given provable and "auxiliary" data.

This function is the reverse operation of calling toFields and toAuxilary methods on an element of type T.

Param​

an array of Field elements describing the provable data of the new T element.

Param​

an array of any type describing the "auxiliary" data of the new T element, optional.

stack.prototype.innerProvable.fromValue​
fromValue: {};

Convert provable type from a normal JS type.

stack.prototype.innerProvable.toAuxiliary​
toAuxiliary: {};

A function that takes value (optional), an element of type T, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of value.

Param​

the element of type T to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned.

stack.prototype.innerProvable.toCanonical?​
optional toCanonical: null | {};

Optional method which transforms a provable type into its canonical representation.

This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations.

An example is the ForeignField class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error.

Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. toCanonical() converts any input into a safe form and enables us to handle cases like this generically.

Note: For most types, this method is the identity function. The identity function will also be used when the toCanonical() is not present on a type.

stack.prototype.innerProvable.toFields​
toFields: {};

A function that takes value, an element of type T, as argument and returns an array of Field elements that make up the provable data of value.

Param​

the element of type T to generate the Field array from.

stack.prototype.innerProvable.toInput​
toInput: {};
stack.prototype.innerProvable.toValue​
toValue: {};

Convert provable type to a normal JS type.

stack.prototype.innerProvable.sizeInFields​
sizeInFields;
stack.prototype.clone​
clone;
stack.prototype.forEach​
forEach;

Iterate through the list in a fixed number of steps any apply a given callback on each element.

Proves that the iteration traverses the entire list. Once past the last element, dummy elements will be passed to the callback.

Note: There are no guarantees about the contents of dummy elements, so the callback is expected to handle the isDummy flag separately.

stack.prototype.isEmpty​
isEmpty;
stack.prototype.lengthUnconstrained​
lengthUnconstrained;
stack.prototype.nextHash​
nextHash;
stack.prototype.pop​
pop;

Remove the last element from the list and return it.

If the list is empty, returns a dummy element.

stack.prototype.popExn​
popExn;

Remove the last element from the list and return it.

This proves that the list is non-empty, and fails otherwise.

stack.prototype.popIf​
popIf;

Return the last element, but only remove it if condition is true.

If the list is empty, returns a dummy element.

stack.prototype.popIfUnsafe​
popIfUnsafe;

Low-level, minimal version of pop() which lets the caller decide whether there is an element to pop.

I.e. this proves:

  • If the input condition is true, this returns the last element and removes it from the list.
  • If the input condition is false, the list is unchanged and the return value is garbage.

Note that if the caller passes true but the list is empty, this will fail. If the caller passes false but the list is non-empty, this succeeds and just doesn't pop off an element.

stack.prototype.push​
push;

Push a new element to the list.

stack.prototype.pushIf​
pushIf;

Push a new element to the list, if the condition is true.

stack.prototype.startIterating​
startIterating;
stack.prototype.startIteratingFromLast​
startIteratingFromLast;
stack.prototype.toArrayUnconstrained​
toArrayUnconstrained;
stack.provable​
provable: {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
stack.provable.check​
check: {};

Add assertions to the proof to check if value is a valid member of type T. This function does not return anything, instead it creates any number of assertions to prove that value is a valid member of the type T.

For instance, calling check function on the type Bool asserts that the value of the element is either 1 or 0.

Param​

the element of type T to put assertions on.

stack.provable.empty​
empty: {};
stack.provable.fromFields​
fromFields: {};

A function that returns an element of type T from the given provable and "auxiliary" data.

This function is the reverse operation of calling toFields and toAuxilary methods on an element of type T.

Param​

an array of Field elements describing the provable data of the new T element.

Param​

an array of any type describing the "auxiliary" data of the new T element, optional.

stack.provable.fromValue​
fromValue: {};

Convert provable type from a normal JS type.

stack.provable.toAuxiliary​
toAuxiliary: {};

A function that takes value (optional), an element of type T, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of value.

Param​

the element of type T to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned.

stack.provable.toCanonical?​
optional toCanonical: null | {};

Optional method which transforms a provable type into its canonical representation.

This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations.

An example is the ForeignField class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error.

Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. toCanonical() converts any input into a safe form and enables us to handle cases like this generically.

Note: For most types, this method is the identity function. The identity function will also be used when the toCanonical() is not present on a type.

stack.provable.toFields​
toFields: {};

A function that takes value, an element of type T, as argument and returns an array of Field elements that make up the provable data of value.

Param​

the element of type T to generate the Field array from.

stack.provable.toInput​
toInput: {};
stack.provable.toValue​
toValue: {};

Convert provable type to a normal JS type.

stack.provable.sizeInFields​
sizeInFields;
stack.create​
create;

Create a Merkle list type

Optionally, you can tell create() how to do the hash that pushes a new list element, by passing a nextHash function.

Example​
class MyList extends MerkleList.create(Field, (hash, x) =>
Poseidon.hashWithPrefix('custom', [hash, x])
) {}
useOnchainStack​
useOnchainStack: boolean = Bool;
witnesses​
witnesses: {
"check": {};
"empty": {};
"fromFields": {};
"fromValue": {};
"toAuxiliary": {};
"toCanonical": null | {};
"toFields": {};
"toInput": {};
"toValue": {};
"sizeInFields": ;
};
witnesses.check​
check: {};

Add assertions to the proof to check if value is a valid member of type T. This function does not return anything, instead it creates any number of assertions to prove that value is a valid member of the type T.

For instance, calling check function on the type Bool asserts that the value of the element is either 1 or 0.

Param​

the element of type T to put assertions on.

witnesses.empty​
empty: {};
witnesses.fromFields​
fromFields: {};

A function that returns an element of type T from the given provable and "auxiliary" data.

This function is the reverse operation of calling toFields and toAuxilary methods on an element of type T.

Param​

an array of Field elements describing the provable data of the new T element.

Param​

an array of any type describing the "auxiliary" data of the new T element, optional.

witnesses.fromValue​
fromValue: {};

Convert provable type from a normal JS type.

witnesses.toAuxiliary​
toAuxiliary: {};

A function that takes value (optional), an element of type T, as argument and returns an array of any type that make up the "auxiliary" (non-provable) data of value.

Param​

the element of type T to generate the auxiliary data array from, optional. If not provided, a default value for auxiliary data is returned.

witnesses.toCanonical?​
optional toCanonical: null | {};

Optional method which transforms a provable type into its canonical representation.

This is needed for types that have multiple representations of the same underlying value, and might even not have perfect completeness for some of those representations.

An example is the ForeignField class, which allows non-native field elements to exist in unreduced form. The unreduced form is not perfectly complete, for example, addition of two unreduced field elements can cause a prover error.

Specific protocols need to be able to protect themselves against incomplete operations at all costs. For example, when using actions and reducer, the reducer must be able to produce a proof regardless of the input action. toCanonical() converts any input into a safe form and enables us to handle cases like this generically.

Note: For most types, this method is the identity function. The identity function will also be used when the toCanonical() is not present on a type.

witnesses.toFields​
toFields: {};

A function that takes value, an element of type T, as argument and returns an array of Field elements that make up the provable data of value.

Param​

the element of type T to generate the Field array from.

witnesses.toInput​
toInput: {};
witnesses.toValue​
toValue: {};

Convert provable type to a normal JS type.

witnesses.sizeInFields​
sizeInFields;

Inherited from​

BatchReducer_.BatchReducer.Batch

Source​

lib/mina/actions/batch-reducer.ts:67


BatchProof​

BatchProof: typeof Proof;

Inherited from​

BatchReducer_.BatchReducer.BatchProof

Source​

lib/mina/actions/batch-reducer.ts:70


_contract?​

optional _contract: BatchReducerContract;

Inherited from​

BatchReducer_.BatchReducer._contract

Source​

lib/mina/actions/batch-reducer.ts:164


_contractClass?​

optional _contractClass: BatchReducerContractClass;

Inherited from​

BatchReducer_.BatchReducer._contractClass

Source​

lib/mina/actions/batch-reducer.ts:165


actionType​

actionType: Provable<Action, any> & {
"empty": () => Action;
} & {
"toInput": (x: Action) => HashInput;
} & Omit<Provable<Action, any>, "fromFields"> & {
"fromFields": (fields: Field[]) => Action;
};

Type declaration​

empty()​
empty: () => Action;
Returns​

Action

Type declaration​

toInput()​
toInput: (x: Action) => HashInput;
Parameters​

• x: Action

Returns​

HashInput

Type declaration​

fromFields()​
fromFields: (fields: Field[]) => Action;
Parameters​

• fields: Field[]

Returns​

Action

Inherited from​

BatchReducer_.BatchReducer.actionType

Source​

lib/mina/actions/batch-reducer.ts:66


batchSize​

batchSize: BatchSize;

Inherited from​

BatchReducer_.BatchReducer.batchSize

Source​

lib/mina/actions/batch-reducer.ts:65


maxActionsPerUpdate​

maxActionsPerUpdate: number;

Inherited from​

BatchReducer_.BatchReducer.maxActionsPerUpdate

Source​

lib/mina/actions/batch-reducer.ts:73


maxUpdatesFinalProof​

maxUpdatesFinalProof: number;

Inherited from​

BatchReducer_.BatchReducer.maxUpdatesFinalProof

Source​

lib/mina/actions/batch-reducer.ts:72


program​

program: ActionStackProgram;

Inherited from​

BatchReducer_.BatchReducer.program

Source​

lib/mina/actions/batch-reducer.ts:69

Accessors​

initialActionStack​

get static initialActionStack(): Field

Returns​

Field

Source​

lib/mina/actions/batch-reducer.ts:160


initialActionState​

get static initialActionState(): Field

Returns​

Field

Source​

lib/mina/actions/batch-reducer.ts:157

Methods​

compile()​

compile(): Promise<{
"verificationKey": {
"data": string;
"hash": Field;
};
}>

Compile the recursive action stack prover.

Returns​

Promise\<{ "verificationKey": { "data": string; "hash": Field; }; }>

verificationKey​
verificationKey: {
"data": string;
"hash": Field;
};
verificationKey.data​
data: string;
verificationKey.hash​
hash: Field;

Inherited from​

BatchReducer_.BatchReducer.compile

Source​

lib/mina/actions/batch-reducer.ts:421


contract()​

contract(): BatchReducerContract

Returns​

BatchReducerContract

Inherited from​

BatchReducer_.BatchReducer.contract

Source​

lib/mina/actions/batch-reducer.ts:174


contractClass()​

contractClass(): BatchReducerContractClass

Returns​

BatchReducerContractClass

Inherited from​

BatchReducer_.BatchReducer.contractClass

Source​

lib/mina/actions/batch-reducer.ts:167


dispatch()​

dispatch(action: From<ActionType>): void

Submit an action.

Parameters​

• action: From\<ActionType>

Returns​

void

Inherited from​

BatchReducer_.BatchReducer.dispatch

Source​

lib/mina/actions/batch-reducer.ts:202


dispatchIf()​

dispatchIf(condition: Bool, action: From<ActionType>): void

Conditionally submit an action.

Parameters​

• condition: Bool

• action: From\<ActionType>

Returns​

void

Inherited from​

BatchReducer_.BatchReducer.dispatchIf

Source​

lib/mina/actions/batch-reducer.ts:215


prepareBatches()​

prepareBatches(): Promise<{
"batch": ActionBatch<Action>;
"proof": ActionStackProof;
}[]>

Create a proof which returns the next actions batch(es) to process and helps guarantee their correctness.

Returns​

Promise\<{ "batch": ActionBatch\<Action>; "proof": ActionStackProof; }[]>

Inherited from​

BatchReducer_.BatchReducer.prepareBatches

Source​

lib/mina/actions/batch-reducer.ts:428


processBatch()​

processBatch(__namedParameters: {
"batch": ActionBatch<Action>;
"proof": Proof<Field, ActionStackState>;
}, callback: (action: Action, isDummy: Bool, i: number) => void): void

Process a batch of actions which was created by prepareBatches().

Important: The callback exposes the action's value along with an isDummy flag. This is necessary because we process a dynamically-sized list in a fixed number of steps. Dummies will be passed to your callback once the actual actions are exhausted.

Make sure to write your code to account for dummies. For example, when sending MINA from your contract for every action, you probably want to zero out the balance decrease in the isDummy case:

processBatch({ batch, proof }, (action, isDummy) => {
// ... other logic ...

let amountToSend = Provable.if(isDummy, UInt64.zero, action.amount);
this.balance.subInPlace(amountToSend);
});

Warning: Don't call processBatch() on two different batches within the same method. The second call would override the preconditions set by the first call, which would leave the method insecure. To process more actions per method call, increase the batchSize.

Parameters​

• __namedParameters

• __namedParameters.batch: ActionBatch\<Action>

• __namedParameters.proof: Proof\<Field, ActionStackState>

• callback

Returns​

void

Inherited from​

BatchReducer_.BatchReducer.processBatch

Source​

lib/mina/actions/batch-reducer.ts:253


setContractClass()​

setContractClass(contractClass: BatchReducerContractClass): void

Set the smart contract class this reducer is connected with.

Note: You can use either this method or setContractInstance() before calling compile(). However, setContractInstance() is required for proveNextBatch().

Parameters​

• contractClass: BatchReducerContractClass

Returns​

void

Inherited from​

BatchReducer_.BatchReducer.setContractClass

Source​

lib/mina/actions/batch-reducer.ts:195


setContractInstance()​

setContractInstance(contract: BatchReducerContract): void

Set the smart contract instance this reducer is connected with.

Note: This is a required step before using dispatch(), proveNextBatch() or processNextBatch().

Parameters​

• contract: BatchReducerContract

Returns​

void

Inherited from​

BatchReducer_.BatchReducer.setContractInstance

Source​

lib/mina/actions/batch-reducer.ts:184