npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@effectstream/midnight-contracts

v0.101.1

Published

Midnight network contract interfaces for EffectStream

Downloads

687

Readme

@effectstream/midnight-contracts

Utilities for reading and deploying Midnight contracts from inside an Effectstream node or test. Two functions: readMidnightContract to load contract metadata + ABI by name, and deployMidnightContract to deploy and persist the resulting address.

  • Reads contract files by name, searching from the current working directory upward.
  • Supports per-network files (contract-counter.undeployed.json, contract-counter.testnet.json) without hardcoded paths.
  • Deploys against the local Midnight stack by default; pass NetworkUrls to point at another environment.
  • Persists the deployed address to a JSON file so subsequent reads pick it up automatically.

Install

bun add @effectstream/midnight-contracts
# or
npm install @effectstream/midnight-contracts

Requires a reachable Midnight node, proof server, and indexer. The defaults match what @effectstream/orchestrator's Midnight step boots locally.

Standalone usage

Read a contract

import { readMidnightContract } from "@effectstream/midnight-contracts/read-contract";

// Defaults to contract-counter.<networkId>.json, where networkId is "undeployed".
const local = readMidnightContract("contract-counter");

// Read the same contract on a different network.
const preview = readMidnightContract("contract-counter", { networkId: "preview" });

// Override the search base if your contracts live outside the CWD tree.
const custom = readMidnightContract("contract-counter", {
  baseDir: "/path/to/contracts",
  networkId: "undeployed",
});

Returns { contractAddress, contractInfo, zkConfigPath }. Results are cached per (location, name, filename) tuple so repeated reads in the same process are free.

Deploy a contract

Only contractName and contractClass are required — everything else has a sensible default, so a minimal deploy is just:

import {
  deployMidnightContract,
  type DeployConfig,
  type NetworkUrls,
} from "@effectstream/midnight-contracts/deploy";

// contractName must match the directory that holds `src/managed`;
// contractClass is the compiled Contract (e.g. `export * as Counter from "./managed/contract"`).
const address = await deployMidnightContract({
  contractName: "contract-counter",
  contractClass: Counter.Contract,
});

Supply the rest only when your contract needs it:

const config: DeployConfig = {
  contractName: "contract-counter",
  contractClass: Counter.Contract,
  witnesses,                              // default: {} (no witnesses)
  privateStateId: "counterPrivateState",  // default: "privateState"
  initialPrivateState: { privateCounter: 0 }, // default: {} (no private state)
  contractFileName: "contract-counter.json",  // default: `${contractName}.json`
};

const address = await deployMidnightContract(config);

To deploy against a non-default stack, pass NetworkUrls:

const network: NetworkUrls = {
  indexer: "http://localhost:8088/api/v3/graphql",
  indexerWS: "ws://localhost:8088/api/v3/graphql/ws",
  node: "http://localhost:9944",
  proofServer: "http://localhost:6300",
};

const address = await deployMidnightContract(config, network);

The deploy helper creates and funds a wallet from the genesis mint seed, runs the deployment, and writes the resulting address to ${contractName}.${networkId}.json so the next readMidnightContract call picks it up.

Contracts with many circuits (phased deployment)

A standard deploy carries every circuit's verifier key in a single transaction. For contracts with enough circuits, that transaction exceeds the node's per-block limits and fails with Transaction would exhaust block limits. Set phasedVerifierKeys: true to instead deploy the contract with no verifier keys and then insert each circuit's key in its own transaction:

const address = await deployMidnightContract({
  ...config,
  phasedVerifierKeys: true, // opt-in; default is a single-transaction deploy
});

Phased mode writes progress to a resume-state file (deployment-state.json by default) and removes it on success, so an interrupted run can be re-run to continue from the last inserted circuit instead of redeploying. Tunables:

  • phasedVerifierKeys?: boolean — enable phased deployment (default false).
  • vkInsertRetries?: number — per-circuit retry count for key insertion (default 3).
  • phasedStateFile?: string — resume-state file path (default deployment-state.json in the CWD).

The circuit list is enumerated automatically from the contract's compiled keys/ directory, so no per-contract configuration is required.

Inside Effectstream

@effectstream/midnight-contracts is the seam between Midnight contract artifacts on disk and the code that reads or deploys them. Templates that target Midnight call readMidnightContract from their node startup to resolve the on-chain address; the orchestrator's deploy step calls deployMidnightContract to put one there in the first place. On the sync side, @effectstream/sync's MidnightFetcher consumes the node behind both calls.

Key exports

@effectstream/midnight-contracts/read-contract:

  • readMidnightContract(name, options?): returns { contractAddress, contractInfo, zkConfigPath }. options.networkId selects per-network files; options.baseDir overrides the search base.

@effectstream/midnight-contracts/deploy:

  • deployMidnightContract(config, networkUrls?): deploys and returns the address. Persists the address to a JSON file. Set config.phasedVerifierKeys for contracts whose circuits don't fit in a single deploy transaction.
  • deployMidnightContractPhased(...): the phased deploy routine deployMidnightContract delegates to when phasedVerifierKeys is set. Exported for advanced callers that already have built providers and a wallet.
  • DeployConfig, NetworkUrls: input types.

Examples

End-to-end usage in templates:

Links

  • Docs: https://effectstream.github.io/docs/packages/chains/midnight-contracts
  • Source: https://github.com/effectstream/effectstream/tree/main/packages/chains/midnight-contracts
  • Midnight: https://midnight.network