{"id":47301303,"url":"https://github.com/midnightntwrk/midnight-local-dev","last_synced_at":"2026-05-14T15:04:26.804Z","repository":{"id":343252514,"uuid":"1168805706","full_name":"midnightntwrk/midnight-local-dev","owner":"midnightntwrk","description":"Midnight local development environment","archived":false,"fork":false,"pushed_at":"2026-03-24T09:29:34.000Z","size":154,"stargazers_count":5,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-24T13:55:53.598Z","etag":null,"topics":["compact","midnightntwrk"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/midnightntwrk.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-27T20:22:17.000Z","updated_at":"2026-03-24T09:29:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/midnightntwrk/midnight-local-dev","commit_stats":null,"previous_names":["midnightntwrk/midnight-local-dev"],"tags_count":0,"template":false,"template_full_name":"midnightntwrk/midnight-template-repo","purl":"pkg:github/midnightntwrk/midnight-local-dev","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/midnightntwrk%2Fmidnight-local-dev","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/midnightntwrk%2Fmidnight-local-dev/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/midnightntwrk%2Fmidnight-local-dev/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/midnightntwrk%2Fmidnight-local-dev/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/midnightntwrk","download_url":"https://codeload.github.com/midnightntwrk/midnight-local-dev/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/midnightntwrk%2Fmidnight-local-dev/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33030380,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"online","status_checked_at":"2026-05-14T02:00:06.663Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compact","midnightntwrk"],"created_at":"2026-03-17T03:00:22.710Z","updated_at":"2026-05-14T15:04:26.793Z","avatar_url":"https://github.com/midnightntwrk.png","language":"TypeScript","funding_links":[],"categories":["Getting Started"],"sub_categories":[],"readme":"# Midnight Local Network\n\nA standalone tool for running a local Midnight development network and funding test accounts. It handles Docker container orchestration, genesis wallet initialization, NIGHT token transfers, and DUST registration — so your DApp projects can connect to a ready-to-use local blockchain without managing infrastructure themselves.\n\n## Table of Contents\n\n- [Prerequisites](#prerequisites)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Network Services](#network-services)\n- [Funding Options](#funding-options)\n  - [Option 1: Fund from Config File (NIGHT + DUST)](#option-1-fund-from-config-file-night--dust)\n  - [Option 2: Fund by Public Key (NIGHT Only)](#option-2-fund-by-public-key-night-only)\n- [Connecting Your DApp](#connecting-your-dapp)\n- [Running the Network Standalone (Without the Funding CLI)](#running-the-network-standalone-without-the-funding-cli)\n- [Accounts Config File Format](#accounts-config-file-format)\n- [Environment Variables](#environment-variables)\n- [Architecture](#architecture)\n- [Troubleshooting](#troubleshooting)\n\n---\n\n## Prerequisites\n\n- **Node.js** \u003e= 22.0.0\n- **Docker** and **Docker Compose** (v2)\n- Access to the Midnight npm registry (for `@midnight-ntwrk/*` packages)\n\n## Installation\n\n```bash\ncd midnight-local-dev\nnpm install\n```\n\n## Quick Start\n\n```bash\nnpm start\n```\n\nThis single command will:\n\n1. **Detect** if a local Midnight network is already running\n   - If running: prompt to **reuse** it or **restart** with fresh images\n   - If not running: **pull** Docker images and **start** all containers\n2. **Initialize** the genesis master wallet (seed `0x00...001`) which holds all minted NIGHT tokens\n3. **Register DUST** for the master wallet (required to pay transaction fees)\n4. **Display** the master wallet balance\n5. **Present an interactive menu** for funding test accounts\n\nIf a network is already running, you'll first see:\n\n```\nA local dev network is already running:\n  [1] Use the existing network\n  [2] Stop containers, pull latest images, and restart\n\u003e\n```\n\nThen the main menu:\n\n```\nChoose an option:\n  [1] Fund accounts from config file (NIGHT + DUST registration)\n  [2] Fund accounts by public key (NIGHT transfer only)\n  [3] Display master wallet balances\n  [4] Exit\n\u003e\n```\n\nWhen you select `[4] Exit` or press `Ctrl+C`, the tool gracefully shuts down all wallets. Docker containers are only stopped if they were started by this session (reusing an existing network leaves containers running).\n\n---\n\n## Network Services\n\nThe local network runs three Docker containers on fixed ports:\n\n| Service | Container Name | Host Port | URL |\n|---|---|---|---|\n| **Midnight Node** | `midnight-node` | `9944` | `http://localhost:9944` |\n| **Indexer** (GraphQL) | `midnight-indexer` | `8088` | `http://localhost:8088/api/v3/graphql` |\n| **Indexer** (WebSocket) | `midnight-indexer` | `8088` | `ws://localhost:8088/api/v3/graphql/ws` |\n| **Proof Server** | `midnight-proof-server` | `6300` | `http://localhost:6300` |\n\nThese ports match the defaults hardcoded by the **Lace wallet extension** when configured for the `undeployed` network type. This means Lace connects to the local network out of the box — no custom endpoint configuration required. Just select \"Undeployed\" in Lace's network settings and it will point to `localhost:9944`, `localhost:8088`, and `localhost:6300` automatically.\n\nAll services use the `undeployed` network ID with the `dev` node preset.\n\n### Docker Images\n\n| Service | Image | Version |\n|---|---|---|\n| Node | `midnightntwrk/midnight-node` | `0.22.3` |\n| Indexer | `midnightntwrk/indexer-standalone` | `4.0.1` |\n| Proof Server | `midnightntwrk/proof-server` | `8.0.3` |\n\n### Wallet SDK Compatibility Matrix\n\n| Package | Version |\n|---|---|\n| `@midnight-ntwrk/wallet-sdk-facade` | 3.0.0 |\n| `@midnight-ntwrk/wallet-sdk-abstractions` | 2.0.0 |\n| `@midnight-ntwrk/wallet-sdk-shielded` | 2.1.0 |\n| `@midnight-ntwrk/wallet-sdk-dust-wallet` | 3.0.0 |\n| `@midnight-ntwrk/wallet-sdk-unshielded-wallet` | 2.1.0 |\n| `@midnight-ntwrk/wallet-sdk-address-format` | 3.1.0 |\n| `@midnight-ntwrk/wallet-sdk-hd` | 3.0.1 |\n| `@midnight-ntwrk/ledger-v8` | 8.0.3 |\n| `@midnight-ntwrk/midnight-js-network-id` | 4.0.2 |\n\n---\n\n## Funding Options\n\nEach funding operation transfers **50,000 NIGHT** (in smallest denomination: `50,000 * 10^6`) from the genesis master wallet. You can fund up to **10 accounts** per operation.\n\n### Option 1: Fund from Config File (NIGHT + DUST)\n\nBest for development setups where you control the test wallets. Provide a JSON file with BIP39 mnemonics. For each account, the tool will:\n\n1. Derive a wallet from the mnemonic\n2. Transfer 50,000 NIGHT from the master wallet\n3. Wait for the recipient to see the funds\n4. Register the recipient's NIGHT UTXOs for DUST generation\n5. Wait for DUST to be available\n\nAfter this, each account is **fully ready** to submit transactions (deploy contracts, call circuits, etc.) because they have both NIGHT (for value) and DUST (for fees).\n\n```\n\u003e 1\nPath to accounts JSON file: ./accounts.json\n```\n\nSee [Accounts Config File Format](#accounts-config-file-format) for the JSON schema.\n\n### Option 2: Fund by Public Key (NIGHT Only)\n\nBest when you already have wallet addresses (e.g., from the Lace wallet or another DApp) and just need tokens. Provide one or more Bech32 addresses separated by commas.\n\n```\n\u003e 2\nEnter Bech32 addresses (comma-separated): mn1q..., mn1q...\n```\n\nEach address receives 50,000 NIGHT. **DUST is not registered** — recipients must register for DUST themselves before they can pay transaction fees.\n\n---\n\n## Connecting Your DApp\n\nOnce the network is running, any Midnight DApp can connect using the standard localhost endpoints. No special configuration needed.\n\n### Example: ZKLoan Credit Scorer CLI\n\nIn a **separate terminal**, while the network is running:\n\n```bash\ncd ../zkloan-credit-scorer/zkloan-credit-scorer-cli\nnpm run standalone\n```\n\nThe CLI's standalone mode connects to the same fixed ports (`9944`, `8088`, `6300`) without starting its own Docker containers.\n\n### Example: Custom TypeScript DApp\n\n```typescript\nimport { setNetworkId } from '@midnight-ntwrk/midnight-js-network-id';\n\nsetNetworkId('undeployed');\n\nconst config = {\n  indexer: 'http://127.0.0.1:8088/api/v3/graphql',\n  indexerWS: 'ws://127.0.0.1:8088/api/v3/graphql/ws',\n  node: 'http://127.0.0.1:9944',\n  proofServer: 'http://127.0.0.1:6300',\n  networkId: 'undeployed',\n};\n\n// Use these endpoints with the Midnight wallet SDK, contract deployment, etc.\n```\n\n### Example: UI Development (React / Vite)\n\nPoint your UI's environment variables to the local endpoints:\n\n```env\nVITE_INDEXER_URL=http://localhost:8088/api/v3/graphql\nVITE_INDEXER_WS_URL=ws://localhost:8088/api/v3/graphql/ws\nVITE_NODE_URL=http://localhost:9944\nVITE_PROOF_SERVER_URL=http://localhost:6300\nVITE_NETWORK_ID=undeployed\n```\n\n---\n\n## Running the Network Standalone (Without the Funding CLI)\n\nIf you only need the Docker containers running (no wallet initialization or funding), you can use Docker Compose directly:\n\n```bash\n# Pull images and start all services\ndocker compose -f standalone.yml up -d\n\n# Check service health\ndocker compose -f standalone.yml ps\n\n# View logs\ndocker compose -f standalone.yml logs -f\n\n# Stop everything\ndocker compose -f standalone.yml down\n```\n\nThis is useful when:\n- Your DApp handles its own wallet initialization\n- You want to keep the network running across multiple test sessions\n- You're debugging container-level issues\n\nNote: In this mode you must handle genesis wallet funding and DUST registration yourself.\n\n---\n\n## Accounts Config File Format\n\nCreate a JSON file with the following structure:\n\n```json\n{\n  \"accounts\": [\n    {\n      \"name\": \"Alice\",\n      \"mnemonic\": \"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art\"\n    },\n    {\n      \"name\": \"Bob\",\n      \"mnemonic\": \"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote\"\n    }\n  ]\n}\n```\n\n| Field | Type | Description |\n|---|---|---|\n| `accounts` | `array` | List of accounts to fund (max 10) |\n| `accounts[].name` | `string` | Display name for logging |\n| `accounts[].mnemonic` | `string` | BIP39 mnemonic phrase (24 words) |\n\nAn example file is provided at `accounts.example.json`.\n\n**Security note:** These mnemonics are for **local development only**. Never use real wallet mnemonics in config files.\n\n---\n\n## Environment Variables\n\nCopy `.env.example` to `.env` and configure as needed:\n\n| Variable | Default | Description |\n|---|---|---|\n| `DEBUG_LEVEL` | `info` | Log level: `trace`, `debug`, `info`, `warn`, `error`, `fatal` |\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────┐\n│              midnight-local-network              │\n│                                                  │\n│  src/index.ts     Entry point \u0026 interactive menu │\n│  src/network.ts   Docker compose orchestration   │\n│  src/wallet.ts    Wallet SDK operations          │\n│  src/funding.ts   NIGHT transfer \u0026 DUST reg.     │\n│  src/config.ts    Network endpoint config        │\n│  src/logger.ts    Pino logger setup              │\n└──────────┬──────────────────────────┬────────────┘\n           │                          │\n     testcontainers              Wallet SDK\n           │                          │\n           ▼                          ▼\n┌──────────────────┐   ┌──────────────────────────┐\n│  Docker Compose  │   │   Midnight Blockchain    │\n│                  │   │                          │\n│  ┌────────────┐  │   │  Genesis Wallet (master) │\n│  │    Node    │◄─┼───┤  ├─ Transfer NIGHT       │\n│  │   :9944    │  │   │  ├─ Register DUST        │\n│  └────────────┘  │   │  └─ Fund recipients      │\n│  ┌────────────┐  │   │                          │\n│  │  Indexer   │  │   │  Recipient Wallets       │\n│  │   :8088    │  │   │  ├─ From mnemonic        │\n│  └────────────┘  │   │  └─ From Bech32 address  │\n│  ┌────────────┐  │   └──────────────────────────┘\n│  │   Proof    │  │\n│  │  Server    │  │\n│  │   :6300    │  │\n│  └────────────┘  │\n└──────────────────┘\n```\n\n### Startup Sequence\n\n```\n1. Network detection\n   ├── Check if midnight-node, midnight-indexer, midnight-proof-server are running\n   ├── If running → prompt: reuse existing or restart fresh\n   └── If not running → docker compose up\n       ├── midnight-node starts (waits for health: /health endpoint)\n       ├── midnight-indexer starts (waits for: \"starting indexing\" log)\n       └── midnight-proof-server starts (waits for: \"Actix runtime found\" log)\n\n2. Master wallet initialization (WalletFacade.init)\n   ├── Derive HD wallet from genesis seed (0x00...001)\n   ├── Create unified DefaultConfiguration\n   ├── Initialize WalletFacade with shielded, unshielded, and dust builders\n   ├── Start wallet facade and wait for sync\n   └── Display genesis NIGHT balance\n\n3. DUST registration for master wallet\n   ├── Find unregistered Night UTXOs\n   ├── Submit registration transaction\n   └── Wait for dust balance \u003e 0\n\n4. Interactive menu (fund accounts, check balances, exit)\n\n5. Cleanup on exit\n   ├── Close all wallet connections\n   └── docker compose down (only if network was started by this session)\n```\n\n### Key Concepts\n\n- **NIGHT**: The native token on Midnight. The genesis block mints a large supply accessible via the master wallet seed.\n- **DUST**: Transaction fees on Midnight are paid in DUST, which is generated by registering NIGHT UTXOs. Without DUST registration, a wallet cannot submit transactions even if it holds NIGHT.\n- **Master Wallet**: The genesis wallet (seed `0x00...001`) that holds all initially minted tokens. All funding transfers originate from this wallet.\n- **Unshielded vs Shielded**: NIGHT can be held in unshielded (public) or shielded (private) form. This tool transfers unshielded NIGHT.\n\n---\n\n## Troubleshooting\n\n### Port already in use\n\n```\nError: Bind for 0.0.0.0:9944 failed: port is already allocated\n```\n\nAnother process or a previous run is using the port. Stop it:\n\n```bash\ndocker compose -f standalone.yml down\n# or find and kill the process\nlsof -i :9944\n```\n\n### Containers not starting\n\nCheck Docker is running and you have access to the Midnight Docker registry:\n\n```bash\ndocker compose -f standalone.yml pull\ndocker compose -f standalone.yml up\n```\n\nWatch the logs for specific errors:\n\n```bash\ndocker compose -f standalone.yml logs -f node\ndocker compose -f standalone.yml logs -f indexer\ndocker compose -f standalone.yml logs -f proof-server\n```\n\n### Wallet sync takes too long\n\nThe indexer needs time to catch up with the node after startup. If sync seems stuck:\n\n1. Check the indexer logs: `docker compose -f standalone.yml logs -f indexer`\n2. Verify the node is producing blocks: `curl http://localhost:9944/health`\n3. Set `DEBUG_LEVEL=debug` in `.env` for more detailed wallet logs\n\n### DUST registration fails\n\nDUST registration requires the wallet to have synced and found its NIGHT UTXOs. If it fails:\n\n1. Ensure the wallet has a non-zero NIGHT balance\n2. Check the proof server is healthy: `curl http://localhost:6300/version`\n3. Try again — transient network issues during startup can cause one-time failures\n\n### Logs\n\nLogs are written to both the console and a timestamped file in the `logs/` directory:\n\n```bash\nls logs/\n# 2026-02-24T12:00:00.000Z.log\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmidnightntwrk%2Fmidnight-local-dev","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmidnightntwrk%2Fmidnight-local-dev","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmidnightntwrk%2Fmidnight-local-dev/lists"}