Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save aaronbassett/e37737b64a3fb501bd3a7967f72083f1 to your computer and use it in GitHub Desktop.

Select an option

Save aaronbassett/e37737b64a3fb501bd3a7967f72083f1 to your computer and use it in GitHub Desktop.
Compact Dev CLI: Comprehensive Reference - Every command, flag, env var, and internal detail

Compact Dev CLI: Comprehensive Reference

Deep dive into every command, subcommand, flag, option, argument, environment variable, and configuration detail of the Compact toolchain.

Generated: 2026-03-27 | compact v0.5.1 | compactc v0.30.104 | Language v0.22.101


Table of Contents

  1. Architecture Overview
  2. The compact CLI (Toolchain Manager)
  3. The compactc Compiler
  4. The format-compact Formatter
  5. The fixup-compact Migration Tool
  6. The zkir Circuit Compiler
  7. The midnight-proof-server
  8. The onchain-runtime VM
  9. WASM Targets
  10. Runtime (@midnight-ntwrk/compact-runtime)
  11. Editor Support
  12. Build System and Nix Configuration
  13. Test Infrastructure
  14. Utility Scripts
  15. All URLs Used by the Toolchain
  16. Complete Environment Variable Index
  17. Version Matrix

1. Architecture Overview

The Compact toolchain is a multi-layered system for developing zero-knowledge smart contracts on the Midnight Network. The architecture consists of:

compact (Rust CLI - toolchain version manager)
  |
  +-- compactc (Chez Scheme compiler)
  |     |
  |     +-- zkir / zkir-v3 (Rust binary - ZK circuit compiler)
  |     |     |
  |     |     +-- BLS12-381 public parameters (downloaded from S3)
  |     |
  |     +-- contract/index.js, index.d.ts, index.js.map (TypeScript output)
  |     +-- compiler/contract-info.json (contract metadata)
  |     +-- zkir/*.zkir (circuit IR files)
  |     +-- keys/*.prover, *.verifier (proving/verifying keys)
  |
  +-- format-compact (Chez Scheme - source formatter)
  +-- fixup-compact (Chez Scheme - migration/fixup tool)
  |
  +-- midnight-proof-server (Rust/actix-web - HTTP proof generation)
  +-- onchain-runtime (Rust - smart contract VM)
  +-- @midnight-ntwrk/compact-runtime (TypeScript - JS runtime)

Key insight: The compact CLI (Rust) is a thin toolchain manager. The actual compiler (compactc), formatter (format-compact), and fixup tool (fixup-compact) are all Chez Scheme programs. The compact CLI downloads, manages versions of, and proxies calls to these Scheme binaries.


2. The compact CLI (Toolchain Manager)

Source: tools/compact/ Language: Rust Version: 0.5.1 Binary: compact

2.1 Global Options

These options are available on every command:

Flag Env Var Default Description
--directory <DIRECTORY> COMPACT_DIRECTORY $HOME/.compact Set the compact artifact directory
--target <TARGET> Auto-detected Hidden flag. Override platform target. Values: x86_64-unknown-linux-musl, aarch64-unknown-linux-musl, x86_64-apple-darwin, aarch64-darwin
-h / --help Print help (-h = summary, --help = full)
-V / --version Print version

2.2 Commands

compact check (aliases: ch)

Check for available compiler updates.

compact check [OPTIONS]

Hidden aliases: che, chec

Behavior:

  • Fetches GitHub releases from midnightntwrk/compact
  • Compares latest remote compactc version against the locally installed default
  • Prints either "Up to date" (green) or "Update Available" (yellow) + version

No additional flags beyond globals.


compact update (aliases: u, up)

Install a specific version of the Compact toolchain.

compact update [OPTIONS] [COMPACT_VERSION]

Hidden aliases: upd, upda, updat

Argument/Flag Description
[COMPACT_VERSION] Optional positional. Version to install: 0.29.0 (exact), 0.29 (latest patch), 0 (latest for major). Omit for latest.
--no-set-default Don't make the newly installed compiler the default

Behavior:

  1. Checks if requested version is already installed locally (skips download if so)
  2. Fetches GitHub releases to resolve version
  3. Downloads artifact zip to <compact_dir>/versions/<version>/<target>/artifact.zip
  4. Extracts using system unzip binary (hard dependency)
  5. Creates symlinks in <compact_dir>/bin/ (unless --no-set-default)

Supports resumable downloads: If artifact.zip.partial exists, resumes from that offset using HTTP Range header.


compact format (aliases: f, fmt)

Format Compact source files.

compact format [OPTIONS] [FILES]...

Hidden aliases: fo, for, form, forma

Argument/Flag Short Description
[FILES]... Files or directories to format (default: .)
--check -c Check if inputs are formatted without changing them
--verbose -v Print each file seen by the formatter
--version -V Print the toolchain version (delegates to format-compact --version)
--language-version Print the language version (delegates to format-compact --language-version)

Behavior:

  • Locates format-compact binary at <compact_dir>/bin/format-compact
  • Errors if binary not found: "formatter not available - please install a compiler version that includes format-compact"
  • For directories: walks recursively, finding *.compact files, respecting .gitignore
  • Runs format-compact in parallel (via tokio::task::JoinSet) on all discovered files
  • In check mode (-c): shows colored diff (deletions=Magenta, insertions=Cyan) using the similar crate

compact fixup (aliases: fx, fix)

Apply migration/fixup transformations to Compact source files.

compact fixup [OPTIONS] [FILES]...

Hidden aliases: fi, fixu

Argument/Flag Short Description
[FILES]... Files or directories to fixup (default: .)
--check -c Check if inputs need fixup without changing them
--update-Uint-ranges Adjust Uint range endpoints (note: capital U in Uint)
--vscode Format error messages as single line (for VS Code extension)
--verbose -v Print verbose output
--version -V Print the toolchain version
--language-version Print the language version

Behavior:

  • Locates fixup-compact binary at <compact_dir>/bin/fixup-compact
  • Errors if not found: "fixup tool not available - please install a compiler version that includes fixup-compact"
  • Forwards --update-Uint-ranges and --vscode to the underlying binary
  • Same file discovery and parallel processing as format

compact list (aliases: l)

List available Compact compiler versions.

compact list [OPTIONS]

Hidden aliases: li, lis

Flag Short Description
--installed -i Show locally installed versions instead of all available remote versions

Behavior:

  • Without --installed: fetches GitHub releases, prints all versions with platform availability tags (x86_macos, aarch64_macos, x86_linux, aarch64_linux). Current version indicated with ->.
  • With --installed: reads <compact_dir>/versions/ directory, lists versions sorted newest-first. Current version indicated with ->.

compact clean (aliases: cl)

Remove installed compiler versions.

compact clean [OPTIONS]

Hidden aliases: cle, clea

Flag Short Description
--keep-current -k Preserve the currently-active version
--cache Also remove the GitHub API response cache

Behavior:

  • Reads current version from bin/compactc symlink
  • Iterates versions/ directory, removes each version directory
  • If --keep-current: skips the active version
  • If --cache: deletes github_cache.json from the cache directory

compact self (aliases: s)

Manage the compact tool itself.

Hidden aliases: se, sel

compact self check

Check if a newer version of the compact CLI tool is available.

compact self check [OPTIONS]

Uses axoupdater to check GitHub releases for the compact tool (not compactc). Reads the installer receipt at $HOME/.config/compact/ (or $XDG_CONFIG_HOME/compact/ or $RECEIPT_HOME/).

compact self update

Update the compact CLI tool itself.

compact self update [OPTIONS]

Downloads and installs the new compact binary in-place via axoupdater.


compact compile (aliases: c)

Proxy call to the compactc compiler.

compact compile [OPTIONS] [ARGS]...

Hidden aliases: co, com, comp, compi, compil

Argument Description
[ARGS]... All arguments passed through to compactc (use +VERSION to select compiler version)

The +VERSION mechanism:

# Use default compiler
compact compile myfile.compact output/

# Use specific installed version
compact compile +0.29.0 myfile.compact output/

# Get compiler help
compact compile -- --help

Important: +VERSION only accepts exact 3-part semver (e.g., +0.29.0). Partial versions (+0.29) are NOT supported for compile (unlike update).

Behavior:

  1. Scans args for any argument starting with +
  2. If found: strips it, parses as exact version, finds that installed compiler
  3. If not found: uses the default compiler (from bin/compactc symlink)
  4. Spawns compactc with all remaining args, inherits stdin/stdout/stderr
  5. Propagates exit code directly via std::process::exit(code)

2.3 Hidden Features

Hidden --target Flag

Available on the top-level CLI (global), hidden from --help:

compact --target aarch64-darwin update 0.30.0

Overrides platform auto-detection. Useful for testing cross-platform behavior. Values:

  • x86_64-unknown-linux-musl
  • aarch64-unknown-linux-musl
  • x86_64-apple-darwin
  • aarch64-darwin

Hidden Command Aliases (Prefix Matching)

All commands have hidden aliases for progressive prefix matching:

Command Visible Aliases Hidden Aliases
check ch che, chec
update u, up upd, upda, updat
format f, fmt fo, for, form, forma
fixup fx, fix fi, fixu
list l li, lis
clean cl cle, clea
self s se, sel
compile c co, com, comp, compi, compil

Stale Cache Behavior

When GitHub API rate limit remaining < 10 AND current time < rate limit reset time, the CLI silently serves potentially stale cached data (even if older than the 15-minute TTL). A warning is printed to stderr.

Partial Download Resume

If artifact.zip.partial exists in the version directory, the HTTP client automatically sends a Range: bytes=<size>- header to resume the download.


2.4 All Environment Variables

Variable Used By Purpose
COMPACT_DIRECTORY compact CLI Override ~/.compact artifact directory. Equivalent to --directory.
GITHUB_TOKEN compact CLI GitHub API personal token to avoid rate limiting. Used in check, list, self check, self update, and update. Optional.
HOME compact CLI Determines default ~/.compact path. Also used for cache directory fallback.
XDG_CONFIG_HOME axoupdater Override config directory for self-update receipt lookup.
XDG_CACHE_HOME compact CLI Override cache directory for github_cache.json.
RECEIPT_HOME axoupdater Direct override of the receipt directory for self-update.

Compile-time constants (not user-configurable):

  • CARGO_PKG_NAME = "compact" — used for user-agent string
  • CARGO_PKG_VERSION = "0.5.1" — used for user-agent string and version display

2.5 Directory Structure (~/.compact/)

~/.compact/                                  # or $COMPACT_DIRECTORY
|-- bin/
|   |-- compactc          -> symlink to current version
|   |-- format-compact    -> symlink to current version (if available)
|   `-- fixup-compact     -> symlink to current version (if available)
`-- versions/
    `-- <semver>/                            # e.g. "0.30.0"
        `-- <target>/                        # e.g. "aarch64-darwin"
            |-- artifact.zip                 # downloaded archive (kept)
            |-- artifact.zip.partial         # temporary during download
            |-- compactc                     # compiler binary
            |-- format-compact               # formatter binary (may not exist in older versions)
            |-- fixup-compact                # fixup binary (may not exist in older versions)
            |-- lib/                         # library files (zkir, etc.)
            `-- public_params.bin            # zkir public parameters

Cache file:

~/.cache/compactc/github_cache.json          # macOS: ~/Library/Caches/compactc/github_cache.json

Self-update receipt:

~/.config/compact/                           # or $XDG_CONFIG_HOME/compact/ or $RECEIPT_HOME/

Note: format-compact and fixup-compact were not shipped in versions <= 0.24.0. The symlinks are only created if the binary exists in the extracted archive.


2.6 Download and Update Mechanism

GitHub Release Discovery:

  1. Fetches GET https://api.github.com/repos/midnightntwrk/compact/releases via octocrab
  2. Filters releases where tag_name contains "compactc" (pattern: compactc-vX.Y.Z)
  3. Strips "compactc-v" prefix to extract version
  4. Caches response for 15 minutes at <cache_dir>/compactc/github_cache.json

Retry logic:

  • MAX_RETRIES = 3
  • Exponential backoff: 1s, 2s delays
  • Prints to stderr on each failure

Rate limit protection:

  • If rate_limit_remaining < 10 AND current time < rate_limit_reset: uses stale cache with warning

Download:

  • Uses reqwest with gzip, rustls-tls
  • User-agent: "compact/0.5.1"
  • Supports HTTP Range header for resume
  • Shows progress bar: [elapsed] [bar] bytes/total (speed, eta)

Extraction:

  • Calls system unzip binary (hard dependency on unzip in $PATH)

Self-update:

  • Uses axoupdater crate with github_releases feature
  • Installer script: https://github.com/midnightntwrk/compact/releases/download/compact-v{VERSION}/compact-installer.sh

2.7 Version Resolution Logic

The update command accepts a VersionSpec:

Input Parsed As Match Logic
0.29.0 Exact(0.29.0) Only matches exact version
0.29 Partial { major: 0, minor: 29 } Matches any 0.29.x (picks latest patch)
0 Major { major: 0 } Matches any 0.x.y (picks latest minor+patch)

Resolution iterates available versions in reverse order (newest first), returns first match.

The compile command's +VERSION only accepts exact 3-part semver.


2.8 Platform Targets

Target String OS Arch Asset Name Pattern
x86_64-unknown-linux-musl Linux x86_64 contains "x86_64-unknown-linux"
aarch64-unknown-linux-musl Linux aarch64 contains "aarch64-unknown-linux" or "aarch64-linux"
x86_64-apple-darwin macOS x86_64 contains "x86_64-apple-darwin" or "x86_64-darwin"
aarch64-darwin macOS aarch64 contains "aarch64-darwin"

3. The compactc Compiler

Source: compiler/compactc.ss Language: Chez Scheme (nanopass framework) Version: 0.30.104 Language Version: 0.22.101

3.1 All Flags and Arguments

compactc <flag> ... <source-pathname> <target-directory-pathname>
Flag Takes Argument Description
--help No Print detailed help text and exit
--version No Print compiler version (e.g., 0.30.104) and exit
--language-version No Print language version (e.g., 0.22.101) and exit
--ledger-version No Print ledger version for the active zkir backend and exit
--runtime-version No Print the Compact runtime JS package version and exit
--vscode No Collapse multi-line error messages to single lines for VS Code
--skip-zk No Skip generating proving keys (faster, TypeScript-only output)
--no-communications-commitment No Omit contract communications commitment for contract-to-contract calls
--sourceRoot <string> Override sourceRoot in generated .js.map file
--compact-path <search-list> Colon-separated (semicolon on Windows) search path for includes/imports. Overrides COMPACT_PATH env var
--trace-search No Print trace of file lookups during include/import resolution
--trace-passes No Print each IR after every compiler pass (for compiler developers)
--feature-zkir-v3 No HIDDEN/UNDOCUMENTED. Switch from zkir-v2 to zkir-v3 IR format

Positional arguments:

  • <source-pathname> — Path to the .compact source file
  • <target-directory-pathname> — Path to the output directory

Important notes:

  • --skip-zk defaults to #t (true) in the source, meaning ZK key generation is skipped by default
  • --feature-zkir-v3 is NOT listed in --help output but IS functional
  • --vscode collapses multi-line errors into single lines by replacing \n + whitespace with ;

3.2 Environment Variables

Variable Purpose
COMPACT_PATH Default module/include search path. Colon-separated (semicolon on Windows) directory list. Overridden by --compact-path flag. This is the ONLY environment variable read by the compiler.

Exhaustive search of the compiler source confirms only one getenv call exists: (getenv "COMPACT_PATH") in config-params.ss.

3.3 Output Files

The compiler produces this directory tree under <target-directory>:

<target-directory>/
|-- compiler/
|   `-- contract-info.json       # Contract metadata (JSON)
|-- contract/
|   |-- index.js                 # Generated JavaScript implementation
|   |-- index.d.ts               # TypeScript declaration file
|   `-- index.js.map             # Source map (Version 3)
|-- zkir/
|   |-- <circuit>.zkir           # One file per exported impure circuit
|   `-- <circuit>.bzkir          # Binary form (written by zkir)
`-- keys/
    |-- <circuit>.prover         # Proving key (generated by zkir)
    `-- <circuit>.verifier       # Verifying key (generated by zkir)

Cleanup behavior: On each compilation, compiler/, zkir/, and keys/ directories are rm-rf'd and recreated. The contract/ directory is NOT pre-cleaned. On error, all created files are cleaned up.

contract-info.json Structure

{
  "compiler-version": "0.30.104",
  "language-version": "0.22.101",
  "runtime-version": "0.15.101",
  "circuits": [
    {
      "name": "<export-name>",
      "pure": true,
      "proof": false,
      "arguments": [{ "name": "<arg>", "type": { "type-name": "Uint", "maxval": 255 } }],
      "result-type": { "type-name": "Boolean" }
    }
  ],
  "witnesses": [
    {
      "name": "<witness-name>",
      "arguments": [...],
      "result type": { ... }
    }
  ],
  "contracts": ["<contract-name>"]
}

Type representations:

Compact Type JSON type-name Extra Fields
Boolean "Boolean"
Field "Field"
Uint<N> "Uint" maxval: N
Bytes<N> "Bytes" length: N
Opaque<S> "Opaque" tsType: S
Vector<N, T> "Vector" length: N, type: {...}
Tuple "Tuple" types: [...]
Struct "Struct" name: ..., elements: [...]
Enum "Enum" name: ..., elements: [...]
Contract "Contract" name: ..., circuits: [...]
Nominal Alias "Alias" name: ..., type: {...}

3.4 Compiler Passes Pipeline

The complete compilation pipeline (generate-everything in passes.ss):

Stage 1: Parsing

# Pass Input -> Output IR Description
1 Lexer source text -> tokens Tokenization
2 parse-file tokens -> Lparser LR parsing (concrete syntax tree)
3 Lparser->Lsrc Lparser -> Lsrc CST to AST conversion

Stage 2: Frontend Passes

# Pass Output IR Description
4 resolve-includes Lnoinclude Expand include forms, resolve file paths, detect cycles
5 expand-const Lsingleconst Split multi-variable const into single-variable
6 expand-patterns Lnopattern Desugar tuple/struct pattern bindings
7 reject-for-return Lnopattern Error on return inside for loop
8 report-unreachable Lnopattern Error on unreachable statements
9 hoist-local-variables Lhoisted Lift const declarations to block top
10 reject-duplicate-bindings Lhoisted Error on duplicate parameter/field names
11 eliminate-statements Lexpr Convert statements to expressions
12 eliminate-boolean-connectives Lnoandornot not/and/or -> if
13 prepare-for-expand Lpreexpand Identity pass

Stage 3: Analysis Passes

# Pass Output IR Description
14 expand-modules-and-types Lexpanded Major pass: resolve identifiers, expand modules/imports, instantiate generics
15 generate-contract-ht Lexpanded Build contract declaration hashtable
16 infer-types Ltypes Full Hindley-Milner type inference
17 remove-tundeclared Lnotundeclared Remove undeclared type markers
18 combine-ledger-declarations Loneledger Merge all ledger declarations
19 discard-unused-functions Loneledger Dead code elimination
20 reject-recursive-circuits Loneledger Error on recursive circuit definitions
21 recognize-let Lnodca Let-binding recognition
22 check-sealed-fields Lnodca Enforce sealed ledger field access rules
23 reject-constructor-cc-calls Lnodca Error on contract-call in constructor
24 identify-pure-circuits Lnodca Mark circuits as pure (no ledger access)
25 determine-ledger-paths Lwithpaths0 Compute ledger state paths
26 propagate-ledger-paths Lwithpaths Propagate path information
27 track-witness-data Lwithpaths Track disclosure of private witness data
28 remove-disclose Lnodisclose Remove disclose() wrappers

Stage 4: Save Contract Info

# Pass Description
29 save-contract-info Write compiler/contract-info.json

Stage 5: TypeScript Generation (parallel with circuit passes)

# Pass Output IR Description
30 prepare-for-typescript Ltypescript Prepare IR for TS codegen
31 print-typescript Ltypescript Emit index.js, index.d.ts, index.js.map

Stage 6: Circuit Passes

# Pass Output IR Description
32 drop-ledger-runtime Lposttypescript Remove ledger ADT runtime operations
33 replace-enums Lnoenums Replace enum values with field integers
34 unroll-loops Lunrolled Statically unroll all loops
35 inline-circuits Linlined Inline circuit calls
36 drop-safe-casts Lnosafecast Remove safe type casts
37 resolve-indices/simplify Lnovectorref Resolve vector/tuple indices, constant fold
38 discard-useless-code Lnovectorref Dead code elimination
39 prune-unnecessary-circuits Lnovectorref Remove unreachable circuits
40 reduce-to-circuit Lcircuit Convert to circuit IR
41 flatten-datatypes Lflattened Flatten structs/tuples to primitives
42 optimize-circuit Lflattened Circuit-level optimizations

Stage 7: ZKIR Generation (branched by --feature-zkir-v3)

zkir-v2 path:

# Pass Description
43 print-zkir Print .zkir files (v2 JSON format)

zkir-v3 path:

# Pass Description
43a reduce-to-zkir Lflattened -> Lzkir (new v3 IR)
43b print-zkir-v3 Print .zkir files (v3 JSON format)

Stage 8: Key Generation

# Step Description
44 Invoke zkir compile-many External binary call to generate proving/verifying keys

3.5 Module and Import Resolution

Search algorithm for find-source-pathname:

  1. Append .compact extension to pathname
  2. If absolute path: try directly
  3. If relative, search in order: a. Directory of the currently-being-processed file (relative-path parameter) b. Each directory in compact-path list (left to right)
  4. If not found: raise error

Special case: If file is "std", error message suggests import CompactStandardLibrary instead.

Include cycle detection: Tracks already-seen pathnames; raises error if a cycle is detected.

Standard library: Always implicitly available. Loaded from compiler/standard-library.compact (path hardcoded in source).

3.6 Error Codes and Exit Statuses

Exit Code Error Type Description
0 Success
1 Usage error Bad arguments / invalid usage
254 Internal error Compiler bug (includes compiler source location)
255 Source error User-code error (source error, accumulated errors, zkir failure)

Error condition types:

  • &source-error-condition — error with source position
  • &halt-condition — accumulated errors signal to stop compilation
  • &pass-name-condition — wraps exceptions with the compiler pass name

3.7 Configuration Parameters

All parameters from config-params.ss (Chez Scheme make-parameter):

Parameter Default Set By
no-communications-commitment #f --no-communications-commitment
skip-zk #t --skip-zk
compact-path (split-search-path (or (getenv "COMPACT_PATH") "")) --compact-path
format-line-length 100 --line-length (format-compact only)
trace-passes #f --trace-passes
trace-search #f --trace-search
feature-zkir-v3 #f --feature-zkir-v3

Additional internal parameters:

  • target-ports — alist of symbolic target names to open output ports
  • target-directory — path to output directory
  • source-directory — directory of source file
  • source-file-name — base name of source file (used for contract name in TS output)
  • relative-path — for relative import path resolution
  • contract-ht — hashtable of contract declarations
  • proof-circuit-names — list of circuits needing ZK proofs
  • pending-conditions — accumulated non-fatal error conditions
  • renaming-table — source positions to old->new name mappings (used by fixup)
  • stdlib-sfd — source file descriptor for standard library
  • verbose-source-path? — whether to show full paths in errors
  • update-Uint-ranges — fixup-compact only: whether to update Uint range syntax
  • zkir-warning-issued — prevents duplicate "ZKIR not found" warnings

3.8 Standard Library

The standard library (compiler/standard-library.compact) is always implicitly available. Key exports:

Generic types:

  • Maybe<T> = { is_some: Boolean, value: T } + some<T>(), none<T>()
  • Either<A, B> = { is_left: Boolean, left: A, right: B } + left<A,B>(), right<A,B>()

Elliptic curves:

  • JubjubPoint (opaque type)
  • MerkleTreeDigest, MerkleTreePathEntry, MerkleTreePath<#n, T>
  • merkleTreePathRoot<#n, T>(), merkleTreePathRootNoLeafHash<#n>()

Midnight kernel types:

  • ContractAddress, ShieldedCoinInfo, QualifiedShieldedCoinInfo
  • ZswapCoinPublicKey, ShieldedSendResult, UserAddress

Token operations:

  • nativeToken(), tokenType(), mintShieldedToken(), sendShielded(), receiveShielded()
  • mintUnshieldedToken(), sendUnshielded(), receiveUnshielded()
  • unshieldedBalance(), unshieldedBalanceLt/Gte/Gt/Lte()
  • mergeCoin(), mergeCoinImmediate(), sendImmediateShielded()
  • blockTimeLt/Gte/Gt/Lte()

Ledger: export ledger kernel: Kernel;

3.9 Native Functions

Built-in circuit and witness declarations from midnight-natives.ss:

Circuit natives (map to JS runtime functions):

Compact Function JS Runtime Signature
transientHash<A> __compactRuntime.transientHash (A) -> Field
transientCommit<A> __compactRuntime.transientCommit (A, Field) -> Field
persistentHash<A> __compactRuntime.persistentHash (A) -> Bytes<32>
persistentCommit<A> __compactRuntime.persistentCommit (A, Bytes<32>) -> Bytes<32>
degradeToTransient __compactRuntime.degradeToTransient (Bytes<32>) -> Field
upgradeFromTransient __compactRuntime.upgradeFromTransient (Field) -> Bytes<32>
jubjubPointX __compactRuntime.jubjubPointX (JubjubPoint) -> Field
jubjubPointY __compactRuntime.jubjubPointY (JubjubPoint) -> Field
ecAdd __compactRuntime.ecAdd (JubjubPoint, JubjubPoint) -> JubjubPoint
ecMul __compactRuntime.ecMul (JubjubPoint, Field) -> JubjubPoint
ecMulGenerator __compactRuntime.ecMulGenerator (Field) -> JubjubPoint
hashToCurve<A> __compactRuntime.hashToCurve (A) -> JubjubPoint
constructJubjubPoint __compactRuntime.constructJubjubPoint (Field, Field) -> JubjubPoint

Witness natives:

Compact Function JS Runtime Signature
ownPublicKey __compactRuntime.ownPublicKey () -> ZswapCoinPublicKey
createZswapInput __compactRuntime.createZswapInput (QualifiedShieldedCoinInfo) -> []
createZswapOutput __compactRuntime.createZswapOutput (ShieldedCoinInfo, Either<ZswapCoinPublicKey, ContractAddress>) -> []

Standard library name aliases (deprecated snake_case -> new camelCase): The compiler maintains alias tables that emit warnings when old names are used. Examples: transient_hash -> transientHash, ec_add -> ecAdd, NativePoint -> JubjubPoint, merge_coin -> mergeCoin.

3.10 Pragma Handling

The language supports compiler version pragmas:

pragma language_version 0.22.*;
pragma compiler_version >= 0.30.0;

Grammar: pragma <name> <version-expression> ;

Version expressions support: ==, !=, <, <=, >=, >, and, or, not with three-part version numbers (wildcards * supported).

3.11 Source Map Generation

Generated .js.map files use Version 3 format:

{
  "version": 3,
  "file": "index.js",
  "sourceRoot": "<computed or --sourceRoot override>",
  "sources": ["<source-file-paths>"],
  "names": [],
  "mappings": "<Base64-VLQ encoded segment data>"
}

sourceRoot computation: Computes the longest common path ancestor between source files and the target directory, expressing the relationship as ../-prefixed relative paths. --sourceRoot overrides this entirely.

3.12 Field Arithmetic Constants

Constant Value Description
max-field 52435875175126190479447740508185965837690552500527637822603658699938581184512 BLS12-381 scalar field prime minus one
field-bits 254 (integer-length max-field) - 1
field-bytes 31 field-bits / 8
max-unsigned 2^248 - 1 Maximum unsigned integer (31 bytes)
max-bytes/vector-length 2^24 (16,777,216) Maximum Bytes or Vector length
max-merkle-tree-depth 32
min-merkle-tree-depth 2

4. The format-compact Formatter

4.1 Direct Invocation (format-compact binary)

format-compact <flag> ... <source-pathname> [<target-pathname>]
Flag Description
--help Print help and exit
--version Print compiler version and exit
--language-version Print language version and exit
--vscode Single-line error messages for VS Code
--line-length <n> Target line length (default: 100, must be non-negative integer)
--compact-path <list> Colon-separated search path (overrides COMPACT_PATH)
--trace-search Print file search trace messages

Invocation patterns:

  • format-compact source.compact — formats to stdout
  • format-compact source.compact target.compact — writes to target file
  • format-compact source.compact source.compact — in-place formatting

4.2 Via compact CLI (compact format)

The Rust CLI wraps format-compact with additional features:

  • Directory walking: Recursively discovers *.compact files
  • .gitignore respect: Uses the ignore crate (works even outside git repos)
  • Parallel processing: Processes files concurrently via tokio::task::JoinSet
  • Check mode with diffs: Shows colored diffs (Magenta=deletions, Cyan=insertions)

4.3 Formatting Rules

The formatter operates in 3 phases:

  1. Comment extraction: Builds hashtables mapping source locations to comments (up, left, right positions)
  2. Q-tree construction: Converts parse tree to Q nodes:
    • Qstring — atomic text
    • Qconcat — sequence of Q nodes
    • fixnum — optional newline/indent (nonneg=space when not broken; neg=no space; both force newline when breaking)
    • nl / nl2 / nl! — required newline / double newline / additive newline
    • nbsp — space suppressed at line start
  3. Q-tree rendering: Decides line breaks based on whether content exceeds target-line-length

4.4 File Discovery

ignore::WalkBuilder::new(dir)
    .follow_links(true)
    .require_git(false)
    .build()
    .filter(|d| d.extension() == Some("compact"))
  • Walks directories recursively
  • Follows symlinks
  • Respects .gitignore even outside git repos
  • Filters to *.compact files only

5. The fixup-compact Migration Tool

5.1 Direct Invocation (fixup-compact binary)

fixup-compact <flag> ... <source-pathname> [<target-pathname>]
Flag Description
--help Print help and exit
--version Print compiler version and exit
--language-version Print language version and exit
--vscode Single-line error messages for VS Code
--update-Uint-ranges Adjust Uint range endpoints
--compact-path <list> Colon-separated search path (overrides COMPACT_PATH)
--trace-search Print file search trace messages

5.2 Via compact CLI (compact fixup)

Same wrapping as format: directory walking, .gitignore respect, parallel processing, check mode with diffs.

5.3 Fixup Transformations

Pass 1 — pre-fixup (before analysis, handles syntax-breaking changes):

  1. include "std" -> import CompactStandardLibrary — Migrates from old include syntax to modern import syntax.

  2. --update-Uint-ranges — Increments upper bound of Uint<lo..hi> by 1 (converting exclusive to inclusive range semantics). Supports decimal, hex (0x), octal (0o), and binary (0b) literals, preserving the original base. If upper bound is a generic parameter reference, emits warning: must be updated manually.

Pass 2 — fixup (after analysis, using renaming table):

  1. Name migration — Uses a renaming-table populated by analysis passes. Checks each identifier in exports, field references (expr.field), method calls (expr.method(...)), function references, and type references. Substitutes the new name where registered.

Post-fixup: The fixed-up parse tree is run through the formatter to produce clean output.


6. The zkir Circuit Compiler

Source (v2): midnight-ledger/zkir/ Source (v3): midnight-ledger/zkir-v3/ Language: Rust

6.1 zkir v2

Crate: midnight-zkir v2.1.0 Binary: zkir Tag: "ir-source[v2]"

zkir <COMMAND>

Commands:
  mock-compile       Load a single IR file and print circuit size
  mock-compile-many  Load all IR files in a directory and print circuit sizes
  compile            Full key generation for a single circuit
  compile-many       Full key generation for all circuits in a directory

zkir mock-compile

zkir mock-compile [-v|--verbose] <ir_file>

Loads a .zkir (JSON) or .bzkir (binary) file, prints circuit size (k, rows). Does NOT produce keys.

zkir mock-compile-many

zkir mock-compile-many [-v|--verbose] <ir_dir>

Same as above for all .zkir/.bzkir files in a directory.

zkir compile

zkir compile [-v|--verbose] <ir_file> <prover_key> <verifier_key>

Full key generation. Outputs .prover and .verifier files (tagged-serialized).

zkir compile-many

zkir compile-many [-v|--verbose] <ir_dir> <key_dir>

Full key generation for all circuits in a directory. This is the command invoked by compactc.

File format handling:

  • .zkir input: parsed as JSON, binary .bzkir sidecar written
  • .bzkir input: deserialized directly (faster for repeated compilations)
  • .prover output: tagged-serialized prover key
  • .verifier output: tagged-serialized verifier key

6.2 zkir v3

Crate: midnight-zkir-v3 v3.0.0-rc.1 Binary: zkir (same name) Tag: "ir-source[v3]"

The CLI interface is identical to v2. Same four subcommands, same arguments.

Key differences from v2:

  • Named variables (%name) instead of positional indices
  • Typed values (IrType: "Scalar<BLS12-381>", "Point<Jubjub>")
  • New instructions: Encode, Decode, Impact
  • JSON format version: {"major": 3, "minor": 0}

6.3 How compactc Invokes zkir

From compiler/passes.ss:

;; Check if zkir is on PATH
(if (zero? (system "command -v zkir > /dev/null"))
  ;; If zkir/ directory exists (has circuits)
  (when (file-exists? (format "~a/zkir" output-directory-pathname))
    ;; Select binary based on feature flag
    (let ([res (system (format "exec ~a compile-many '~a/zkir' '~a/keys'"
                               (if (feature-zkir-v3) "zkir-v3" "zkir")
                               output-directory-pathname
                               output-directory-pathname))])
      (unless (zero? res)
        (external-errorf "zkir returned a non-zero exit status ~d" res))))
  ;; If zkir not found, warn once
  (unless (zkir-warning-issued)
    (zkir-warning-issued #t)
    (fprintf (console-error-port)
             "Warning: ZKIR not found; skipping final circuit compilation.\n")))

Details:

  • Detection: command -v zkir > /dev/null
  • v2 command: exec zkir compile-many '<output>/zkir' '<output>/keys'
  • v3 command: exec zkir-v3 compile-many '<output>/zkir' '<output>/keys'
  • Missing zkir: gracefully skips with one-time warning to stderr
  • Non-zero exit: raises external-errorf
  • Note: Path quoting uses single quotes only (no proper shell escaping)

The bundled distribution includes zkir in <compiler_dir>/lib/. The wrapper script (compactc.bin) prepends this to $PATH:

thisdir="$(cd $(dirname $0) ; pwd -P)"
PATH="$thisdir:$PATH"
exec "$thisdir/compactc.bin" "$@"

6.4 ZKIR IR v2 Data Model

IrSource struct (tag: "ir-source[v2]"):

{
  "version": { "major": 2, "minor": 0 },
  "do_communications_commitment": false,
  "num_inputs": 77,
  "instructions": [...]
}

Instructions (all op values):

Op Arguments Outputs Description
assert cond: Index 0 Assert condition is true
cond_select bit, a, b: Index 1 Conditional select (mux)
constrain_bits var: Index, bits: u32 0 Constrain to N bits
constrain_eq a, b: Index 0 Assert equality
constrain_to_boolean var: Index 0 Assert is 0 or 1
copy var: Index 1 Copy value
declare_pub_input var: Index 0 Declare public input
pi_skip guard: ?Index, count: u32 0 Skip public inputs
ec_add a_x, a_y, b_x, b_y: Index 2 Elliptic curve addition
ec_mul a_x, a_y, scalar: Index 2 Elliptic curve scalar multiplication
ec_mul_generator scalar: Index 2 Generator scalar multiplication
hash_to_curve inputs: [Index] 2 Hash to curve point
load_imm imm: Fr 1 Load immediate field element
div_mod_power_of_two var: Index, bits: u32 2 Divide and modulo by 2^bits
reconstitute_field divisor, modulus: Index, bits: u32 1 Reconstitute field element
output var: Index 0 Mark as output
transient_hash inputs: [Index] 1 Poseidon hash (transient)
persistent_hash alignment, inputs: [Index] 1 SHA-256 hash (persistent)
test_eq a, b: Index 1 Test equality (returns 0/1)
add a, b: Index 1 Field addition
mul a, b: Index 1 Field multiplication
neg a: Index 1 Field negation
not a: Index 1 Boolean not
less_than a, b: Index, bits: u32 1 Less-than comparison
public_input guard: ?Index 1 Read public input
private_input guard: ?Index 1 Read private input

6.5 ZKIR IR v3 Data Model

IrSource struct (tag: "ir-source[v3]"):

{
  "version": { "major": 3, "minor": 0 },
  "do_communications_commitment": false,
  "inputs": [{ "identifier": "%input0", "type": "Scalar<BLS12-381>" }],
  "instructions": [...]
}

New types:

  • "Scalar<BLS12-381>" — native field element
  • "Point<Jubjub>" — Jubjub curve point

New instructions (additions over v2):

  • Encode — encode typed value to raw Fr fields
  • Decode — decode raw Fr fields to typed value
  • Impact — declare multiple public inputs under a guard condition (replaces declare_pub_input + pi_skip)

Key differences: Named variables (%name), typed inputs, typed operations on curve points.

6.6 Public Parameters

Managed by MidnightDataProvider in base-crypto. Files named bls_midnight_2p{k} for k=0..25. Each is a BLS12-381 SRS for Halo2 PLONK circuits of size 2^k.

SHA-256 hashes for all 26 parameter files are hardcoded. Downloads verified against these hashes.

Source URL: $MIDNIGHT_PARAM_SOURCE (default: https://midnight-s3-fileshare-dev-eu-west-1.s3.eu-west-1.amazonaws.com/)

Local cache: $MIDNIGHT_PP or $XDG_CACHE_HOME/midnight/zk-params or $HOME/.cache/midnight/zk-params


7. The midnight-proof-server

Source: midnight-ledger/proof-server/ Version: 8.0.3 Framework: actix-web 4.x Default port: 6300

7.1 CLI Arguments

Flag Short Default Env Var Description
--port -p 6300 MIDNIGHT_PROOF_SERVER_PORT TCP port
--verbose -v false MIDNIGHT_PROOF_SERVER_VERBOSE Enable DEBUG logging
--job-capacity 0 MIDNIGHT_PROOF_SERVER_JOB_CAPACITY Max pending jobs (0=unlimited)
--num-workers 2 MIDNIGHT_PROOF_SERVER_NUM_WORKERS Proving worker threads
--job-timeout 600.0 MIDNIGHT_PROOF_SERVER_JOB_TIMEOUT Job timeout in seconds
--no-fetch-params false MIDNIGHT_PROOF_SERVER_NO_FETCH_PARAMS Skip fetching zswap keys on startup

7.2 Environment Variables

In addition to CLI flags:

Variable Purpose
MIDNIGHT_PP Local cache directory for ZK public parameters
MIDNIGHT_PARAM_SOURCE URL to fetch public parameters from
XDG_CACHE_HOME Fallback cache location
HOME Second fallback cache location
RUST_LOG Standard tracing log filter

7.3 HTTP API Endpoints

All endpoints on 0.0.0.0:{port}, fully CORS-permissive.

Method Path Description
GET / Health check -> {"status":"ok","timestamp":"..."}
GET /health Same as /
GET /version Returns CARGO_PKG_VERSION
GET /ready Job queue status: `{"status":"ok"
GET /proof-versions Supported proof version variants
GET /fetch-params/{k} Fetch BLS public params for k in 0-25 (unless --no-fetch-params)
POST /k Body: serialized IrSource. Returns circuit size k as text.
POST /check Body: serialized (ProofPreimage, Option<WrappedIr>). Returns Vec<Option<u64>> pi_skips.
POST /prove Body: serialized (ProofPreimage, Option<ProvingKeyMaterial>, Option<Fr>). Returns Proof.
POST /prove-tx Deprecated. Body: serialized transaction + key material. Returns proved transaction.

Startup behavior (without --no-fetch-params):

  1. Pre-fetches BLS public parameters for k=10 through k=15
  2. Pre-fetches key material for: midnight/zswap/spend, midnight/zswap/output, midnight/zswap/sign, midnight/dust/spend

Worker pool: N worker threads (default 2) via unbounded async channel. Job GC every 10 seconds. Jobs identified by UUID v4.


8. The onchain-runtime VM

Source: midnight-ledger/onchain-runtime/ Crate: midnight-onchain-runtime v3.0.0

Has a debug CLI (not production):

<binary> <STATE-IN> <PROGRAM> [<STATE-OUT>]
Positional Description
STATE-IN Serialized StateValue binary
PROGRAM Serialized Op operations
STATE-OUT Optional: serializes first stack result

Uses std::env::args() directly (no clap, no flags).


9. WASM Targets

zkir-wasm (v2.1.0)

Exported functions:

JS Function Description
prove(preimage, provider, overwrite?) Generate ZK proof from serialized PreofPreimage
check(preimage, provider) Validate proof preimage, returns pi_skips
provingProvider(kmProvider) Wrap JS key material provider
jsonIrToBinary(json) Convert JSON ZKIR to binary format
Zkir.fromJson(json) Parse JSON ZKIR
Zkir.deserialize(bytes) Parse binary ZKIR
Zkir.serialize() Serialize to binary
Zkir.getK() Get circuit k parameter

JS KeyMaterialProvider interface:

interface KeyMaterialProvider {
  getParams(k: number): Promise<Uint8Array>;
  lookupKey(location: string): Promise<{
    proverKey: Uint8Array;
    verifierKey: Uint8Array;
    ir: Uint8Array;
  } | null>;
}

zkir-v3-wasm (v3.0.0-rc.1)

Same API as zkir-wasm but uses zkir-v3 internally.

ledger-wasm (v8.0.3) & onchain-runtime-wasm (v3.0.0)

Wrap their respective crates for browser/WASM usage.


10. Runtime (@midnight-ntwrk/compact-runtime)

Package: @midnight-ntwrk/compact-runtime v0.15.101 Source: compact/runtime/

Key exports:

  • CompactType<A>, JubjubPoint, MerkleTreeDigest, MerkleTreePath<A>
  • addField, subField, mulField, transientHash, transientCommit, persistentHash, persistentCommit, degradeToTransient
  • ecAdd, ecMul, ecMulGenerator, hashToCurve
  • CompactError, MAX_FIELD
  • CircuitContext<PS>, CircuitResults, WitnessContext
  • ProofData, PartialProofData
  • emptyZswapLocalState, ZswapLocalState, encodeZswapLocalState
  • contractDependencies, SparseCompact* types

Re-exports from @midnight-ntwrk/onchain-runtime-v3: Value, ContractState, StateValue, StateMap, CostModel, Fr, runProgram, ContractOperation, token types, signing/verification functions, etc.


11. Editor Support

VS Code Extension

Package: compact (publisher: midnightnetwork) v0.2.11 Requires: VS Code ^1.100.0

Features:

  • Language ID: compact, extension .compact
  • TextMate grammar for syntax highlighting
  • Bracket matching, auto-closing pairs
  • Line comments //, block comments /* */
  • Problem matchers: compactException, compactInternal, compactCommandNotFound
  • Breakpoint support
  • Code snippets: pragma, ledger/state, constructor, circuit/function/transition, witness/private, enum, init/stdlib, if/cond, map/for, fold, module, struct, assert, compact (full template)
  • Command: extension.createCompactcProjectFromTemplate

