Skip to main content

Midnight.js v5.0.0 release notes

For the complete documentation index, see llms.txt
  • Version: v5.0.0
  • Date: 2026-11-06
  • Environment: Mainnet, Preview
  • Node.js requirement: 22.12 or later

High-level summary​

Midnight.js 5.0.0 is the major release for the ledger 9 network upgrade. After the upgrade, Mainnet accepts only ledger 9 transactions, so a DApp on Mainnet needs Midnight.js 5, wallet SDK 2.0.0, and indexer 4.4.101.

Midnight.js 5 works across both ledger eras, so a DApp can run the same code before and after the upgrade. A contract deployed before the upgrade keeps its existing build and runs as a ledger 8 contract. Preview was reset on 6 November 2026 as a new chain that runs ledger 9, so a DApp on Preview also needs Midnight.js 5. Preprod stays on ledger 8 until a later upgrade. For Preprod, keep using Midnight.js 4.1.1.

The release also makes the packages ESM-only, replaces the global network ID with a config object on the providers, checks ZK artifacts before use, and gives every error a stable code.

Audience​

This release note is relevant for developers who:

  • Run a DApp on Mainnet or Preview
  • Call contracts deployed on Mainnet before the ledger 9 network upgrade
  • Use contract-to-contract calls or contract events
  • Write their own providers

Requirements​

Item4.1.15.0.0
Node.js22 or later22.12 or later
Module formatCommonJS and ESMESM only
Indexer4.3.x4.4.101 on Mainnet and Preview
Proof server8.1.x9.0.0
Compact toolchain for new contracts0.31.x0.36.0 (Compact runtime 0.21.0)
Compact.js2.5.x3.0.0
Ledger package@midnight-ntwrk/ledger-v8@midnightntwrk/ledger-v9 1.0.0, with @midnightntwrk/ledger-v8 8.1.3 for contracts deployed before the upgrade
On-chain runtime@midnight-ntwrk/onchain-runtime-v3@midnightntwrk/onchain-runtime-v4 4.0.0
Wallet SDK1.x@midnightntwrk/wallet-sdk 2.0.0

The framework packages stay under @midnight-ntwrk/midnight-js-*. The ledger, on-chain runtime, wallet SDK, and DApp Connector API packages that Midnight.js depends on now publish under @midnightntwrk.

Summary of updates​

  • Deploys, finds, calls, and maintains contracts of both ledger eras through the same functions. When the upgrade happens in the middle of an operation, it throws ForkCrossedDuringOperationError with what to do next.
  • Refuses a ledger 8 transaction on a ledger 9 network before it submits, with EraMismatchError.
  • Adds contract-to-contract calls.
  • Adds contract events: queryContractEvents, contractEventsObservable, and getAllContractEvents on the indexer provider.
  • Adds predefined network endpoints: networks.preview(), networks.preprod(projectId), networks.mainnet(projectId), and dappConnectorNetwork(api) for a browser DApp.
  • Builds wallet and Midnight providers from the DApp Connector with dappConnectorWalletProviders(connectedAPI).
  • Adds bounded waits: the watchFor* methods take { maxWaitMs }.
  • Gives every error a code and a category, with helpers such as hasErrorCode and findCodedCause.
  • Adds ZK artifact checking modes: verify: 'require' | 'require-if-present' | 'warn' | 'off'.
  • Fixes indexer subscriptions that stalled silently on a lost frame. They now send keep-alives, reconnect, and end with an error after repeated failures.

Breaking changes​

For the full list, with before and after code, see the Midnight.js breaking changes and the migration guide.

Ledger 9 is the current ledger​

Contracts deployed after the upgrade are compiled with Compact toolchain 0.36.0. The protocol subpaths name their ledger: /ledger is now /v9, /compact-runtime is /v9/compact-runtime, /compact-js* is /v9/compact-js*, and /onchain-runtime is /v9/onchain-runtime. Import Transaction from @midnight-ntwrk/midnight-js-protocol/v9.

ESM-only packages​

The midnight-js-* packages publish as ESM only. A require() of one needs Node.js 22.12 or later, and TypeScript node16 or node18 module settings fail with TS1479.

