Set up and run Midnight infrastructure locally using official dev tools...
Complete guide to running Midnight infrastructure locally using the official midnight-infra-dev-tools. This enables full local development without connecting to testnet.
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Local Development Stack ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā ā
ā āāāāāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāāāāā ā
ā ā Midnight Node ā ā Indexer ā ā Proof Server ā ā
ā ā ā ā ā ā ā ā
ā ā ws://127.0.0.1 ā ā http://127.0.0.1ā ā http://127.0.0.1ā ā
ā ā :9944 ā ā :8088 ā ā :6300 ā ā
ā ā ā ā ā ā ā ā
ā ā - Blockchain ā ā - Query state ā ā - ZK proofs ā ā
ā ā - Consensus ā ā - Index txs ā ā - Verification ā ā
ā ā - State ā ā - GraphQL API ā ā - Circuits ā ā
ā āāāāāāāāāā¬āāāāāāāāā āāāāāāāāāā¬āāāāāāāāā āāāāāāāāāā¬āāāāāāāāā ā
ā ā ā ā ā
ā āāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāā ā
ā ā ā
ā āāāāāāāāāāāāā“āāāāāāāāāāāā ā
ā ā Your dApp / Tests ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
| Component | Repository | Purpose |
|---|---|---|
| Dev Tools | midnight-infra-dev-tools | Scripts & guides for local setup |
| Node | midnight-node | Blockchain node (Substrate-based) |
| Indexer | midnight-indexer | State indexing & GraphQL API |
| Ledger | midnight-ledger | Proof server & ZK circuits |
git clone https://github.com/midnightntwrk/midnight-infra-dev-tools.git
cd midnight-infra-dev-tools
The dev tools allow you to select specific commits for each component to ensure compatibility.
# Check available versions
cat versions.json
# Or select specific commits in the config
# Clone the node
git clone https://github.com/midnightntwrk/midnight-node.git
# Clone the indexer
git clone https://github.com/midnightntwrk/midnight-indexer.git
# Clone the ledger (proof server)
git clone https://github.com/midnightntwrk/midnight-ledger.git
# Start all three components
./scripts/start-all.sh
# Or start individually:
./scripts/start-node.sh
./scripts/start-indexer.sh
./scripts/start-proof-server.sh
The blockchain node handles consensus, state management, and transaction processing.
Default Endpoint: ws://127.0.0.1:9944
# Start node
cd midnight-node
cargo build --release
./target/release/midnight-node --dev
# Or use Docker
docker run -p 9944:9944 midnightntwrk/midnight-node:latest --dev
Key Features:
Indexes blockchain state and provides GraphQL API for queries.
Default Endpoint: http://127.0.0.1:8088
# Start indexer
cd midnight-indexer
npm install
npm run start
# GraphQL playground available at:
# http://127.0.0.1:8088/graphql
Key Features:
IMPORTANT: The indexer must be synced with the node version. Update the metadata that the indexer interprets when changing node commits.
Generates and verifies zero-knowledge proofs for transactions.
Default Endpoint: http://127.0.0.1:6300
# Start proof server
cd midnight-ledger
cargo build --release
./target/release/proof-server
# Or use Docker
docker run -p 6300:6300 midnightntwrk/proof-server:latest
CRITICAL: The proof server must use the same ledger version integrated into midnight-node. Check version in:
midnight-node/Cargo.toml lines 63-70
Example from Cargo.toml:
[dependencies]
midnight-ledger = { git = "https://github.com/midnightntwrk/midnight-ledger", rev = "abc123" }
All three components must be version-compatible:
# Check node's ledger dependency
grep "midnight-ledger" midnight-node/Cargo.toml
# Check indexer metadata version
cat midnight-indexer/metadata/version.json
# Verify proof server version
./proof-server --version
When you change the node commit:
# Update indexer metadata
cd midnight-indexer
./scripts/update-metadata.sh <node-commit>
npm run reindex
Create a config file for your dApp:
// config.ts
export const localConfig = {
node: {
url: "ws://127.0.0.1:9944",
},
indexer: {
url: "http://127.0.0.1:8088",
graphql: "http://127.0.0.1:8088/graphql",
},
proofServer: {
url: "http://127.0.0.1:6300",
},
};
export const previewConfig = {
node: {
url: "wss://rpc.preview.midnight.network",
},
indexer: {
url: "https://indexer.preview.midnight.network",
graphql: "https://indexer.preview.midnight.network/graphql",
},
proofServer: {
url: "https://proof.preview.midnight.network",
},
};
# .env.local
MIDNIGHT_NODE_URL=ws://127.0.0.1:9944
MIDNIGHT_INDEXER_URL=http://127.0.0.1:8088
MIDNIGHT_PROOF_SERVER_URL=http://127.0.0.1:6300
The starter template integrates with local infrastructure:
# Clone starter template
git clone https://github.com/MeshJS/midnight-starter-template.git
cd midnight-starter-template
# Install dependencies
npm install
# Start local infrastructure (uses Docker)
npm run setup-standalone
# In another terminal, start frontend
npm run dev:frontend
Error: Cannot bind to port 9944
Solution: Another process is using the port
lsof -i :9944
kill -9 <PID>
Error: WebSocket connection failed
Solution: Ensure node is running and accessible
# Test node connection
wscat -c ws://127.0.0.1:9944
Error: Incompatible ledger version
Solution: Sync proof server to node's ledger version
# Check node's ledger dependency
grep "midnight-ledger" midnight-node/Cargo.toml
# Checkout matching version in midnight-ledger
cd midnight-ledger
git checkout <matching-commit>
cargo build --release
Error: Block parsing failed
Solution: Update indexer metadata and reindex
cd midnight-indexer
./scripts/update-metadata.sh
npm run reindex
Error: Cannot connect to Docker daemon
Solution: Start Docker Desktop or daemon
# macOS
open -a Docker
# Linux
sudo systemctl start docker
# Node health
curl -s http://127.0.0.1:9944/health
# Indexer health
curl -s http://127.0.0.1:8088/health
# Proof server health
curl -s http://127.0.0.1:6300/health
# Test WebSocket to node
wscat -c ws://127.0.0.1:9944
# Test GraphQL
curl -X POST http://127.0.0.1:8088/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ __schema { types { name } } }"}'
Use the provided setup script:
bash /path/to/skills/midnight-infra-setup/scripts/setup.sh [action]
Actions:
start - Start all infrastructurestop - Stop all infrastructurestatus - Check service statuslogs - View logsreset - Reset and restartMidnight Infrastructure Status:
Node: ā Running (ws://127.0.0.1:9944)
Indexer: ā Running (http://127.0.0.1:8088)
Proof Server: ā Running (http://127.0.0.1:6300)
All services are healthy and synchronized.
Next steps:
1. Deploy your contract: npm run deploy:local
2. Start frontend: npm run dev:frontend
3. Connect wallet and interact