This project is built on the Midnight Network.
Use this repo as a template. Do not fork it.
This repository is intended to be used via GitHub’s “Use this template” flow.
Forking this repo is discouraged, as forks are not tracked as independent projects.
A Midnight smart contract example demonstrating a simple one-item bulletin board with zero-knowledge proofs on testnet. Users can post a single message at a time, and only the message author can remove it.
bulletin-board/
├── contract/ # Smart contract in Compact language
│ └── src/ # Contract source and utilities
├── api/ # Methods, classes and types for CLI and UI
├── bboard-cli/ # Command-line interface
│ └── src/ # CLI implementation
└── bboard-ui/ # Web browser interface
└── src/ # Web UI implementation
You need Node.js:
node --versionExpected output: v24.11.1 or higher. The repository includes an .nvmrc pinned to 24.11.1.
If you get a lower version: Install Node.js LTS.
The proof server runs in Docker and is required for both CLI and UI to generate zero-knowledge proofs:
docker --versionExpected output: Docker version X.X.X.
If Docker is not found: Install Docker Desktop. Make sure Docker Desktop is running.
For the web interface, install the official Lace wallet extension on Chrome Store or the Edge Store (tested with version 1.36.0).
After installing, set up the Midnight wallet:
- Create a new wallet — Midnight will appear as a network option
- Set Network to Preprod
- Set Proof server to Local (http://localhost:6300) — this must point to your local proof server started via Docker
- Click Enter Wallet
- Fund your wallet with tNIGHT tokens from the Preprod Faucet
- Go to Tokens in the wallet, click Generate tDUST, and confirm the transaction — tDUST tokens are required to pay transaction fees on preprod
npm installThis repository uses npm workspaces. Run installation once from the repository root.
The Compact compiler (compactc 0.30.0) generates TypeScript bindings and zero-knowledge circuits from the smart contract source code:
cd contract
npm run compact # Compiles the Compact contract
npm run build # Copies compiled files to dist/
cd ..Expected output:
> compact
> compact compile src/bboard.compact ./src/managed/bboard
Compiling 2 circuits:
circuit "post" (k=14, rows=10070)
circuit "takeDown" (k=14, rows=10087)
> build
> rm -rf dist && tsc --project tsconfig.build.json && cp -Rf ./src/managed ./dist/managed && cp ./src/bboard.compact ./dist
cd bboard-cli
npm run build
cd ..Only needed if you want to use the web interface:
cd bboard-ui
npm run build
cd ..The CLI requires a local proof server running in Docker:
cd bboard-cli
docker compose -f proof-server-local.yml up -dThis uses midnightntwrk/proof-server:8.0.3 on http://127.0.0.1:6300.
# For preprod network
npm run preprod-remote
# For preview network
npm run preview-remote- Choose option
1to build a fresh wallet - The system will generate a wallet address and seed
- Save both the address and seed - you'll need them later
Expected output is similar to:
Your wallet seed is: [64-character hex string]
Using unshielded address: mn_addr_preprod1hdvtst70zfgd8wvh7l8ppp7mcrxnjn56wc5hlxpwflz3fxdykaesrw0ln4 waiting for funds...
Before deploying contracts, you need testnet tokens.
- Copy your wallet address from the output above
- Visit the faucet
- Paste your address and request funds
- Wait for the CLI to detect the funds (takes 2-3 minutes)
Expected output after funding is similar to:
Your NIGHT wallet balance is: 1000000000
- Choose the contract deployment option
- Wait for deployment (takes ~30 seconds)
- Save the contract address for future use
Expected output:
Deployed bulletin board contract at address: [contract address]
You can now:
- Post a message to the bulletin board
- View the current message
- Remove your message (only if you posted it)
- Exit when done
Each action creates a real transaction on Midnight Testnet using zero-knowledge proofs generated by the proof server.
The web interface uses the same proof server and requires additional browser setup.
If you haven't started the proof server for the CLI, start it now:
cd bboard-cli
docker compose -f proof-server-local.yml up -d
cd ..Verify it's running:
docker psThe UI can run against preprod or preview networks:
cd bboard-ui
# For preprod network
npm run build:start
# For preview network
npm run build:start:previewThe UI will be available at:
- Open the UI URL in a browser with Lace wallet extension installed
- Set up Lace wallet if it's your first time
- Authorize the application when Lace wallet prompts
- Use the bulletin board web interface
- Get Testnet tNIGHT on Preprod Faucet or Preview Faucet
- Midnight Documentation - Complete developer guide
- Compatibility Matrix - Current supported Midnight component versions
- Compact Language Guide - Smart contract language reference
- Get Lace wallet on the Chrome Store or the Edge Store
| Common Issue | Solution |
|---|---|
npm install fails |
Ensure you're using Node v24.11.1 or newer. Older Node versions can install with warnings but are not the target runtime |
| Contract compilation fails | Ensure the Compact toolchain is installed and run npm run compact from contract/ |
| Network connection timeout | CLI requires internet connection, restart if connection times out |
| Token funding takes too long | Wait 1-2 minutes, funding is automatic in CLI |
| "Application not authorized" error | Start proof server: docker compose -f proof-server-local.yml up -d |
| Lace wallet not detected | Install Lace wallet browser extension and refresh page |
| Docker issues | Ensure Docker Desktop is running, check docker --version |
| Port 6300 in use | Run docker compose down then restart services |
| Dependencies won't install | Use Node.js LTS version. For older npm versions, you may need --legacy-peer-deps |
| Contract deployment fails | Verify wallet has sufficient balance and network connection |
- CLI and UI can run simultaneously and share the same proof server
- Proof server (Docker) is required for both CLI and UI to generate zero-knowledge proofs
- Contract must be compiled before building CLI or UI
- Fund your wallet using the testnet faucet before deploying contracts
- Transaction fee configuration
The defaultadditionalFeeOverheadvalue (500_000_000_000_000_000n) from@midnight-ntwrk/testkit-jsis required on theundeployednetwork. Lower values can fail withBalanceCheckOverspendon the node side. On remote networks, that overhead requires too much dust, so the CLI overrides it to1_000n. - CLI private state is stored per contract address, matching the
Midnight.js 4.xprivate-state provider model.