@aaronbassett/midnight-local-devnet 0.1.0 → 0.1.2
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.
- package/README.md +52 -22
- package/dist/cli/interactive.js +123 -37
- package/dist/cli/interactive.js.map +1 -1
- package/dist/cli.js +12 -17
- package/dist/cli.js.map +1 -1
- package/dist/core/logger.d.ts +1 -1
- package/dist/core/logger.js +2 -1
- package/dist/core/logger.js.map +1 -1
- package/docker/standalone.yml +1 -1
- package/package.json +10 -4
package/README.md
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
|
-
# midnight-local-devnet
|
|
1
|
+
# @aaronbassett/midnight-local-devnet
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@aaronbassett/midnight-local-devnet)
|
|
2
4
|
|
|
3
5
|
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
6
|
|
|
5
7
|
## Prerequisites
|
|
6
8
|
|
|
7
|
-
- **Node.js >= 22**
|
|
9
|
+
- **Node.js >= 22**
|
|
8
10
|
- **Docker** (Docker Desktop or Docker Engine with Compose v2)
|
|
9
11
|
|
|
10
|
-
## Installation
|
|
11
|
-
|
|
12
|
-
```bash
|
|
13
|
-
npm install
|
|
14
|
-
npm run build
|
|
15
|
-
```
|
|
16
|
-
|
|
17
12
|
## Quick Start
|
|
18
13
|
|
|
19
14
|
### CLI
|
|
@@ -21,34 +16,36 @@ npm run build
|
|
|
21
16
|
Run with no arguments to enter interactive mode:
|
|
22
17
|
|
|
23
18
|
```bash
|
|
24
|
-
npx midnight-devnet
|
|
19
|
+
npx @aaronbassett/midnight-local-devnet
|
|
25
20
|
```
|
|
26
21
|
|
|
27
22
|
Or start the network directly:
|
|
28
23
|
|
|
29
24
|
```bash
|
|
30
|
-
npx midnight-devnet start
|
|
25
|
+
npx @aaronbassett/midnight-local-devnet start
|
|
31
26
|
```
|
|
32
27
|
|
|
33
28
|
### MCP Server
|
|
34
29
|
|
|
35
|
-
Add
|
|
30
|
+
Add to your MCP client configuration (Claude Code, Cursor, Windsurf, etc.):
|
|
36
31
|
|
|
37
32
|
```json
|
|
38
33
|
{
|
|
39
34
|
"mcpServers": {
|
|
40
35
|
"midnight-devnet": {
|
|
41
|
-
"command": "
|
|
42
|
-
"args": ["
|
|
36
|
+
"command": "npx",
|
|
37
|
+
"args": ["-y", "-p", "@aaronbassett/midnight-local-devnet", "midnight-devnet-mcp"]
|
|
43
38
|
}
|
|
44
39
|
}
|
|
45
40
|
}
|
|
46
41
|
```
|
|
47
42
|
|
|
48
|
-
The MCP server communicates over stdio and exposes tools
|
|
43
|
+
The MCP server communicates over stdio and exposes tools and resources that an AI assistant can use to manage the devnet on your behalf.
|
|
49
44
|
|
|
50
45
|
## CLI Command Reference
|
|
51
46
|
|
|
47
|
+
All commands can be run via `npx @aaronbassett/midnight-local-devnet <command>`.
|
|
48
|
+
|
|
52
49
|
| Command | Description | Options |
|
|
53
50
|
|---|---|---|
|
|
54
51
|
| `start` | Start the local Midnight devnet | `--pull` Pull latest Docker images |
|
|
@@ -63,7 +60,7 @@ The MCP server communicates over stdio and exposes tools, resources, and prompts
|
|
|
63
60
|
| `generate-accounts` | Generate random test accounts | `--count <n>`, `--format <mnemonic\|privateKey>`, `--output <path>`, `--fund`, `--register-dust` |
|
|
64
61
|
| `interactive` | Start interactive menu mode | |
|
|
65
62
|
|
|
66
|
-
Running
|
|
63
|
+
Running with no arguments automatically enters interactive mode.
|
|
67
64
|
|
|
68
65
|
## MCP Tool Reference
|
|
69
66
|
|
|
@@ -147,6 +144,35 @@ const config = {
|
|
|
147
144
|
|
|
148
145
|
You can also retrieve this configuration at runtime via the `get-network-config` MCP tool or the `devnet://config` MCP resource.
|
|
149
146
|
|
|
147
|
+
## Development
|
|
148
|
+
|
|
149
|
+
To work on this project locally:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
git clone https://github.com/devrelaicom/midnight-local-devnet.git
|
|
153
|
+
cd midnight-local-devnet
|
|
154
|
+
npm install
|
|
155
|
+
npm run build
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Run the CLI from source:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
node --enable-source-maps dist/cli.js start
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Run the MCP server from source:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
node --enable-source-maps dist/index.js
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Run tests:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
npm test
|
|
174
|
+
```
|
|
175
|
+
|
|
150
176
|
## Troubleshooting
|
|
151
177
|
|
|
152
178
|
### Docker containers fail to start
|
|
@@ -174,15 +200,15 @@ lsof -i :6300
|
|
|
174
200
|
Run the health check to see which service is not responding:
|
|
175
201
|
|
|
176
202
|
```bash
|
|
177
|
-
npx midnight-devnet health
|
|
203
|
+
npx @aaronbassett/midnight-local-devnet health
|
|
178
204
|
```
|
|
179
205
|
|
|
180
206
|
Check the logs for the failing service:
|
|
181
207
|
|
|
182
208
|
```bash
|
|
183
|
-
npx midnight-devnet logs --service node
|
|
184
|
-
npx midnight-devnet logs --service indexer
|
|
185
|
-
npx midnight-devnet logs --service proof-server
|
|
209
|
+
npx @aaronbassett/midnight-local-devnet logs --service node
|
|
210
|
+
npx @aaronbassett/midnight-local-devnet logs --service indexer
|
|
211
|
+
npx @aaronbassett/midnight-local-devnet logs --service proof-server
|
|
186
212
|
```
|
|
187
213
|
|
|
188
214
|
### Clean restart
|
|
@@ -190,7 +216,7 @@ npx midnight-devnet logs --service proof-server
|
|
|
190
216
|
If the network is in a broken state, do a clean restart that removes all volumes:
|
|
191
217
|
|
|
192
218
|
```bash
|
|
193
|
-
npx midnight-devnet restart --remove-volumes
|
|
219
|
+
npx @aaronbassett/midnight-local-devnet restart --remove-volumes
|
|
194
220
|
```
|
|
195
221
|
|
|
196
222
|
This removes all chain data and starts fresh.
|
|
@@ -204,9 +230,13 @@ The master wallet must synchronize with the chain on first start. This can take
|
|
|
204
230
|
The tool detects running containers on startup. If you stopped the containers externally (e.g. via `docker compose down`), run `start` again:
|
|
205
231
|
|
|
206
232
|
```bash
|
|
207
|
-
npx midnight-devnet start
|
|
233
|
+
npx @aaronbassett/midnight-local-devnet start
|
|
208
234
|
```
|
|
209
235
|
|
|
236
|
+
## Acknowledgments
|
|
237
|
+
|
|
238
|
+
This project is based on [midnight-local-network](https://github.com/hbulgarini/midnight-local-network) by [@hbulgarini](https://github.com/hbulgarini). Thank you for the initial version that made this possible.
|
|
239
|
+
|
|
210
240
|
## License
|
|
211
241
|
|
|
212
242
|
MIT
|
package/dist/cli/interactive.js
CHANGED
|
@@ -1,77 +1,163 @@
|
|
|
1
1
|
import { stdin as input, stdout as output } from 'node:process';
|
|
2
2
|
import { createInterface } from 'node:readline/promises';
|
|
3
3
|
import { fundAccount, fundAccountsFromFile } from '../core/funding.js';
|
|
4
|
-
import { generateAccounts, writeAccountsFile } from '../core/accounts.js';
|
|
4
|
+
import { generateAccounts, generateAndFundAccounts, writeAccountsFile } from '../core/accounts.js';
|
|
5
5
|
import { getWalletBalances } from '../core/wallet.js';
|
|
6
|
+
import { checkAllHealth } from '../core/health.js';
|
|
7
|
+
const MENU = `
|
|
8
|
+
[1] Start network
|
|
9
|
+
[2] Stop network
|
|
10
|
+
[3] Restart network
|
|
11
|
+
[4] Network status
|
|
12
|
+
[5] Service logs
|
|
13
|
+
[6] Health check
|
|
14
|
+
[7] Wallet balances
|
|
15
|
+
[8] Fund account by address
|
|
16
|
+
[9] Fund accounts from file
|
|
17
|
+
[10] Generate test accounts
|
|
18
|
+
[0] Exit
|
|
19
|
+
`;
|
|
6
20
|
export async function startInteractiveMode(manager) {
|
|
7
21
|
const rli = createInterface({ input, output });
|
|
8
22
|
console.log('Midnight Local Devnet — Interactive Mode\n');
|
|
9
23
|
if (manager.getStatus() === 'running') {
|
|
10
24
|
console.log('Detected running network. Initializing wallet...');
|
|
11
25
|
await manager.ensureWallet();
|
|
12
|
-
console.log('Ready
|
|
26
|
+
console.log('Ready.');
|
|
13
27
|
}
|
|
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
28
|
let running = true;
|
|
29
29
|
while (running) {
|
|
30
|
-
|
|
30
|
+
console.log(MENU);
|
|
31
31
|
const choice = await rli.question('> ');
|
|
32
32
|
try {
|
|
33
33
|
switch (choice.trim()) {
|
|
34
34
|
case '1': {
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
console.log('Starting network...');
|
|
36
|
+
const result = await manager.start({ pull: false });
|
|
37
|
+
if (result === 'already-running') {
|
|
38
|
+
console.log('Network is already running.');
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
console.log('Network is ready.');
|
|
42
|
+
}
|
|
43
|
+
const services = await manager.getServices();
|
|
44
|
+
console.table(services.map((s) => ({ Service: s.name, Port: s.port, URL: s.url, Status: s.status })));
|
|
39
45
|
break;
|
|
40
46
|
}
|
|
41
47
|
case '2': {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
await fundAccount(wallet, addr.trim());
|
|
45
|
-
console.log('Funded.');
|
|
48
|
+
await manager.stop({ removeVolumes: false });
|
|
49
|
+
console.log('Network stopped.');
|
|
46
50
|
break;
|
|
47
51
|
}
|
|
48
52
|
case '3': {
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
await writeAccountsFile(outPath.trim(), accounts);
|
|
55
|
-
}
|
|
56
|
-
console.table(accounts.map((a) => ({ Name: a.name, Mnemonic: a.mnemonic })));
|
|
53
|
+
const volAnswer = await rli.question('Remove volumes for clean restart? [y/N]: ');
|
|
54
|
+
const removeVolumes = volAnswer.trim().toLowerCase() === 'y';
|
|
55
|
+
console.log('Restarting...');
|
|
56
|
+
await manager.restart({ pull: false, removeVolumes });
|
|
57
|
+
console.log('Network restarted and ready.');
|
|
57
58
|
break;
|
|
58
59
|
}
|
|
59
60
|
case '4': {
|
|
61
|
+
try {
|
|
62
|
+
const services = await manager.getServices();
|
|
63
|
+
if (services.length === 0) {
|
|
64
|
+
console.log('Network is not running.');
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
console.table(services.map((s) => ({ Service: s.name, Status: s.status, Port: s.port, URL: s.url })));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
console.log('Network is not running.');
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case '5': {
|
|
76
|
+
const svc = await rli.question('Service (node, indexer, proof-server) or all [all]: ');
|
|
77
|
+
const lines = await rli.question('Number of lines [50]: ');
|
|
78
|
+
const svcName = svc.trim();
|
|
79
|
+
const logs = await manager.getLogs({
|
|
80
|
+
service: svcName || undefined,
|
|
81
|
+
lines: parseInt(lines.trim() || '50', 10),
|
|
82
|
+
});
|
|
83
|
+
console.log(logs);
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case '6': {
|
|
87
|
+
const health = await checkAllHealth(manager.config);
|
|
88
|
+
console.table({
|
|
89
|
+
Node: { Healthy: health.node.healthy, 'Response (ms)': health.node.responseTime },
|
|
90
|
+
Indexer: { Healthy: health.indexer.healthy, 'Response (ms)': health.indexer.responseTime },
|
|
91
|
+
'Proof Server': { Healthy: health.proofServer.healthy, 'Response (ms)': health.proofServer.responseTime },
|
|
92
|
+
});
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
case '7': {
|
|
60
96
|
const wallet = await manager.ensureWallet();
|
|
61
97
|
const b = await getWalletBalances(wallet);
|
|
62
98
|
console.table({
|
|
63
99
|
Unshielded: b.unshielded.toString(),
|
|
64
100
|
Shielded: b.shielded.toString(),
|
|
65
101
|
DUST: b.dust.toString(),
|
|
102
|
+
Total: b.total.toString(),
|
|
66
103
|
});
|
|
67
104
|
break;
|
|
68
105
|
}
|
|
69
|
-
case '
|
|
70
|
-
const
|
|
71
|
-
|
|
106
|
+
case '8': {
|
|
107
|
+
const addr = await rli.question('Bech32 address: ');
|
|
108
|
+
const amountStr = await rli.question('Amount in NIGHT [50000]: ');
|
|
109
|
+
const wallet = await manager.ensureWallet();
|
|
110
|
+
let amount;
|
|
111
|
+
if (amountStr.trim()) {
|
|
112
|
+
amount = BigInt(amountStr.trim()) * 10n ** 6n;
|
|
113
|
+
}
|
|
114
|
+
const result = await fundAccount(wallet, addr.trim(), amount);
|
|
115
|
+
console.log(`Funded ${result.address} with ${result.amount} NIGHT (tx: ${result.txHash})`);
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
case '9': {
|
|
119
|
+
const filePath = await rli.question('Path to accounts JSON file: ');
|
|
120
|
+
const wallet = await manager.ensureWallet();
|
|
121
|
+
const results = await fundAccountsFromFile(wallet, filePath.trim(), manager.config);
|
|
122
|
+
console.table(results.map((r) => ({
|
|
123
|
+
Name: r.name,
|
|
124
|
+
Address: r.address,
|
|
125
|
+
Amount: r.amount.toString(),
|
|
126
|
+
DUST: r.hasDust ? 'Yes' : 'No',
|
|
127
|
+
})));
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
case '10': {
|
|
131
|
+
const countStr = await rli.question('How many accounts? [1]: ');
|
|
132
|
+
const count = parseInt(countStr.trim() || '1', 10);
|
|
133
|
+
const fundAnswer = await rli.question('Fund from master wallet? [y/N]: ');
|
|
134
|
+
const shouldFund = fundAnswer.trim().toLowerCase() === 'y';
|
|
135
|
+
let accounts;
|
|
136
|
+
if (shouldFund) {
|
|
137
|
+
const wallet = await manager.ensureWallet();
|
|
138
|
+
accounts = await generateAndFundAccounts(wallet, manager.config, {
|
|
139
|
+
format: 'mnemonic',
|
|
140
|
+
count,
|
|
141
|
+
fund: true,
|
|
142
|
+
registerDust: true,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
accounts = await generateAccounts({ format: 'mnemonic', count });
|
|
147
|
+
}
|
|
148
|
+
const outPath = await rli.question('Save to file? (path or enter to skip): ');
|
|
149
|
+
if (outPath.trim()) {
|
|
150
|
+
await writeAccountsFile(outPath.trim(), accounts);
|
|
151
|
+
console.log(`Accounts written to ${outPath.trim()}`);
|
|
152
|
+
}
|
|
153
|
+
console.table(accounts.map((a) => ({
|
|
154
|
+
Name: a.name,
|
|
155
|
+
Address: a.address || '(not funded)',
|
|
156
|
+
Mnemonic: a.mnemonic ? a.mnemonic.split(' ').slice(0, 3).join(' ') + '...' : 'N/A',
|
|
157
|
+
})));
|
|
72
158
|
break;
|
|
73
159
|
}
|
|
74
|
-
case '
|
|
160
|
+
case '0':
|
|
75
161
|
running = false;
|
|
76
162
|
break;
|
|
77
163
|
default:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../src/cli/interactive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,KAAK,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"interactive.js","sourceRoot":"","sources":["../../src/cli/interactive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,KAAK,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACnG,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,IAAI,GAAG;;;;;;;;;;;;CAYZ,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAuB;IAChE,MAAM,GAAG,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IAE/C,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAE1D,IAAI,OAAO,CAAC,SAAS,EAAE,KAAK,SAAS,EAAE,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxB,CAAC;IAED,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,OAAO,OAAO,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAExC,IAAI,CAAC;YACH,QAAQ,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gBACtB,KAAK,GAAG,CAAC,CAAC,CAAC;oBACT,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;oBACnC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;oBACpD,IAAI,MAAM,KAAK,iBAAiB,EAAE,CAAC;wBACjC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;oBAC7C,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC;oBACnC,CAAC;oBACD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;oBAC7C,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;oBACtG,MAAM;gBACR,CAAC;gBACD,KAAK,GAAG,CAAC,CAAC,CAAC;oBACT,MAAM,OAAO,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;oBAC7C,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;oBAChC,MAAM;gBACR,CAAC;gBACD,KAAK,GAAG,CAAC,CAAC,CAAC;oBACT,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,2CAA2C,CAAC,CAAC;oBAClF,MAAM,aAAa,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC;oBAC7D,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;oBAC7B,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;oBACtD,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;oBAC5C,MAAM;gBACR,CAAC;gBACD,KAAK,GAAG,CAAC,CAAC,CAAC;oBACT,IAAI,CAAC;wBACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;wBAC7C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;4BAC1B,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;wBACzC,CAAC;6BAAM,CAAC;4BACN,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;wBACxG,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;oBACzC,CAAC;oBACD,MAAM;gBACR,CAAC;gBACD,KAAK,GAAG,CAAC,CAAC,CAAC;oBACT,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,sDAAsD,CAAC,CAAC;oBACvF,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,wBAAwB,CAAC,CAAC;oBAC3D,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAqD,CAAC;oBAC9E,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC;wBACjC,OAAO,EAAE,OAAO,IAAI,SAAS;wBAC7B,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC;qBAC1C,CAAC,CAAC;oBACH,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAClB,MAAM;gBACR,CAAC;gBACD,KAAK,GAAG,CAAC,CAAC,CAAC;oBACT,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;oBACpD,OAAO,CAAC,KAAK,CAAC;wBACZ,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE;wBACjF,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY,EAAE;wBAC1F,cAAc,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,CAAC,WAAW,CAAC,YAAY,EAAE;qBAC1G,CAAC,CAAC;oBACH,MAAM;gBACR,CAAC;gBACD,KAAK,GAAG,CAAC,CAAC,CAAC;oBACT,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;oBAC5C,MAAM,CAAC,GAAG,MAAM,iBAAiB,CAAC,MAAM,CAAC,CAAC;oBAC1C,OAAO,CAAC,KAAK,CAAC;wBACZ,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,EAAE;wBACnC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE;wBAC/B,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE;wBACvB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE;qBAC1B,CAAC,CAAC;oBACH,MAAM;gBACR,CAAC;gBACD,KAAK,GAAG,CAAC,CAAC,CAAC;oBACT,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;oBACpD,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,2BAA2B,CAAC,CAAC;oBAClE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;oBAC5C,IAAI,MAA0B,CAAC;oBAC/B,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;wBACrB,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC;oBAChD,CAAC;oBACD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;oBAC9D,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,eAAe,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;oBAC3F,MAAM;gBACR,CAAC;gBACD,KAAK,GAAG,CAAC,CAAC,CAAC;oBACT,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,8BAA8B,CAAC,CAAC;oBACpE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;oBAC5C,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;oBACpF,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBAChC,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,OAAO,EAAE,CAAC,CAAC,OAAO;wBAClB,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;wBAC3B,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;qBAC/B,CAAC,CAAC,CAAC,CAAC;oBACL,MAAM;gBACR,CAAC;gBACD,KAAK,IAAI,CAAC,CAAC,CAAC;oBACV,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAC;oBAChE,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;oBACnD,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,kCAAkC,CAAC,CAAC;oBAC1E,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC;oBAE3D,IAAI,QAAQ,CAAC;oBACb,IAAI,UAAU,EAAE,CAAC;wBACf,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,YAAY,EAAE,CAAC;wBAC5C,QAAQ,GAAG,MAAM,uBAAuB,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;4BAC/D,MAAM,EAAE,UAAU;4BAClB,KAAK;4BACL,IAAI,EAAE,IAAI;4BACV,YAAY,EAAE,IAAI;yBACnB,CAAC,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACN,QAAQ,GAAG,MAAM,gBAAgB,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;oBACnE,CAAC;oBAED,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,yCAAyC,CAAC,CAAC;oBAC9E,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;wBACnB,MAAM,iBAAiB,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC;wBAClD,OAAO,CAAC,GAAG,CAAC,uBAAuB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBACvD,CAAC;oBACD,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;wBACjC,IAAI,EAAE,CAAC,CAAC,IAAI;wBACZ,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,cAAc;wBACpC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK;qBACnF,CAAC,CAAC,CAAC,CAAC;oBACL,MAAM;gBACR,CAAC;gBACD,KAAK,GAAG;oBACN,OAAO,GAAG,KAAK,CAAC;oBAChB,MAAM;gBACR;oBACE,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;IACnE,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC;IACzB,GAAG,CAAC,KAAK,EAAE,CAAC;IACZ,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAC1B,CAAC"}
|
package/dist/cli.js
CHANGED
|
@@ -10,7 +10,9 @@ import { setLogger as setWalletLogger } from './core/wallet.js';
|
|
|
10
10
|
import { setLogger as setFundingLogger } from './core/funding.js';
|
|
11
11
|
import { setLogger as setAccountsLogger } from './core/accounts.js';
|
|
12
12
|
const manager = new NetworkManager();
|
|
13
|
-
const
|
|
13
|
+
const isInteractive = process.argv.length <= 2 || process.argv[2] === 'interactive';
|
|
14
|
+
// In interactive mode, send logs to stderr so they don't stomp on the readline prompt
|
|
15
|
+
const logger = createLogger('info', isInteractive ? process.stderr : process.stdout);
|
|
14
16
|
setWalletLogger(logger);
|
|
15
17
|
setFundingLogger(logger);
|
|
16
18
|
setAccountsLogger(logger);
|
|
@@ -24,25 +26,18 @@ const shutdown = async () => {
|
|
|
24
26
|
};
|
|
25
27
|
process.on('SIGINT', shutdown);
|
|
26
28
|
process.on('SIGTERM', shutdown);
|
|
27
|
-
|
|
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) {
|
|
29
|
+
if (isInteractive) {
|
|
43
30
|
startInteractiveMode(manager).catch(console.error);
|
|
44
31
|
}
|
|
45
32
|
else {
|
|
33
|
+
const program = new Command();
|
|
34
|
+
program
|
|
35
|
+
.name('midnight-local-devnet')
|
|
36
|
+
.description('Manage a local Midnight development network')
|
|
37
|
+
.version('0.1.1');
|
|
38
|
+
registerNetworkCommands(program, manager);
|
|
39
|
+
registerWalletCommands(program, manager);
|
|
40
|
+
registerAccountCommands(program, manager);
|
|
46
41
|
program.parse();
|
|
47
42
|
}
|
|
48
43
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +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;
|
|
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,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC;AAEpF,sFAAsF;AACtF,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACrF,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,IAAI,aAAa,EAAE,CAAC;IAClB,oBAAoB,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACrD,CAAC;KAAM,CAAC;IACN,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,uBAAuB,CAAC;SAC7B,WAAW,CAAC,6CAA6C,CAAC;SAC1D,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,uBAAuB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1C,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzC,uBAAuB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAE1C,OAAO,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC"}
|
package/dist/core/logger.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import pino from 'pino';
|
|
2
|
-
export declare function createLogger(level?: string): pino.Logger;
|
|
2
|
+
export declare function createLogger(level?: string, destination?: NodeJS.WritableStream): pino.Logger;
|
package/dist/core/logger.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// src/core/logger.ts
|
|
2
2
|
import pino from 'pino';
|
|
3
|
-
export function createLogger(level = 'info') {
|
|
3
|
+
export function createLogger(level = 'info', destination = process.stdout) {
|
|
4
4
|
return pino({
|
|
5
5
|
level,
|
|
6
6
|
transport: {
|
|
@@ -9,6 +9,7 @@ export function createLogger(level = 'info') {
|
|
|
9
9
|
colorize: true,
|
|
10
10
|
translateTime: 'SYS:standard',
|
|
11
11
|
ignore: 'pid,hostname',
|
|
12
|
+
destination: destination === process.stderr ? 2 : 1,
|
|
12
13
|
},
|
|
13
14
|
},
|
|
14
15
|
});
|
package/dist/core/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,UAAU,YAAY,CAAC,QAAgB,MAAM;
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,UAAU,YAAY,CAAC,QAAgB,MAAM,EAAE,cAAqC,OAAO,CAAC,MAAM;IACtG,OAAO,IAAI,CAAC;QACV,KAAK;QACL,SAAS,EAAE;YACT,MAAM,EAAE,aAAa;YACrB,OAAO,EAAE;gBACP,QAAQ,EAAE,IAAI;gBACd,aAAa,EAAE,cAAc;gBAC7B,MAAM,EAAE,cAAc;gBACtB,WAAW,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;aACpD;SACF;KACF,CAAC,CAAC;AACL,CAAC"}
|
package/docker/standalone.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aaronbassett/midnight-local-devnet",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Local Midnight development network manager — CLI and MCP server",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/devrelaicom/midnight-local-devnet.git"
|
|
9
9
|
},
|
|
10
|
-
"keywords": [
|
|
10
|
+
"keywords": [
|
|
11
|
+
"midnight",
|
|
12
|
+
"blockchain",
|
|
13
|
+
"devnet",
|
|
14
|
+
"mcp",
|
|
15
|
+
"development"
|
|
16
|
+
],
|
|
11
17
|
"publishConfig": {
|
|
12
18
|
"access": "public"
|
|
13
19
|
},
|
|
@@ -21,8 +27,8 @@
|
|
|
21
27
|
"node": ">=22.0.0"
|
|
22
28
|
},
|
|
23
29
|
"bin": {
|
|
24
|
-
"midnight-local-devnet": "
|
|
25
|
-
"midnight-devnet-mcp": "
|
|
30
|
+
"midnight-local-devnet": "dist/cli.js",
|
|
31
|
+
"midnight-devnet-mcp": "dist/index.js"
|
|
26
32
|
},
|
|
27
33
|
"scripts": {
|
|
28
34
|
"build": "tsc",
|