Skip to main content
For the complete documentation index, see llms.txt

Ledger API

@midnight-ntwrk/ledger v3.0.2 • Readme | API


Ledger TypeScript API

This document outlines the flow of transaction assembly and usage with the ledger TS API.

Network ID​

Prior to any interaction, setNetworkId should be used to set the NetworkId to target the correct network.

Proof stages​

Most transaction components will be in one of three stages: X, UnprovenX, or ProofErasedX. The UnprovenX stage is always the first one. It is possible to transition to the X stage by proving an UnprovenTransaction through the proof server. For testing, and where proofs aren't necessary, the ProofErasedX stage is used, which can be reached via eraseProof[s] from the other two stages.

Transaction structure​

A Transaction runs in two phases: a guaranteed phase, handling fee payments and fast-to-verify operations, and a fallible phase, handling operations which may fail atomically, separately from the guaranteed phase. It therefore contains:

It also contains additional cryptographic glue that will be omitted in this document.

Zswap​

A Zswap Offer consists of:

  • A set of Inputs, burning coins.
  • A set of Outputs, creating coins.
  • A set of Transients, indicating a coin that is created and burnt in the same transaction.
  • A mapping from TokenTypes to offer balance, positive when there are more inputs than outputs and vice versa.

Inputs can be created either from a QualifiedCoinInfo and a contract address, if the coin is contract-owned, or from a QualifiedCoinInfo and a ZswapLocalState, if it is user-owned. Similarly, Outputs can be created from a CoinInfo and a contract address for contract-owned coins, or from a CoinInfo and a user's public key(s), if it is user-owned. A Transient is created similarly to a Input, but directly converts an existing Output.

A QualifiedCoinInfo is a CoinInfo with an index into the Merkle tree of coin commitments that can be used to find the relevant coin to spend, while a CoinInfo consists of a coins TokenType, value, and a nonce.

Calls​

A ContractDeploy consists of an initial contract state, and a nonce.

A ContractCall consists of a contract's address, the entry point used on this contract, a guaranteed and a fallible public oracle transcript, a communication commitment, and a proof. ContractCalls are constructed via ContractCallPrototypes, which consist of the following raw pieces of data:

  • The contract address
  • The contract's entry point
  • The contract operation expected (that is, the verifier key and transcript shape expected to be at this contract address and entry point)
  • The guaranteed transcript (as produced by the generated JS code)
  • The fallible transcript (as produced by the generated JS code)
  • The outputs of the private oracle calls (As a FAB AlignedValues)
  • The input(s) to the call, concatenated together (As a FAB AlignedValue)
  • The output(s) to the call, concatenated together (As a FAB AlignedValue)
  • The communications commitment randomness (As a hex-encoded field element string)
  • A unique identifier for the ZK circuit used (used by the proof server to index for the prover key)

NOTE: currently the JS code only generates a single transcript. We probably just want a canonical way to split this into guaranteed/fallible?

A ContractCalls object is assembed, and ContractCallPrototypes / ContractDeploys are added to this directly. This can then be inserted into an UnprovenTransaction.

State Structure​

The LedgerState is the primary entry point for Midnight's ledger state, and it consists of a ZswapChainState, as well as a mapping from ContractAddresses to ContractStates. States are immutable, and applying transactions always produce new outputs states.