Vim Support

  • ftdetect/compact.vim — detects .compact files, sets filetype=compact, disables spell check
  • syntax/ — syntax highlighting rules

12. Build System and Nix Configuration

Nix Flake Packages

Package Description
compactc Full compiler (Node.js + Chez)
compactc-no-runtime Compiler without runtime
compactc-binary-nixos Statically linked native binary
compactc-binary Distribution bundle: compactc.bin, format-compact, fixup-compact, lib/zkir, lib/zkir-v3
compactc-oci OCI container image (entrypoint: bash, cmd: compactc)
runtime @midnight-ntwrk/compact-runtime npm package
compact-vscode-extension Built .vsix file

Nix Dev Shells

Shell Purpose
default Full dev environment
with-zkir Includes zkir binaries + binaryen
compiler compactc + yarn + zkir
runtime Runtime development (Node.js + Chez)
dapp DApp development (compactc, runtime, zkir)

Build Details

The Chez Scheme programs are compiled with:

  • optimize-level 2
  • compile-imported-libraries #t
  • generate-wpo-files #t
  • generate-inspector-information #f
  • compile-profile #f

Final native binaries use compile-whole-program with .wpo (whole-program optimization) files.

Binary cache: IOG public cache at https://cache.iog.io


13. Test Infrastructure

