@aaronbassett/midnight-local-devnet 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +212 -0
  3. package/dist/cli/commands/accounts.d.ts +3 -0
  4. package/dist/cli/commands/accounts.js +38 -0
  5. package/dist/cli/commands/accounts.js.map +1 -0
  6. package/dist/cli/commands/network.d.ts +3 -0
  7. package/dist/cli/commands/network.js +84 -0
  8. package/dist/cli/commands/network.js.map +1 -0
  9. package/dist/cli/commands/wallet.d.ts +3 -0
  10. package/dist/cli/commands/wallet.js +49 -0
  11. package/dist/cli/commands/wallet.js.map +1 -0
  12. package/dist/cli/interactive.d.ts +2 -0
  13. package/dist/cli/interactive.js +90 -0
  14. package/dist/cli/interactive.js.map +1 -0
  15. package/dist/cli.d.ts +2 -0
  16. package/dist/cli.js +48 -0
  17. package/dist/cli.js.map +1 -0
  18. package/dist/core/accounts.d.ts +17 -0
  19. package/dist/core/accounts.js +80 -0
  20. package/dist/core/accounts.js.map +1 -0
  21. package/dist/core/config.d.ts +12 -0
  22. package/dist/core/config.js +22 -0
  23. package/dist/core/config.js.map +1 -0
  24. package/dist/core/docker.d.ts +13 -0
  25. package/dist/core/docker.js +101 -0
  26. package/dist/core/docker.js.map +1 -0
  27. package/dist/core/funding.d.ts +15 -0
  28. package/dist/core/funding.js +105 -0
  29. package/dist/core/funding.js.map +1 -0
  30. package/dist/core/health.d.ts +13 -0
  31. package/dist/core/health.js +34 -0
  32. package/dist/core/health.js.map +1 -0
  33. package/dist/core/logger.d.ts +2 -0
  34. package/dist/core/logger.js +16 -0
  35. package/dist/core/logger.js.map +1 -0
  36. package/dist/core/network-manager.d.ts +31 -0
  37. package/dist/core/network-manager.js +101 -0
  38. package/dist/core/network-manager.js.map +1 -0
  39. package/dist/core/types.d.ts +51 -0
  40. package/dist/core/types.js +11 -0
  41. package/dist/core/types.js.map +1 -0
  42. package/dist/core/wallet.d.ts +23 -0
  43. package/dist/core/wallet.js +163 -0
  44. package/dist/core/wallet.js.map +1 -0
  45. package/dist/index.d.ts +2 -0
  46. package/dist/index.js +34 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/mcp/resources/config.d.ts +3 -0
  49. package/dist/mcp/resources/config.js +28 -0
  50. package/dist/mcp/resources/config.js.map +1 -0
  51. package/dist/mcp/server.d.ts +3 -0
  52. package/dist/mcp/server.js +28 -0
  53. package/dist/mcp/server.js.map +1 -0
  54. package/dist/mcp/tools/accounts.d.ts +3 -0
  55. package/dist/mcp/tools/accounts.js +28 -0
  56. package/dist/mcp/tools/accounts.js.map +1 -0
  57. package/dist/mcp/tools/funding.d.ts +3 -0
  58. package/dist/mcp/tools/funding.js +59 -0
  59. package/dist/mcp/tools/funding.js.map +1 -0
  60. package/dist/mcp/tools/health.d.ts +3 -0
  61. package/dist/mcp/tools/health.js +19 -0
  62. package/dist/mcp/tools/health.js.map +1 -0
  63. package/dist/mcp/tools/network.d.ts +3 -0
  64. package/dist/mcp/tools/network.js +64 -0
  65. package/dist/mcp/tools/network.js.map +1 -0
  66. package/dist/mcp/tools/wallet.d.ts +3 -0
  67. package/dist/mcp/tools/wallet.js +19 -0
  68. package/dist/mcp/tools/wallet.js.map +1 -0
  69. package/docker/standalone.env +5 -0
  70. package/docker/standalone.yml +49 -0
  71. package/package.json +64 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 DevRel AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,212 @@
