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

@no-witness-labs/midday-sdk

v0.6.4

Published

Developer-friendly SDK for building dapps on Midnight Network

Readme

midday-sdk

Developer-friendly SDK for building dapps on Midnight Network. This project integrates with the Midnight Network.

Installation

pnpm add @no-witness-labs/midday-sdk

Quick Start

Promise API

import * as Midday from '@no-witness-labs/midday-sdk';
import * as CounterContract from './contracts/counter/contract/index.js';

// Create client
const client = await Midday.Client.create({
  seed: 'your-64-char-hex-seed',
  networkConfig: Midday.Config.NETWORKS.local,
  privateStateProvider: Midday.PrivateState.inMemoryPrivateStateProvider(),
});

// Load and deploy a contract (deploy returns a DeployedContract handle)
const loaded = await client.loadContract({
  module: CounterContract,
  zkConfig: Midday.ZkConfig.fromPath('./contracts/counter'),
  privateStateId: 'my-counter',
});
const deployed = await loaded.deploy();
console.log(`Deployed at: ${deployed.address}`);

// Call contract actions (typed)
await deployed.actions.increment();

// Or untyped fallback
await deployed.call('increment');

// Read state
const state = await deployed.ledgerState();
console.log(state.counter);

Effect API

import * as Midday from '@no-witness-labs/midday-sdk';
import * as CounterContract from './contracts/counter/contract/index.js';
import { Effect } from 'effect';

const program = Effect.gen(function* () {
  const client = yield* Midday.Client.effect.create({
    seed: 'your-64-char-hex-seed',
    networkConfig: Midday.Config.NETWORKS.local,
    privateStateProvider: Midday.PrivateState.inMemoryPrivateStateProvider(),
  });

  const loaded = yield* client.effect.loadContract({
    module: CounterContract,
    zkConfig: Midday.ZkConfig.fromPath('./contracts/counter'),
    privateStateId: 'my-counter',
  });
  const deployed = yield* loaded.effect.deploy();
  yield* deployed.effect.actions.increment();
  const state = yield* deployed.effect.ledgerState();

  return state;
});

const result = await Midday.Runtime.runEffectPromise(program);

Effect DI (Dependency Injection)

import * as Midday from '@no-witness-labs/midday-sdk';
import { Cluster, ClusterService } from '@no-witness-labs/midday-sdk/devnet';
import { Effect, Layer } from 'effect';

// Layer composition — all lifecycle is automatic
const ClusterLayer = Cluster.managedLayer({ clusterName: 'my-app' });

const ClientFromCluster = Layer.scoped(
  Midday.Client.MiddayClientService,
  Effect.gen(function* () {
    const cluster = yield* ClusterService;
    return yield* Midday.Client.effect.createScoped({
      seed: 'your-64-char-hex-seed',
      networkConfig: cluster.networkConfig,
      privateStateProvider: Midday.PrivateState.inMemoryPrivateStateProvider(),
    });
  }),
);

const AppLayer = ClientFromCluster.pipe(Layer.provide(ClusterLayer));

const program = Effect.gen(function* () {
  const client = yield* Midday.Client.MiddayClientService;
  const loaded = yield* client.effect.loadContract({ module: CounterContract });
  const deployed = yield* loaded.effect.deploy();
  yield* deployed.effect.actions.increment();
  return yield* deployed.effect.ledgerState();
});

// Zero lifecycle code — cleanup is automatic (LIFO: client closes → cluster removes)
const result = await Effect.runPromise(program.pipe(Effect.provide(AppLayer)));

For simpler cases without devnet management, use Client.layer() directly:

const ClientLayer = Midday.Client.layer({
  seed: 'your-64-char-hex-seed',
  networkConfig: Midday.Config.NETWORKS.local,
  privateStateProvider: Midday.PrivateState.inMemoryPrivateStateProvider(),
});

const result = await Effect.runPromise(program.pipe(Effect.provide(ClientLayer)));

Browser Usage (Lace Wallet)

import * as Midday from '@no-witness-labs/midday-sdk';

// Connect to Lace wallet
const wallet = await Midday.Wallet.fromBrowser('preview');

// Create client with connected wallet
const client = await Midday.Client.create({
  wallet,
  privateStateProvider: Midday.PrivateState.indexedDBPrivateStateProvider({
    privateStateStoreName: 'my-app',
  }),
});

// Load and deploy contract (zkConfig goes in loadContract, not in client)
const loaded = await client.loadContract({
  module: CounterContract,
  zkConfig: new Midday.ZkConfig.HttpZkConfigProvider('https://cdn.example.com/zk'),
  privateStateId: 'my-counter',
});
const deployed = await loaded.deploy();
await deployed.actions.increment();

Wallet Factories

// From seed (Node.js) — positional args
const wallet = await Midday.Wallet.fromSeed(seed, networkConfig);
const balance = await wallet.getBalance();

// From browser (Lace extension)
const wallet = await Midday.Wallet.fromBrowser('preview');
const balance = await wallet.getBalance();

// Read-only (address only, no signing)
const wallet = Midday.Wallet.fromAddress('0x...');
console.log(wallet.address);