Required providers.config​

Pass config: { networkId, ttlSeconds } on your provider set. setNetworkId() and the @midnight-ntwrk/midnight-js-network-id package are removed. Import NetworkId from @midnight-ntwrk/midnight-js-types.

ZK artifacts ship their compiler/ directory​

The ZK config providers check every artifact against compiler/contract-manifest.json and refuse a mismatch by default. Every contract operation also reads the artifacts' runtime version to pick the ledger. FetchZkConfigProvider takes an options object as its second argument: new FetchZkConfigProvider(url, { fetchFunc }).

Transactions and on-chain state carry their ledger era​

  • proveTx, balanceTx, and submitTx take and return transaction handles (UnprovenTx, UnboundTx, FinalizedTx) that hold the bytes and the era.
  • State reads return records whose states are serialized. Decode them with your own runtime, for example read.contractState.deserialize({ v9: ContractState }).
  • watchForTxData, watchForDeployTxData, and submitTx return era-tagged records. Check record.era before you read the rest.
  • contractStateObservable and unshieldedBalancesObservable emit { value, blockHeight, blockHash }.

Providers declare their eras​

ProofProvider, WalletProvider, and MidnightProvider declare supportedEras. Build ledger 9 providers with createLedger9ProofProvider (was createProofProvider), createLedger9WalletProvider, and createLedger9MidnightProvider. A custom PublicDataProvider needs four new members: queryBlock, queryLatestProtocolVersion, queryContractEvents, and contractEventsObservable.

Private state is reached per contract​

provider.forContract(address) returns the view with get, set, remove, clear, export, and import. setContractAddress is removed.

If you rotated a private state password on 4.x, run changePassword again after upgrading. In 4.x it could report success without re-encrypting every contract.

Exports named after their ledger​

Names that apply only to ledger 9 carry Ledger9. For example, CallTxOptions is Ledger9CallTxOptions in generic code, and TransactionContext is Ledger9TransactionContext. Names without a prefix pick the era from the contract type. A contract-scoped transaction before the upgrade uses Ledger8TransactionContext or withLedger8ContractScopedTransaction.

One error model​

Every framework error extends MidnightJsError. The five *TxFailedError classes are now one TxFailedError with an operation. A rejection from the proof server, wallet, or node arrives wrapped in ProviderFailedError. ContractTypeError is no longer a TypeError.

Contract action subscriptions start at their offset​

On indexer 4.4.101, a contract action subscription opened without an offset delivers only new actions. Midnight.js 5.0.0 passes an explicit offset, so it still replays a contract's history. Midnight.js 4.x does not pass an offset and receives no history.

Contracts deployed before the upgrade​

A contract deployed before the upgrade keeps working through its ledger 8 artifacts, built with Compact toolchain 0.31.x (Compact runtime 0.16). Configure your ZK config provider with verify: 'require-if-present' for these artifacts, because 0.31.x output has no contract manifest.

Midnight.js 5 accepts artifacts built for Compact runtime 0.16 or 0.21 only. It refuses artifacts from any other runtime version, including Compact toolchain 0.30.0 and 0.35.0, with EraMismatchError (reason unknown-artifact-runtime-version).

If you recompile a contract that an earlier toolchain built, its verifier keys change even when the source hasn't. The new artifacts don't match the deployed contract, so findDeployedContract refuses it with ContractTypeError. To keep calling the contract, keep its deployed artifacts. To move it to Compact toolchain 0.36.0, its maintenance authority inserts the new verifier keys with a maintenance update first. For how recompiling changes verifier keys, see the ledger 9 upgrade page.

This section applies to Mainnet. Preview keeps no contracts from before the reset, so redeploy your contracts there, compiled with Compact toolchain 0.36.0.

Known issues​

  • Proof server 9.0.0 is required. Release candidate 9.0.0-rc.7 can't prove circuits compiled by Compact toolchain 0.36.0 and returns 400 Bad Request.
  • ZKIR version 3 prover keys are larger than version 2 keys, so expect larger artifact downloads.
  • For network known issues that affect DApps after the upgrade, see the ledger 9 upgrade page.