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.
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.
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.
Run it locally
Requires Docker Desktop (macOS / Windows) or Docker Engine (Linux) running.
- 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. Usedown,status, orlogsin place ofupfor lifecycle control.
- Verify from the browser: /undeployed-preflight. Four green pills = ready. Any red pill shows the exact endpoint + error.
- Point Lace at the local node. Add a custom network in Lace → Midnight settings with node
ws://localhost:9944and indexerhttp://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.) - 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. - 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)
brew install --cask docker → open -a Docker → wait for the whale icon → run the up command above.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.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.Both the deploy script and WalletConnectPanel hard-fail on prefix mismatch, so a stray preview / test suffix would abort before any funds move.