Demo 04 · Local · Undeployed · Zero-DUST

Choreo Ledger (Local)

The same TimestampLog.compact contract from Demo 01, run against a local Midnight standalone stack instead of Preprod. This is the path Midnight DevRel currently recommends for reviewers: no faucet, no tDUST scarcity, no 1010 InvalidDustSpendProof, no /check 400 — the local node mints tokens to the genesis wallet and every version is guaranteed to match.

why undeployed?

NetworkId.Undeployed is a fully local devnet: node + indexer + proof-server all on localhost. The bech32 suffix on every address is undeployed (Lace labels this network as "Preview" in its UI, but the addresses are prefixed mn_shield-addr_undeployed1…). See the known issues page for why this bypasses the current Preprod DUST bugs.

network · undeployed (local)

This demo only works when the local Midnight standalone stack is running on your machine. Use the wallet panel below to confirm Lace is pointing at ws://localhost:9944.

try it · connect lace

Run it locally

Requires Docker Desktop (macOS / Windows) or Docker Engine (Linux) running.

  1. Start the standalone stack — one command.
    bun scripts/midnight-standalone.mjs up

    Writes .midnight/standalone.docker-compose.yml, pulls the pinned node / indexer / proof-server images, boots the three services, and polls readiness. First run pulls ~1 GB and takes 2–5 min; subsequent boots are seconds. Use down, status, or logs in place of up for lifecycle control.

  1. Verify from the browser: /undeployed-preflight. Four green pills = ready. Any red pill shows the exact endpoint + error.
  2. Point Lace at the local node. Add a custom network in Lace → Midnight settings with node ws://localhost:9944 and indexer http://localhost:8088/api/v4/graphql. Switch Lace to that network. (Lace displays it as "Preview" — that's expected; the address prefix confirms it's Undeployed.)
  3. Deploy the contract locally:
    VITE_NETWORK_ID=undeployed \
    VITE_INDEXER_URL=http://localhost:8088/api/v4/graphql \
    VITE_INDEXER_WS_URL=ws://localhost:8088/api/v4/graphql/ws \
    VITE_NODE_RPC=ws://localhost:9944 \
    bun scripts/deploy-midnight.mjs

    Writes src/data/midnight-contract.undeployed.json; this page hydrates on the next reload.

  4. Reload the page. Wallet panel above should show network · undeployed; the address block below should switch from placeholder to a real hex contract ID.
OS-specific fallback (manual docker compose)
macOS: brew install --cask dockeropen -a Docker → wait for the whale icon → run the up command above.
Windows (WSL2): wsl --install, install Docker Desktop with "Use WSL 2 based engine", then run the up command from inside the WSL2 Ubuntu shell so browser port-forwarding works.
Linux: sudo apt install -y docker.io docker-compose-plugin sudo systemctl enable --now docker sudo usermod -aG docker "$USER" && newgrp docker, then run the up command.
contract address · undeployed
0x00… (awaiting local deploy — see steps above)
local endpoints
node · ws://localhost:9944
indexer · http://localhost:8088/api/v4/graphql
proof · http://localhost:6300
expected address prefixes
mn_addr_undeployed1… · mn_shield-addr_undeployed1

Both the deploy script and WalletConnectPanel hard-fail on prefix mismatch, so a stray preview / test suffix would abort before any funds move.