Read-Only Client

// No wallet, seed, or proof server required
const reader = Midday.Client.createReadonly({
  networkConfig: Midday.Config.NETWORKS.preview,
});

const counter = reader.loadContract({ module: CounterContract });
const state = await counter.readState(contractAddress);
console.log(state.counter); // 42n

Configuration

Network Configuration

// Local network
const client = await Midday.Client.create({
  networkConfig: Midday.Config.NETWORKS.local,
  // ...
});

// Preview network
const client = await Midday.Client.create({
  networkConfig: Midday.Config.NETWORKS.preview,
  seed: 'your-64-char-hex-seed',
  // ...
});

// Custom network
const client = await Midday.Client.create({
  networkConfig: {
    networkId: 'testnet',
    indexer: 'https://indexer.testnet.midnight.network/graphql',
    indexerWS: 'wss://indexer.testnet.midnight.network/graphql/ws',
    node: 'wss://node.testnet.midnight.network',
    proofServer: 'https://proof.testnet.midnight.network',
  },
  seed: 'your-64-char-hex-seed',
  // ...
});

Contract Operations

Deploy a New Contract

const loaded = await client.loadContract({ module, zkConfig, privateStateId: 'my-id' });
const deployed = await loaded.deploy();
console.log(`Deployed at: ${deployed.address}`);

// With timeout
const deployed = await loaded.deploy({ timeout: 60_000 });

Join an Existing Contract

const loaded = await client.loadContract({ module, zkConfig, privateStateId: 'my-id' });
const deployed = await loaded.join(contractAddress);

// With timeout
const deployed = await loaded.join(contractAddress, { timeout: 60_000 });

With Witnesses

const loaded = await client.loadContract({
  module,
  zkConfig,
  privateStateId: 'my-id',
  witnesses: {
    my_witness_function: myImplementation,
  },
});
const deployed = await loaded.deploy();

Call Actions

// Typed — preferred
await deployed.actions.increment();
await deployed.actions.transfer(receiverAddress, 100n);

// Untyped fallback
const result = await deployed.call('increment');
console.log(`TX Hash: ${result.txHash}`);
console.log(`Block: ${result.blockHeight}`);

Read State

// Parsed state via ledger
const state = await deployed.ledgerState();

// State at specific block
const historicalState = await deployed.ledgerStateAt(blockHeight);

// Raw state
const raw = await deployed.getState();

Watch State Changes

// Callback style
const unsub = deployed.onStateChange((state) => {
  console.log('Counter:', state.counter);
});
// later: unsub();

// Async iterator
for await (const state of deployed.watchState()) {
  console.log('Counter:', state.counter);
  if (state.counter > 10n) break;
}

// Effect Stream
const stream = deployed.effect.watchState();

Transaction Lifecycle

// Wait for a transaction with timeout
await client.waitForTx(txHash, { timeout: 30_000 });

// Deploy and join support timeout
const deployed = await loaded.deploy({ timeout: 60_000 });

API Reference

Namespaces

  • Midday.Client — Client creation, contract loading, read-only client, fee relay
  • Midday.Contract — Contract types (LoadedContract, DeployedContract, ReadonlyContract)
  • Midday.Config — Network configuration presets and constants
  • Midday.Wallet — Wallet factories (fromSeed, fromBrowser, fromAddress)
  • Midday.PrivateState — Private state providers (in-memory, IndexedDB)
  • Midday.ZkConfig — ZK configuration providers (fromPath, HttpZkConfigProvider)
  • Midday.Hash — Cryptographic hash utilities
  • Midday.Runtime — Effect runtime utilities (runEffectPromise, runEffectWithLogging)
  • Midday.Utils — Hex encoding, address formatting, coin utilities

Services (Effect DI)

| Service | Layer | Description | |---------|-------|-------------| | Client.MiddayClientService | Client.layer(config) | Pre-initialized client (scoped — auto-closes) | | Client.ClientService | Client.ClientLive | Client factory | | ClusterService | Cluster.managedLayer(config?) | Managed devnet cluster (auto-starts/removes) |

Key Types

import type {
  // Client
  ClientConfig,
  MiddayClient,
  ReadonlyClient,
  ReadonlyClientConfig,
  WaitForTxOptions,

  // Contract
  LoadedContract,
  DeployedContract,
  ReadonlyContract,
  DeployOptions,
  JoinOptions,
  CallResult,
  ContractProviders,

  // Wallet
  ConnectedWallet,
  ReadonlyWallet,
  WalletConnection,
  WalletBalance,
  DustBalance,
  WalletProviders,

  // Config
  NetworkConfig,

  // Errors
  ClientError,
  ContractError,
  WalletError,
} from '@no-witness-labs/midday-sdk';

Error Types

| Error | Module | Description | |-------|--------|-------------| | ClientError | Client | Client creation/operation failures | | Client.TxTimeoutError | Client | Transaction timeout (has txHash) | | ContractError | Contract | Contract deployment/call failures | | Contract.TxTimeoutError | Contract | Deploy/join timeout (has operation) | | WalletError | Wallet | Wallet connection/operation failures |

License

MIT