Unit Tests (compiler/go)

Bash script runner for Chez Scheme unit tests:

./compiler/go             # recompile as needed, run tests
./compiler/go --rebuild   # force full recompile

Generates HTML coverage reports in coverage/.

End-to-End Tests (tests-e2e/)

Framework: Vitest (TypeScript) Runner: nix develop .#compiler --command yarn test

Tests cover: compiler features, formatter, fixup, extracted contracts, fuzzer-generated inputs, runtime compatibility.

Binary argument enum in tests:

  • SKIP_ZK = '--skip-zk'
  • FEATURE_V3 = '--feature-zkir-v3'
  • TRACE_PASSES = '--trace-passes'
  • HELP = '--help'
  • VERSION = '--version'
  • LANGUAGE_VERSION = '--language-version'
  • LEDGER_VERSION = '--ledger-version'
  • RUNTIME_VERSION = '--runtime-version'
  • VSCODE = '--vscode'
  • LINES_LENGTH = '--line-length'

Integration Tests (test-center/)

Framework: Vitest Tests full compiled contract pipeline including zkir WASM modules. Depends on @midnight-ntwrk/zkir-v2 and @midnight-ntwrk/zkir-v3.

Debug Tests (debug-test/)

Tests contract debugging functionality:

./run-debug-test.sh  # builds runtime, compiles test contract, runs debug tests