1
+ # midnight-local-devnet
2
+
3
+ A CLI and MCP (Model Context Protocol) server for managing a local Docker-based Midnight development network. It spins up a Midnight node, indexer, and proof server in Docker containers, initializes a genesis master wallet pre-loaded with NIGHT tokens and DUST, and provides commands to fund test accounts, generate wallets, and monitor network health -- all from the command line or from any MCP-compatible AI assistant.
4
+
5
+ ## Prerequisites
6
+
7
+ - **Node.js >= 22** (uses native ES modules and `node:` imports)
8
+ - **Docker** (Docker Desktop or Docker Engine with Compose v2)
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install
14
+ npm run build
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ### CLI
20
+
21
+ Run with no arguments to enter interactive mode:
22
+
23
+ ```bash
24
+ npx midnight-devnet
25
+ ```
26
+
27
+ Or start the network directly:
28
+
29
+ ```bash
30
+ npx midnight-devnet start
31
+ ```
32
+
33
+ ### MCP Server
34
+
35
+ Add the server to your `.mcp.json` (Claude Code, Cursor, or any MCP client):
36
+
37
+ ```json
38
+ {
39
+ "mcpServers": {
40
+ "midnight-devnet": {
41
+ "command": "node",
42
+ "args": ["--enable-source-maps", "/absolute/path/to/midnight-local-devnet/dist/index.js"]
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ The MCP server communicates over stdio and exposes tools, resources, and prompts that an AI assistant can use to manage the devnet on your behalf.
49
+
50
+ ## CLI Command Reference
51
+
52
+ | Command | Description | Options |
53
+ |---|---|---|
54
+ | `start` | Start the local Midnight devnet | `--pull` Pull latest Docker images |
55
+ | `stop` | Stop the devnet | `--remove-volumes` Remove volumes and containers |
56
+ | `restart` | Restart the network | `--pull`, `--remove-volumes` |
57
+ | `status` | Show network status and per-service info | |
58
+ | `logs` | Show network service logs | `--service <name>` (node, indexer, proof-server), `--lines <n>` (default: 50) |
59
+ | `health` | Check health of all services | |
60
+ | `balances` | Show master wallet NIGHT/DUST balances | |
61
+ | `fund <address>` | Fund a Bech32 address with NIGHT tokens | `--amount <n>` Amount in NIGHT (default: 50,000) |
62
+ | `fund-file <path>` | Fund all accounts from an accounts.json file | |
63
+ | `generate-accounts` | Generate random test accounts | `--count <n>`, `--format <mnemonic\|privateKey>`, `--output <path>`, `--fund`, `--register-dust` |
64
+ | `interactive` | Start interactive menu mode | |
65
+
66
+ Running the CLI with no arguments automatically enters interactive mode.
67
+
68
+ ## MCP Tool Reference
69
+
70
+ | Tool | Description | Parameters |
71
+ |---|---|---|
72
+ | `start-network` | Start the devnet (node, indexer, proof-server) | `pull?` boolean |
73
+ | `stop-network` | Stop the devnet and close wallets | `removeVolumes?` boolean |
74
+ | `restart-network` | Restart the network | `pull?` boolean, `removeVolumes?` boolean |
75
+ | `network-status` | Get current network and per-service status | |
76
+ | `network-logs` | Get recent logs from services | `service?` (node, indexer, proof-server), `lines?` number |
77
+ | `health-check` | Check health of all service endpoints | |
78
+ | `get-network-config` | Get endpoint URLs, network ID, image versions | |
79
+ | `get-wallet-balances` | Get NIGHT and DUST balances of master wallet | |
80
+ | `fund-account` | Transfer NIGHT to a Bech32 address | `address` string, `amount?` string |
81
+ | `fund-account-from-mnemonic` | Derive wallet from mnemonic, fund NIGHT, register DUST | `name` string, `mnemonic` string |
82
+ | `fund-accounts-from-file` | Batch fund accounts from accounts.json | `filePath` string |
83
+ | `generate-test-account` | Generate random test accounts | `format` (mnemonic\|privateKey), `count?`, `fund?`, `registerDust?`, `outputFile?` |
84
+
85
+ ## MCP Resource Reference
86
+
87
+ | URI | Description |
88
+ |---|---|
89
+ | `devnet://config` | Current network configuration: endpoints, network ID, Docker image versions |
90
+ | `devnet://status` | Live network status including per-service container state |
91
+
92
+ Resources are read-only and can be accessed by any MCP client to display context to an AI assistant.
93
+
94
+ ## accounts.json Format
95
+
96
+ The `fund-file` CLI command and `fund-accounts-from-file` MCP tool accept a JSON file describing accounts to fund. Each account is identified by a mnemonic; the tool derives its wallet, transfers NIGHT tokens, and registers DUST.
97
+
98
+ ```json
99
+ {
100
+ "accounts": [
101
+ {
102
+ "name": "Alice",
103
+ "mnemonic": "abandon abandon abandon ... art"
104
+ },
105
+ {
106
+ "name": "Bob",
107
+ "mnemonic": "zoo zoo zoo ... vote"
108
+ }
109
+ ]
110
+ }
111
+ ```
112
+
113
+ See `accounts.example.json` for a complete example with valid 24-word BIP39 mnemonics.
114
+
115
+ Each account entry requires:
116
+
117
+ - **name** -- A display label for the account.
118
+ - **mnemonic** -- A 24-word BIP39 mnemonic phrase.
119
+
120
+ ## Docker Services
121
+
122
+ The devnet runs three containers managed via Docker Compose:
123
+
124
+ | Service | Container Name | Image | Port | URL |
125
+ |---|---|---|---|---|
126
+ | Node | midnight-node | `midnightntwrk/midnight-node:0.20.0` | 9944 | `http://127.0.0.1:9944` |
127
+ | Indexer | midnight-indexer | `midnightntwrk/indexer-standalone:3.0.0` | 8088 | `http://127.0.0.1:8088/api/v3/graphql` |
128
+ | Proof Server | midnight-proof-server | `midnightntwrk/proof-server:7.0.0` | 6300 | `http://127.0.0.1:6300` |
129
+
130
+ The indexer also exposes a WebSocket endpoint at `ws://127.0.0.1:8088/api/v3/graphql/ws`.
131
+
132
+ The network ID is `undeployed` (development mode).
133
+
134
+ ## Network Endpoints for DApp Development
135
+
136
+ When connecting a Midnight DApp to the local devnet, use the following configuration:
137
+
138
+ ```typescript
139
+ const config = {
140
+ indexer: 'http://127.0.0.1:8088/api/v3/graphql',
141
+ indexerWS: 'ws://127.0.0.1:8088/api/v3/graphql/ws',
142
+ node: 'http://127.0.0.1:9944',
143
+ proofServer: 'http://127.0.0.1:6300',
144
+ networkId: 'undeployed',
145
+ };
146
+ ```
147
+
148
+ You can also retrieve this configuration at runtime via the `get-network-config` MCP tool or the `devnet://config` MCP resource.
149
+
150
+ ## Troubleshooting
151
+
152
+ ### Docker containers fail to start
153
+
154
+ Make sure Docker is running and your user has permissions to use it:
155
+
156
+ ```bash
157
+ docker info
158
+ ```
159
+
160
+ If you see a permission error, add your user to the `docker` group or use `sudo`.
161
+
162
+ ### Port conflicts
163
+
164
+ The devnet uses ports 9944, 8088, and 6300. If another process is using one of these ports, stop it before starting the devnet:
165
+
166
+ ```bash
167
+ lsof -i :9944
168
+ lsof -i :8088
169
+ lsof -i :6300
170
+ ```
171
+
172
+ ### Containers are unhealthy
173
+
174
+ Run the health check to see which service is not responding:
175
+
176
+ ```bash
177
+ npx midnight-devnet health
178
+ ```
179
+
180
+ Check the logs for the failing service:
181
+
182
+ ```bash
183
+ npx midnight-devnet logs --service node
184
+ npx midnight-devnet logs --service indexer
185
+ npx midnight-devnet logs --service proof-server
186
+ ```
187
+
188
+ ### Clean restart
189
+
190
+ If the network is in a broken state, do a clean restart that removes all volumes:
191
+
192
+ ```bash
193
+ npx midnight-devnet restart --remove-volumes
194
+ ```
195
+
196
+ This removes all chain data and starts fresh.
197
+
198
+ ### Wallet sync takes too long
199
+
200
+ The master wallet must synchronize with the chain on first start. This can take 10--30 seconds depending on your machine. The CLI and MCP server wait for synchronization automatically.
201
+
202
+ ### "Network is not running" error
203
+
204
+ The tool detects running containers on startup. If you stopped the containers externally (e.g. via `docker compose down`), run `start` again:
205
+
206
+ ```bash
207
+ npx midnight-devnet start
208
+ ```
209
+
210
+ ## License
211
+
212
+ MIT
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ import type { NetworkManager } from '../../core/network-manager.js';
3
+ export declare function registerAccountCommands(program: Command, manager: NetworkManager): void;
@@ -0,0 +1,38 @@
1
+ import { generateAccounts, generateAndFundAccounts, writeAccountsFile } from '../../core/accounts.js';
2
+ export function registerAccountCommands(program, manager) {
3
+ program
4
+ .command('generate-accounts')
5
+ .description('Generate random test accounts')
6
+ .option('--count <n>', 'Number of accounts', '1')
7
+ .option('--format <type>', 'mnemonic or privateKey', 'mnemonic')
8
+ .option('--output <path>', 'Write to file in accounts.json format')
9
+ .option('--fund', 'Fund accounts from master wallet')
10
+ .option('--register-dust', 'Register DUST for funded accounts')
11
+ .action(async (opts) => {
12
+ const format = opts.format;
13
+ const count = parseInt(opts.count, 10);
14
+ let accounts;
15
+ if (opts.fund) {
16
+ const wallet = await manager.ensureWallet();
17
+ accounts = await generateAndFundAccounts(wallet, manager.config, {
18
+ format,
19
+ count,
20
+ fund: true,
21
+ registerDust: opts.registerDust ?? false,
22
+ });
23
+ }
24
+ else {
25
+ accounts = await generateAccounts({ format, count });
26
+ }
27
+ if (opts.output) {
28
+ await writeAccountsFile(opts.output, accounts);
29
+ console.log(`Accounts written to ${opts.output}`);
30
+ }
31
+ console.table(accounts.map((a) => ({
32
+ Name: a.name,
33
+ Address: a.address || '(generated on fund)',
34
+ ...(a.mnemonic ? { Mnemonic: a.mnemonic.split(' ').slice(0, 3).join(' ') + '...' } : {}),
35
+ })));
36
+ });
37
+ }
38
+ //# sourceMappingURL=accounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../../src/cli/commands/accounts.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAEtG,MAAM,UAAU,uBAAuB,CAAC,OAAgB,EAAE,OAAuB;IAC/E,OAAO;SACJ,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,+BAA+B,CAAC;SAC5C,MAAM,CAAC,aAAa,EAAE,oBAAoB,EAAE,GAAG,CAAC;SAChD,MAAM,CAAC,iBAAiB,EAAE,wBAAwB,EAAE,UAAU,CAAC;SAC/D,MAAM,CAAC,iBAAiB,EAAE,uCAAuC,CAAC;SAClE,MAAM,CAAC,QAAQ,EAAE,kCAAkC,CAAC;SACpD,MAAM,CAAC,iBAAiB,EAAE,mCAAmC,CAAC;SAC9D,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAmC,CAAC;QACxD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAEvC,IAAI,QAAQ,CAAC;QACb,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;YAC5C,QAAQ,GAAG,MAAM,uBAAuB,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;gBAC/D,MAAM;gBACN,KAAK;gBACL,IAAI,EAAE,IAAI;gBACV,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,KAAK;aACzC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,MAAM,gBAAgB,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,iBAAiB,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACpD,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACjC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,qBAAqB;YAC3C,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACzF,CAAC,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ import type { NetworkManager } from '../../core/network-manager.js';
3
+ export declare function registerNetworkCommands(program: Command, manager: NetworkManager): void;
@@ -0,0 +1,84 @@
1
+ import { checkAllHealth } from '../../core/health.js';
2
+ export function registerNetworkCommands(program, manager) {
3
+ program
4
+ .command('start')
5
+ .description('Start the local Midnight development network')
6
+ .option('--pull', 'Pull latest Docker images before starting')
7
+ .action(async (opts) => {
8
+ console.log('Starting Midnight local devnet...');
9
+ const result = await manager.start({ pull: opts.pull ?? false });
10
+ if (result === 'already-running') {
11
+ console.log('Network is already running.');
12
+ }
13
+ else {
14
+ console.log('Network is ready.');
15
+ }
16
+ const services = await manager.getServices();
17
+ console.table(services.map((s) => ({ Service: s.name, Port: s.port, URL: s.url, Status: s.status })));
18
+ });
19
+ program
20
+ .command('stop')
21
+ .description('Stop the local Midnight development network')
22
+ .option('--remove-volumes', 'Remove volumes and containers')
23
+ .action(async (opts) => {
24
+ await manager.stop({ removeVolumes: opts.removeVolumes ?? false });
25
+ console.log('Network stopped.');
26
+ });
27
+ program
28
+ .command('restart')
29
+ .description('Restart the network')
30
+ .option('--pull', 'Pull latest Docker images')
31
+ .option('--remove-volumes', 'Remove volumes for clean restart')
32
+ .action(async (opts) => {
33
+ await manager.restart({
34
+ pull: opts.pull ?? false,
35
+ removeVolumes: opts.removeVolumes ?? false,
36
+ });
37
+ console.log('Network restarted and ready.');
38
+ });
39
+ program
40
+ .command('status')
41
+ .description('Show network status')
42
+ .action(async () => {
43
+ try {
44
+ const services = await manager.getServices();
45
+ if (services.length === 0) {
46
+ console.log('Network is not running.');
47
+ return;
48
+ }
49
+ console.table(services.map((s) => ({
50
+ Service: s.name,
51
+ Status: s.status,
52
+ Port: s.port,
53
+ URL: s.url,
54
+ })));
55
+ }
56
+ catch {
57
+ console.log('Network is not running.');
58
+ }
59
+ });
60
+ program
61
+ .command('logs')
62
+ .description('Show network service logs')
63
+ .option('--service <name>', 'Specific service (node, indexer, proof-server)')
64
+ .option('--lines <n>', 'Number of lines', '50')
65
+ .action(async (opts) => {
66
+ const logs = await manager.getLogs({
67
+ service: opts.service,
68
+ lines: parseInt(opts.lines, 10),
69
+ });
70
+ console.log(logs);
71
+ });
72
+ program
73
+ .command('health')
74
+ .description('Check health of all services')
75
+ .action(async () => {
76
+ const health = await checkAllHealth(manager.config);
77
+ console.table({
78
+ Node: { Healthy: health.node.healthy, 'Response (ms)': health.node.responseTime },
79
+ Indexer: { Healthy: health.indexer.healthy, 'Response (ms)': health.indexer.responseTime },
80
+ 'Proof Server': { Healthy: health.proofServer.healthy, 'Response (ms)': health.proofServer.responseTime },
81
+ });
82
+ });
83
+ }
84
+ //# sourceMappingURL=network.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"network.js","sourceRoot":"","sources":["../../../src/cli/commands/network.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ import type { NetworkManager } from '../../core/network-manager.js';
3
+ export declare function registerWalletCommands(program: Command, manager: NetworkManager): void;
@@ -0,0 +1,49 @@
1
+ import { getWalletBalances } from '../../core/wallet.js';
2
+ import { fundAccount, fundAccountsFromFile } from '../../core/funding.js';
3
+ export function registerWalletCommands(program, manager) {
4
+ program
5
+ .command('balances')
6
+ .description('Show master wallet balances')
7
+ .action(async () => {
8
+ const wallet = await manager.ensureWallet();
9
+ const b = await getWalletBalances(wallet);
10
+ console.table({
11
+ Unshielded: b.unshielded.toString(),
12
+ Shielded: b.shielded.toString(),
13
+ DUST: b.dust.toString(),
14
+ Total: b.total.toString(),
15
+ });
16
+ });
17
+ program
18
+ .command('fund <address>')
19
+ .description('Fund an address with NIGHT tokens')
20
+ .option('--amount <n>', 'Amount in NIGHT (default: 50000)')
21
+ .action(async (address, opts) => {
22
+ const wallet = await manager.ensureWallet();
23
+ let amount;
24
+ if (opts.amount) {
25
+ if (!/^[1-9]\d*$/.test(opts.amount)) {
26
+ console.error('Error: --amount must be a positive whole number of NIGHT tokens.');
27
+ process.exitCode = 1;
28
+ return;
29
+ }
30
+ amount = BigInt(opts.amount) * 10n ** 6n;
31
+ }
32
+ const result = await fundAccount(wallet, address, amount);
33
+ console.log(`Funded ${result.address} with ${result.amount} NIGHT (tx: ${result.txHash})`);
34
+ });
35
+ program
36
+ .command('fund-file <path>')
37
+ .description('Fund accounts from an accounts.json file')
38
+ .action(async (filePath) => {
39
+ const wallet = await manager.ensureWallet();
40
+ const results = await fundAccountsFromFile(wallet, filePath, manager.config);
41
+ console.table(results.map((r) => ({
42
+ Name: r.name,
43
+ Address: r.address,
44
+ Amount: r.amount.toString(),
45
+ DUST: r.hasDust ? 'Yes' : 'No',
46
+ })));
47
+ });
48
+ }
49
+ //# sourceMappingURL=wallet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wallet.js","sourceRoot":"","sources":["../../../src/cli/commands/wallet.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAE1E,MAAM,UAAU,sBAAsB,CAAC,OAAgB,EAAE,OAAuB;IAC9E,OAAO;SACJ,OAAO,CAAC,UAAU,CAAC;SACnB,WAAW,CAAC,6BAA6B,CAAC;SAC1C,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;QAC5C,MAAM,CAAC,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC1C,OAAO,CAAC,KAAK,CAAC;YACZ,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,EAAE;YACnC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE;YAC/B,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE;YACvB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE;SAC1B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,gBAAgB,CAAC;SACzB,WAAW,CAAC,mCAAmC,CAAC;SAChD,MAAM,CAAC,cAAc,EAAE,kCAAkC,CAAC;SAC1D,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,IAAI,EAAE,EAAE;QACtC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;QAC5C,IAAI,MAA0B,CAAC;QAC/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACpC,OAAO,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;gBAClF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YACD,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC;QAC3C,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,eAAe,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAC7F,CAAC,CAAC,CAAC;IAEL,OAAO;SACJ,OAAO,CAAC,kBAAkB,CAAC;SAC3B,WAAW,CAAC,0CAA0C,CAAC;SACvD,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,EAAE;QACjC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAC7E,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAChC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;YAC3B,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;SAC/B,CAAC,CAAC,CAAC,CAAC;IACP,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { NetworkManager } from '../core/network-manager.js';
2
+ export declare function startInteractiveMode(manager: NetworkManager): Promise<void>;
@@ -0,0 +1,90 @@
1
+ import { stdin as input, stdout as output } from 'node:process';
2
+ import { createInterface } from 'node:readline/promises';
3
+ import { fundAccount, fundAccountsFromFile } from '../core/funding.js';
4
+ import { generateAccounts, writeAccountsFile } from '../core/accounts.js';
5
+ import { getWalletBalances } from '../core/wallet.js';
6
+ export async function startInteractiveMode(manager) {
7
+ const rli = createInterface({ input, output });
8
+ console.log('Midnight Local Devnet — Interactive Mode\n');
9
+ if (manager.getStatus() === 'running') {
10
+ console.log('Detected running network. Initializing wallet...');
11
+ await manager.ensureWallet();
12
+ console.log('Ready.\n');
13
+ }
14
+ else {
15
+ console.log('Starting network...');
16
+ await manager.start({ pull: false });
17
+ console.log('Network ready.\n');
18
+ }
19
+ const showMenu = () => {
20
+ console.log('\nChoose an option:');
21
+ console.log(' [1] Fund accounts from config file (NIGHT + DUST)');
22
+ console.log(' [2] Fund account by address (NIGHT only)');
23
+ console.log(' [3] Generate test accounts');
24
+ console.log(' [4] Display master wallet balances');
25
+ console.log(' [5] Show network status');
26
+ console.log(' [6] Exit');
27
+ };
28
+ let running = true;
29
+ while (running) {
30
+ showMenu();
31
+ const choice = await rli.question('> ');
32
+ try {
33
+ switch (choice.trim()) {
34
+ case '1': {
35
+ const path = await rli.question('Path to accounts JSON file: ');
36
+ const wallet = await manager.ensureWallet();
37
+ const results = await fundAccountsFromFile(wallet, path.trim(), manager.config);
38
+ console.table(results.map((r) => ({ Name: r.name, Address: r.address, DUST: r.hasDust })));
39
+ break;
40
+ }
41
+ case '2': {
42
+ const addr = await rli.question('Bech32 address: ');
43
+ const wallet = await manager.ensureWallet();
44
+ await fundAccount(wallet, addr.trim());
45
+ console.log('Funded.');
46
+ break;
47
+ }
48
+ case '3': {
49
+ const countStr = await rli.question('How many accounts? [1]: ');
50
+ const count = parseInt(countStr.trim() || '1', 10);
51
+ const accounts = await generateAccounts({ format: 'mnemonic', count });
52
+ const outPath = await rli.question('Save to file? (path or empty to skip): ');
53
+ if (outPath.trim()) {
54
+ await writeAccountsFile(outPath.trim(), accounts);
55
+ }
56
+ console.table(accounts.map((a) => ({ Name: a.name, Mnemonic: a.mnemonic })));
57
+ break;
58
+ }
59
+ case '4': {
60
+ const wallet = await manager.ensureWallet();
61
+ const b = await getWalletBalances(wallet);
62
+ console.table({
63
+ Unshielded: b.unshielded.toString(),
64
+ Shielded: b.shielded.toString(),
65
+ DUST: b.dust.toString(),
66
+ });
67
+ break;
68
+ }
69
+ case '5': {
70
+ const services = await manager.getServices();
71
+ console.table(services);
72
+ break;
73
+ }
74
+ case '6':
75
+ running = false;
76
+ break;
77
+ default:
78
+ console.log('Invalid option.');
79
+ }
80
+ }
81
+ catch (err) {
82
+ console.error('Error:', err instanceof Error ? err.message : err);
83
+ }
84
+ }
85
+ console.log('\nShutting down wallet (containers left running)...');
86
+ await manager.shutdown();
87
+ rli.close();
88
+ console.log('Goodbye.');
89
+ }
90
+ //# sourceMappingURL=interactive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../src/cli/interactive.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { NetworkManager } from './core/network-manager.js';
4
+ import { registerNetworkCommands } from './cli/commands/network.js';
5
+ import { registerWalletCommands } from './cli/commands/wallet.js';
6
+ import { registerAccountCommands } from './cli/commands/accounts.js';
7
+ import { startInteractiveMode } from './cli/interactive.js';
8
+ import { createLogger } from './core/logger.js';
9
+ import { setLogger as setWalletLogger } from './core/wallet.js';
10
+ import { setLogger as setFundingLogger } from './core/funding.js';
11
+ import { setLogger as setAccountsLogger } from './core/accounts.js';
12
+ const manager = new NetworkManager();
13
+ const logger = createLogger();
14
+ setWalletLogger(logger);
15
+ setFundingLogger(logger);
16
+ setAccountsLogger(logger);
17
+ manager.setLogger(logger);
18
+ // Detect existing containers before running any command
19
+ await manager.detectRunningNetwork();
20
+ // Graceful shutdown on Ctrl+C
21
+ const shutdown = async () => {
22
+ await manager.shutdown();
23
+ process.exit(0);
24
+ };
25
+ process.on('SIGINT', shutdown);
26
+ process.on('SIGTERM', shutdown);
27
+ const program = new Command();
28
+ program
29
+ .name('midnight-local-devnet')
30
+ .description('Manage a local Midnight development network')
31
+ .version('0.1.0');
32
+ registerNetworkCommands(program, manager);
33
+ registerWalletCommands(program, manager);
34
+ registerAccountCommands(program, manager);
35
+ program
36
+ .command('interactive')
37
+ .description('Start interactive menu mode')
38
+ .action(async () => {
39
+ await startInteractiveMode(manager);
40
+ });
41
+ // No arguments = interactive mode
42
+ if (process.argv.length <= 2) {
43
+ startInteractiveMode(manager).catch(console.error);
44
+ }
45
+ else {
46
+ program.parse();
47
+ }
48
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,SAAS,IAAI,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,EAAE,SAAS,IAAI,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEpE,MAAM,OAAO,GAAG,IAAI,cAAc,EAAE,CAAC;AAErC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;AAC9B,eAAe,CAAC,MAAM,CAAC,CAAC;AACxB,gBAAgB,CAAC,MAAM,CAAC,CAAC;AACzB,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC1B,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;AAE1B,wDAAwD;AACxD,MAAM,OAAO,CAAC,oBAAoB,EAAE,CAAC;AAErC,8BAA8B;AAC9B,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;IAC1B,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;IACzB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC;AACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAEhC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,uBAAuB,CAAC;KAC7B,WAAW,CAAC,6CAA6C,CAAC;KAC1D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,uBAAuB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAC1C,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AACzC,uBAAuB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AAE1C,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,6BAA6B,CAAC;KAC1C,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,oBAAoB,CAAC,OAAO,CAAC,CAAC;AACtC,CAAC,CAAC,CAAC;AAEL,kCAAkC;AAClC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;IAC7B,oBAAoB,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACrD,CAAC;KAAM,CAAC;IACN,OAAO,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { GeneratedAccount, NetworkConfig } from './types.js';
2
+ import type { WalletContext } from './wallet.js';
3
+ import type { Logger } from 'pino';
4
+ export declare function setLogger(l: Logger): void;
5
+ export interface GenerateOptions {
6
+ format: 'mnemonic' | 'privateKey';
7
+ count?: number;
8
+ }
9
+ export declare function generateAccounts(opts: GenerateOptions): Promise<GeneratedAccount[]>;
10
+ export declare function generateAndFundAccounts(masterWallet: WalletContext, config: NetworkConfig, opts: GenerateOptions & {
11
+ fund?: boolean;
12
+ registerDust?: boolean;
13
+ }): Promise<(GeneratedAccount & {
14
+ funded?: boolean;
15
+ dustRegistered?: boolean;
16
+ })[]>;
17
+ export declare function writeAccountsFile(filePath: string, accounts: GeneratedAccount[]): Promise<void>;