For the complete documentation index, see llms.txt
Compact toolchain 0.36.0
- Date: 2026-11-02
- Language version: 0.28.0
- Compact runtime version: 0.21.0
- Environment: This release works with a Midnight ledger 9 blockchain. For the full compatibility matrix, see the release notes overview
High-level summary
Version 0.36.0 of the Compact toolchain is a major release. It builds on 0.35.0.
The compiler now generates only ZKIR version 3, and the --feature-zkir-v3 flag is gone, so the features introduced in 0.35.0 behind that flag are available without it. Circuits declared in a contract type can no longer be pure, which changes both the language and the Compact runtime's cross-contract API. The release also fixes a number of compiler internal errors and Compact runtime defects. Several changes are breaking; the entries below mark them.
You can update to version 0.36.0 using the Compact devtools. compact update will update to the latest released version, and compact update 0.36 will specifically update to the latest patch release of toolchain 0.36.
Audience
These release notes are intended for Compact smart-contract developers and for DApp developers who use the Compact runtime.
What changed
New features
ZKIR version 3 is the default and only backend
The compiler now always generates ZKIR version 3. The ZKIR version 2 backend is removed. As a result, the features added in toolchain 0.35.0 that required --feature-zkir-v3 are available without a flag: sha512, the secp256r1 (P256) and Curve25519 curves and fields, secp256r1EcdsaVerify, and ed25519Verify.
Passing --feature-zkir-v3 is now an error; see Breaking changes.
Improvements
The zkir-v3 binary is updated
The zkir-v3 binary shipped with the compiler now comes from midnight-zkir zkir-3.2.0-rc.2. The compiler continues to generate ZKIR 3.1.
assert produces the value []
In generated JavaScript, a successful assert now produces the value [], as the language reference specifies. Previously, wherever the value of an assert was used, such as return assert(...) or [assert(...), x], it produced undefined.
serialize and deserialize support type aliases
The built-in serialize and deserialize circuits now work for values whose types are or contain structural or nominal type aliases. They raise a not-yet-implemented exception for values whose types are or contain Secp256k1Point, Secp256r1Point, or Curve25519Point.
Identity points have a single encoding
The Compact runtime now encodes every Secp256k1Point and Secp256r1Point identity point the same way, with both coordinates 0, whatever coordinates the JavaScript value carries.
Breaking changes
The --feature-zkir-v3 flag is removed
Passing --feature-zkir-v3 to the compiler is now an error. Remove the flag from your build scripts. --ledger-version now always prints the version of the zkir-v3 dependency.
Circuits in a contract type cannot be pure
A cross-contract call is matched by the ledger against the called circuit's proof, so every circuit declared in a contract type must have a proof. Marking a circuit declaration in a contract type pure is now a compile-time error, since a pure circuit has no proof. A contract implements declaration is likewise rejected when the implementing circuit is declared pure.
The arguments of every cross-contract call must now be disclosed. The exemption for calls to circuits declared pure is gone with those declarations.
Purity is removed from the Compact runtime's cross-contract API
Conformance of a resolved module now checks that every declared circuit is implemented by a provable circuit (the Provability check), and nothing about purity.
- The
PureInterfaceCircuitfailure kind and thePurityconformance check are removed. - The
purefield ofInterfaceCircuitDeclarationis removed. - The never-read
pureCircuitsfield ofModuleis removed, together with thePureCircuitandPureCircuitstypes. CircuitSignaturekeeps itspurefield, for information only.
The compiler no longer emits pure for the circuits of a contract type in declaredInterfaces or in contract-info.json.
Contracts that make cross-contract calls must be recompiled
A cross-contract call's proof now binds the callee circuit named at the call site: the compiler emits the entry-point hash as a constant of the call site. Contracts that make cross-contract calls must be recompiled to get this fix.
Casting a non-native field to Boolean is a type error
Casting any field type other than Field to Boolean is now always a type error. These casts used to be accepted in pure circuits, and failed when compiled to a ZK circuit.
Links and references
Fixed defect list
The following defects are fixed by updating to Compact toolchain 0.36.
- The compiler failed with an internal error on a cast to a foreign field type (
Secp256k1Base,Secp256k1Scalar,Secp256r1Base,Secp256r1Scalar,Curve25519Base, orCurve25519Scalar) when the cast is a constant, such as(1 as Bytes<32>) as Secp256k1Base, or when its result is never used, such as a struct field that is never read (#891). This is fixed. - The compiler failed with an internal error when a circuit subtracts a foreign field value from itself, such as
k - kfor aSecp256k1Scalark, including when the two operands become the same only after inlining (#866). This is fixed. - The compiler failed with an internal error for
*or+on operands of a nominalUinttype whose result range equals the type's own range, such asx * ywherexandyhave typeBitdeclared bynew type Bit = Uint<1>(#881). This is fixed. - Casting
Secp256k1Base,Secp256k1Scalar,Secp256r1Base,Secp256r1Scalar,Curve25519Base, orCurve25519Scalarto aUinttype failed with an internal error (#880). It is now reported as a type error. - Casting any field type other than
Field, includingJubjubScalar, to an enum type failed with an internal error. It is now reported as a type error. - An exported circuit whose only public effect is a cross-contract call on an address that is not read from the ledger (for example, an argument) got no ZKIR or verifier key, so the circuit could not be submitted or called. This is fixed.
- A program that declares a contract type had to import
CompactStandardLibraryfor its cross-contract calls to compile. This is fixed. - The compiler failed with an internal error when a circuit needed a default value of type
Curve25519Base,Curve25519Scalar, orCurve25519Point, such as innone<Curve25519Point>()or the unused side of anEither(#868). This is fixed. - When the witness-protect pass encountered a tuple used as an array, it used the first tuple element as a representative for all of the array's elements, which could give the wrong result when the elements differ (#847). This is fixed.
- The Compact runtime's conformance check for dynamically resolved contract calls did not recognize
Secp256r1Base,Secp256r1Scalar,Secp256r1Point,Curve25519Base,Curve25519Scalar, orCurve25519Point. A call to a contract type that declares a circuit with one of these types in its signature failed to resolve. This is fixed. - A circuit that returns a conditional expression whose else branch is
[], such asreturn b ? f() : [];, returnedundefinedfrom the generated JavaScript when the condition was false. It now returns[]. - The compiler failed with an internal error on a conditional expression with an
assertin one branch and a[]literal in the other, such asb ? assert(...) : []. This is fixed.