Source Map Tests (test-src-maps/)

Tests VLQ encoding and source map generation.

Compact CLI Tests (tools/compact/tests/)

Integration tests for the Rust CLI tool. Key test constants:

  • COMPACT_VERSION = "0.5.1"
  • PREVIOUS_COMPACT_VERSION = "0.5.0"
  • LATEST_COMPACTC_VERSION = "0.30.0"
  • PREVIOUS_COMPACTC_VERSION = "0.29.0"
  • OLDEST_COMPACTC_VERSION = "0.22.0"
  • VERSION_WITH_NO_FORMAT = "0.24.0" (last version without format-compact)

14. Utility Scripts

Script Purpose
clean.sh Remove obj/, coverage/, result/ build artifacts
run-e2e-tests.sh Run e2e tests in Nix compiler dev shell
run-debug-test.sh Build runtime, compile test contract, run debug tests
srcMaps/test.sh Run VLQ/source-map unit tests
compiler/export-keywords.ss Export Compact keywords to JSON for VS Code extension
compiler/update-test.ss Update test expectation files
compiler/go Unit test runner with coverage
add_headers.py Add SPDX license headers
midnight-ledger/scripts/check-licenses.sh Verify SPDX headers in all source files
midnight-ledger/scripts/upload-keys-s3.sh Upload compiled ZK keys to AWS S3
midnight-ledger/scripts/hardfork_version_patch/ Bump #[tag = "name[vN]"] version annotations during hard forks
midnight-ledger/run_it.sh Run TypeScript integration tests

15. All URLs Used by the Toolchain

URL Used By Purpose
https://api.github.com/repos/midnightntwrk/compact/releases compact CLI Discover available compactc versions
https://github.com/midnightntwrk/compact/releases/download/compactc-v{V}/{asset}.zip compact CLI Download compactc artifact
https://github.com/midnightntwrk/compact/releases/download/compact-v{V}/compact-installer.sh axoupdater Self-update installer
GitHub releases API for compact (not compactc) axoupdater compact self check/self update
https://midnight-s3-fileshare-dev-eu-west-1.s3.eu-west-1.amazonaws.com/ MidnightDataProvider Default public parameters download source
S3 bucket paths: zswap/{version}/*.{prover,verifier,bzkir} upload-keys-s3.sh Upload compiled ZK keys
S3 bucket paths: dust/{version}/*.{prover,verifier,bzkir} upload-keys-s3.sh Upload compiled ZK keys
https://cache.iog.io Nix binary cache Pre-built Nix packages

16. Complete Environment Variable Index

Variable Binary Purpose
COMPACT_DIRECTORY compact Override ~/.compact artifact directory
COMPACT_PATH compactc, format-compact, fixup-compact Module/include search path
GITHUB_TOKEN compact GitHub API authentication
HOME all Home directory
MIDNIGHT_PP zkir, proof-server ZK public parameters cache directory
MIDNIGHT_PARAM_SOURCE zkir, proof-server Public parameters download URL
MIDNIGHT_PROOF_SERVER_PORT proof-server TCP port (default 6300)
MIDNIGHT_PROOF_SERVER_VERBOSE proof-server Enable DEBUG logging
MIDNIGHT_PROOF_SERVER_JOB_CAPACITY proof-server Max pending jobs
MIDNIGHT_PROOF_SERVER_NUM_WORKERS proof-server Proving worker threads
MIDNIGHT_PROOF_SERVER_JOB_TIMEOUT proof-server Job timeout seconds
MIDNIGHT_PROOF_SERVER_NO_FETCH_PARAMS proof-server Skip startup key fetch
RECEIPT_HOME compact (axoupdater) Self-update receipt directory
RUST_LOG zkir, proof-server Log level filter
XDG_CACHE_HOME compact, zkir, proof-server Cache directory override
XDG_CONFIG_HOME compact (axoupdater) Config directory override

17. Version Matrix

Component Version Source
compact CLI 0.5.1 Cargo.toml workspace
compactc compiler 0.30.104 compiler-version.ss
Compact language 0.22.101 language-version.ss
Compact runtime 0.15.101 runtime/package.json
Ledger (zkir-v2) ledger-8.0.2 flake.nix
Ledger (zkir-v3) ambrona@zkirv3-typed-inputs flake.nix
midnight-zkir (v2) 2.1.0 Cargo.toml
midnight-zkir-v3 3.0.0-rc.1 Cargo.toml
midnight-ledger 8.0.3 Cargo.toml workspace
midnight-onchain-runtime 3.0.0 Cargo.toml
midnight-proof-server 8.0.3 Cargo.toml
VS Code extension 0.2.11 package.json
Min Rust version 1.88.0 Cargo.toml workspace
Chez Scheme latest flake.nix
Node.js >=18 flake.nix
BLS12-381 field prime - 1 52435875...84512 field.ss

Appendix A: Language Keywords

Value literals: false, true

Module: export, from, import, module, prefix

Statements/expressions: as, assert, circuit, const, constructor, contract, default, disclose, else, enum, fold, for, if, include, ledger, map, new, of, pad, pragma, pure, return, sealed, slice, struct, type, witness

Built-in types: Boolean, Bytes, Field, Opaque, Uint, Vector

Reserved (future use, cannot be identifiers): await, break, case, catch, class, continue, debugger, delete, do, extends, finally, function, implements, in, instanceof, interface, let, null, package, private, protected, public, static, super, switch, this, throw, try, typeof, var, void

Appendix B: Pre-compiled Circuit Library

The zkir-precompiles/ directory contains pre-compiled ZKIR v2 circuits for built-in Midnight contracts:

Contract Circuits
composable-burn burn
composable-inner get, set
composable-outer update
composable-relay send_to_burn
dust spend
fallible count
micro-dao advance, buyIn, cashOut, setTopic, voteCommit, voteReveal
simple-merkle-tree check, store
token-vault depositShielded, depositUnshielded, getShieldedBalance, getUnshieldedBalance, withdrawShielded, withdrawUnshielded
zswap output, sign, spend

Appendix C: Key Material Resolution Chain

String-based key locations: "midnight/{domain}/{circuit}"

Location Resolver File Path
midnight/zswap/spend ZswapResolver zswap/{version}/spend.{prover,verifier,bzkir}
midnight/zswap/output ZswapResolver zswap/{version}/output.{prover,verifier,bzkir}
midnight/zswap/sign ZswapResolver zswap/{version}/sign.{prover,verifier,bzkir}
midnight/dust/spend DustResolver dust/{version}/spend.{prover,verifier,bzkir}
midnight/{contract}/{circuit} External Supplied by caller

Static version: "9" (from midnight-ledger/static/version)

Appendix D: Console Output Styling

The compact CLI uses styled console output:

  • Label: "compact" (magenta, bold)
  • Version numbers: cyan, bold
  • Target strings: white, bold
  • Success: green, bold
  • Warning: yellow
  • Error: red
  • Current version indicator: -> (cyan, dim)
  • Progress bar: [elapsed] [bar:40.cyan/blue] bytes/total (speed, eta)
  • Spinner: " ▏▎▍▌▋▊▉█"

Appendix E: Circuit Name Case Sensitivity Warning

From passes.ss: If two exported circuits have names differing only in case (e.g., Foo and foo), the compiler raises an error to avoid filename clashes on case-insensitive filesystems (macOS, Windows):

the exported impure circuit name <X> is identical to the exported circuit name <Y>
at <location> modulo case; please rename to avoid zkir and prover-key filename
clashes on case-insensitive filesystems
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment