@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.
- package/LICENSE +21 -0
- package/README.md +212 -0
- package/dist/cli/commands/accounts.d.ts +3 -0
- package/dist/cli/commands/accounts.js +38 -0
- package/dist/cli/commands/accounts.js.map +1 -0
- package/dist/cli/commands/network.d.ts +3 -0
- package/dist/cli/commands/network.js +84 -0
- package/dist/cli/commands/network.js.map +1 -0
- package/dist/cli/commands/wallet.d.ts +3 -0
- package/dist/cli/commands/wallet.js +49 -0
- package/dist/cli/commands/wallet.js.map +1 -0
- package/dist/cli/interactive.d.ts +2 -0
- package/dist/cli/interactive.js +90 -0
- package/dist/cli/interactive.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +48 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/accounts.d.ts +17 -0
- package/dist/core/accounts.js +80 -0
- package/dist/core/accounts.js.map +1 -0
- package/dist/core/config.d.ts +12 -0
- package/dist/core/config.js +22 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/docker.d.ts +13 -0
- package/dist/core/docker.js +101 -0
- package/dist/core/docker.js.map +1 -0
- package/dist/core/funding.d.ts +15 -0
- package/dist/core/funding.js +105 -0
- package/dist/core/funding.js.map +1 -0
- package/dist/core/health.d.ts +13 -0
- package/dist/core/health.js +34 -0
- package/dist/core/health.js.map +1 -0
- package/dist/core/logger.d.ts +2 -0
- package/dist/core/logger.js +16 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/network-manager.d.ts +31 -0
- package/dist/core/network-manager.js +101 -0
- package/dist/core/network-manager.js.map +1 -0
- package/dist/core/types.d.ts +51 -0
- package/dist/core/types.js +11 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/wallet.d.ts +23 -0
- package/dist/core/wallet.js +163 -0
- package/dist/core/wallet.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/resources/config.d.ts +3 -0
- package/dist/mcp/resources/config.js +28 -0
- package/dist/mcp/resources/config.js.map +1 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.js +28 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/accounts.d.ts +3 -0
- package/dist/mcp/tools/accounts.js +28 -0
- package/dist/mcp/tools/accounts.js.map +1 -0
- package/dist/mcp/tools/funding.d.ts +3 -0
- package/dist/mcp/tools/funding.js +59 -0
- package/dist/mcp/tools/funding.js.map +1 -0
- package/dist/mcp/tools/health.d.ts +3 -0
- package/dist/mcp/tools/health.js +19 -0
- package/dist/mcp/tools/health.js.map +1 -0
- package/dist/mcp/tools/network.d.ts +3 -0
- package/dist/mcp/tools/network.js +64 -0
- package/dist/mcp/tools/network.js.map +1 -0
- package/dist/mcp/tools/wallet.d.ts +3 -0
- package/dist/mcp/tools/wallet.js +19 -0
- package/dist/mcp/tools/wallet.js.map +1 -0
- package/docker/standalone.env +5 -0
- package/docker/standalone.yml +49 -0
- package/package.json +64 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
|
2
|
+
import { generateNewMnemonic, mnemonicToSeed, initWalletFromMnemonic, waitForFunds, registerNightForDust, closeWallet, } from './wallet.js';
|
|
3
|
+
import { fundAccount } from './funding.js';
|
|
4
|
+
import { PublicKey as UnshieldedPublicKey } from '@midnight-ntwrk/wallet-sdk-unshielded-wallet';
|
|
5
|
+
import { DEFAULT_NIGHT_AMOUNT } from './config.js';
|
|
6
|
+
let logger = null;
|
|
7
|
+
export function setLogger(l) {
|
|
8
|
+
logger = l;
|
|
9
|
+
}
|
|
10
|
+
export async function generateAccounts(opts) {
|
|
11
|
+
const count = opts.count ?? 1;
|
|
12
|
+
const accounts = [];
|
|
13
|
+
for (let i = 0; i < count; i++) {
|
|
14
|
+
const mnemonic = generateNewMnemonic();
|
|
15
|
+
if (opts.format === 'privateKey') {
|
|
16
|
+
// Derive actual hex seed from mnemonic (review fix #5)
|
|
17
|
+
const seed = mnemonicToSeed(mnemonic);
|
|
18
|
+
accounts.push({
|
|
19
|
+
name: `Account ${i + 1}`,
|
|
20
|
+
privateKey: seed.toString('hex'),
|
|
21
|
+
address: '', // Address is derived when wallet is initialized on-chain
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
accounts.push({
|
|
26
|
+
name: `Account ${i + 1}`,
|
|
27
|
+
mnemonic,
|
|
28
|
+
address: '', // Address is derived when wallet is initialized on-chain
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return accounts;
|
|
33
|
+
}
|
|
34
|
+
export async function generateAndFundAccounts(masterWallet, config, opts) {
|
|
35
|
+
const accounts = await generateAccounts(opts);
|
|
36
|
+
const results = [];
|
|
37
|
+
for (const account of accounts) {
|
|
38
|
+
const mnemonic = account.mnemonic;
|
|
39
|
+
if (!mnemonic) {
|
|
40
|
+
results.push({ ...account, funded: false, dustRegistered: false });
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
if (opts.fund) {
|
|
44
|
+
logger?.info({ name: account.name }, 'Funding account...');
|
|
45
|
+
const ctx = await initWalletFromMnemonic(mnemonic, config);
|
|
46
|
+
try {
|
|
47
|
+
const address = UnshieldedPublicKey.fromKeyStore(ctx.unshieldedKeystore).address;
|
|
48
|
+
account.address = address;
|
|
49
|
+
await fundAccount(masterWallet, address, DEFAULT_NIGHT_AMOUNT);
|
|
50
|
+
await waitForFunds(ctx.wallet);
|
|
51
|
+
if (opts.registerDust) {
|
|
52
|
+
const dustOk = await registerNightForDust(ctx);
|
|
53
|
+
results.push({ ...account, funded: true, dustRegistered: dustOk });
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
results.push({ ...account, funded: true, dustRegistered: false });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
await closeWallet(ctx);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
results.push({ ...account, funded: false, dustRegistered: false });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return results;
|
|
68
|
+
}
|
|
69
|
+
export async function writeAccountsFile(filePath, accounts) {
|
|
70
|
+
const fileContent = {
|
|
71
|
+
accounts: accounts.map((a) => ({
|
|
72
|
+
name: a.name,
|
|
73
|
+
...(a.mnemonic ? { mnemonic: a.mnemonic } : {}),
|
|
74
|
+
...(a.privateKey ? { privateKey: a.privateKey } : {}),
|
|
75
|
+
})),
|
|
76
|
+
};
|
|
77
|
+
await writeFile(filePath, JSON.stringify(fileContent, null, 2) + '\n', 'utf-8');
|
|
78
|
+
logger?.info({ filePath, count: accounts.length }, 'Accounts file written');
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=accounts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/core/accounts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { NetworkConfig } from './types.js';
|
|
2
|
+
export declare const DOCKER_COMPOSE_DIR: string;
|
|
3
|
+
export declare const DOCKER_COMPOSE_FILE = "standalone.yml";
|
|
4
|
+
export declare const GENESIS_SEED = "0000000000000000000000000000000000000000000000000000000000000001";
|
|
5
|
+
export declare const DEFAULT_NIGHT_AMOUNT: bigint;
|
|
6
|
+
export declare const MAX_ACCOUNTS_PER_BATCH = 10;
|
|
7
|
+
export declare const DOCKER_IMAGES: {
|
|
8
|
+
readonly node: "midnightntwrk/midnight-node:0.20.0";
|
|
9
|
+
readonly indexer: "midnightntwrk/indexer-standalone:3.0.0";
|
|
10
|
+
readonly proofServer: "midnightntwrk/proof-server:7.0.0";
|
|
11
|
+
};
|
|
12
|
+
export declare const defaultConfig: NetworkConfig;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
4
|
+
export const DOCKER_COMPOSE_DIR = path.resolve(__dirname, '../../docker');
|
|
5
|
+
export const DOCKER_COMPOSE_FILE = 'standalone.yml';
|
|
6
|
+
// Dev-only genesis seed (private key = 1). Never use on a live network.
|
|
7
|
+
export const GENESIS_SEED = '0000000000000000000000000000000000000000000000000000000000000001';
|
|
8
|
+
export const DEFAULT_NIGHT_AMOUNT = 50000n * 10n ** 6n; // 50,000 NIGHT in smallest unit
|
|
9
|
+
export const MAX_ACCOUNTS_PER_BATCH = 10;
|
|
10
|
+
export const DOCKER_IMAGES = {
|
|
11
|
+
node: 'midnightntwrk/midnight-node:0.20.0',
|
|
12
|
+
indexer: 'midnightntwrk/indexer-standalone:3.0.0',
|
|
13
|
+
proofServer: 'midnightntwrk/proof-server:7.0.0',
|
|
14
|
+
};
|
|
15
|
+
export const defaultConfig = {
|
|
16
|
+
indexer: 'http://127.0.0.1:8088/api/v3/graphql',
|
|
17
|
+
indexerWS: 'ws://127.0.0.1:8088/api/v3/graphql/ws',
|
|
18
|
+
node: 'http://127.0.0.1:9944',
|
|
19
|
+
proofServer: 'http://127.0.0.1:6300',
|
|
20
|
+
networkId: 'undeployed',
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;AAEpD,wEAAwE;AACxE,MAAM,CAAC,MAAM,YAAY,GAAG,kEAAkE,CAAC;AAC/F,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAO,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC,gCAAgC;AACzF,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAEzC,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,oCAAoC;IAC1C,OAAO,EAAE,wCAAwC;IACjD,WAAW,EAAE,kCAAkC;CACvC,CAAC;AAEX,MAAM,CAAC,MAAM,aAAa,GAAkB;IAC1C,OAAO,EAAE,sCAAsC;IAC/C,SAAS,EAAE,uCAAuC;IAClD,IAAI,EAAE,uBAAuB;IAC7B,WAAW,EAAE,uBAAuB;IACpC,SAAS,EAAE,YAAY;CACxB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ServiceStatus, type ServiceName } from './types.js';
|
|
2
|
+
export declare function isDockerRunning(): Promise<boolean>;
|
|
3
|
+
export declare function composeUp(opts: {
|
|
4
|
+
pull: boolean;
|
|
5
|
+
}): Promise<void>;
|
|
6
|
+
export declare function composeDown(opts: {
|
|
7
|
+
removeVolumes: boolean;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
export declare function composePs(): Promise<ServiceStatus[]>;
|
|
10
|
+
export declare function composeLogs(opts: {
|
|
11
|
+
service?: ServiceName;
|
|
12
|
+
lines?: number;
|
|
13
|
+
}): Promise<string>;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// src/core/docker.ts
|
|
2
|
+
import { execFile as execFileCb } from 'node:child_process';
|
|
3
|
+
import { DOCKER_COMPOSE_DIR, DOCKER_COMPOSE_FILE } from './config.js';
|
|
4
|
+
import { DevnetError } from './types.js';
|
|
5
|
+
function execFile(cmd, args, opts = {}) {
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
execFileCb(cmd, args, opts, (error, stdout, stderr) => {
|
|
8
|
+
if (error) {
|
|
9
|
+
reject(error);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
resolve({ stdout: stdout, stderr: stderr });
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
const COMPOSE_ARGS = [
|
|
18
|
+
'compose',
|
|
19
|
+
'-f',
|
|
20
|
+
`${DOCKER_COMPOSE_DIR}/${DOCKER_COMPOSE_FILE}`,
|
|
21
|
+
];
|
|
22
|
+
const CONTAINER_TO_SERVICE = {
|
|
23
|
+
'midnight-node': { name: 'node', port: 9944, url: 'http://127.0.0.1:9944' },
|
|
24
|
+
'midnight-indexer': { name: 'indexer', port: 8088, url: 'http://127.0.0.1:8088/api/v3/graphql' },
|
|
25
|
+
'midnight-proof-server': { name: 'proof-server', port: 6300, url: 'http://127.0.0.1:6300' },
|
|
26
|
+
};
|
|
27
|
+
export async function isDockerRunning() {
|
|
28
|
+
try {
|
|
29
|
+
await execFile('docker', ['info'], { timeout: 5000 });
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function assertDocker() {
|
|
37
|
+
const running = await isDockerRunning();
|
|
38
|
+
if (!running) {
|
|
39
|
+
throw new DevnetError('Docker is not running.', 'DOCKER_NOT_RUNNING', 'Please start Docker Desktop.');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export async function composeUp(opts) {
|
|
43
|
+
await assertDocker();
|
|
44
|
+
if (opts.pull) {
|
|
45
|
+
await execFile('docker', [...COMPOSE_ARGS, 'pull'], { timeout: 300_000 });
|
|
46
|
+
}
|
|
47
|
+
await execFile('docker', [...COMPOSE_ARGS, 'up', '-d', '--wait'], { timeout: 300_000 });
|
|
48
|
+
}
|
|
49
|
+
export async function composeDown(opts) {
|
|
50
|
+
const args = [...COMPOSE_ARGS, 'down'];
|
|
51
|
+
if (opts.removeVolumes) {
|
|
52
|
+
args.push('-v');
|
|
53
|
+
}
|
|
54
|
+
await execFile('docker', args, { timeout: 60_000 });
|
|
55
|
+
}
|
|
56
|
+
export async function composePs() {
|
|
57
|
+
let stdout;
|
|
58
|
+
try {
|
|
59
|
+
const result = await execFile('docker', [...COMPOSE_ARGS, 'ps', '--format', 'json'], { timeout: 10_000 });
|
|
60
|
+
stdout = result.stdout;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
if (!stdout.trim())
|
|
66
|
+
return [];
|
|
67
|
+
let containers;
|
|
68
|
+
try {
|
|
69
|
+
containers = JSON.parse(stdout);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// docker compose ps --format json may output one JSON object per line
|
|
73
|
+
containers = stdout
|
|
74
|
+
.trim()
|
|
75
|
+
.split('\n')
|
|
76
|
+
.filter(Boolean)
|
|
77
|
+
.map((line) => JSON.parse(line));
|
|
78
|
+
}
|
|
79
|
+
if (!Array.isArray(containers)) {
|
|
80
|
+
containers = [containers];
|
|
81
|
+
}
|
|
82
|
+
return containers.map((c) => {
|
|
83
|
+
const svc = CONTAINER_TO_SERVICE[c.Name];
|
|
84
|
+
return {
|
|
85
|
+
name: svc?.name ?? c.Name,
|
|
86
|
+
containerName: c.Name,
|
|
87
|
+
status: c.State === 'running' ? 'running' : 'stopped',
|
|
88
|
+
port: svc?.port ?? 0,
|
|
89
|
+
url: svc?.url ?? '',
|
|
90
|
+
};
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
export async function composeLogs(opts) {
|
|
94
|
+
const args = [...COMPOSE_ARGS, 'logs', '--tail', String(opts.lines ?? 50)];
|
|
95
|
+
if (opts.service) {
|
|
96
|
+
args.push(opts.service);
|
|
97
|
+
}
|
|
98
|
+
const { stdout } = await execFile('docker', args, { timeout: 10_000 });
|
|
99
|
+
return stdout;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=docker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/core/docker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Logger } from 'pino';
|
|
2
|
+
import type { NetworkConfig, FundedAccount } from './types.js';
|
|
3
|
+
import { type WalletContext } from './wallet.js';
|
|
4
|
+
export declare function setLogger(l: Logger): void;
|
|
5
|
+
/**
|
|
6
|
+
* Transfer NIGHT tokens using the 4-step recipe pattern:
|
|
7
|
+
* 1. Build recipe (transferTransaction)
|
|
8
|
+
* 2. Sign recipe (signRecipe)
|
|
9
|
+
* 3. Finalize (finalizeRecipe)
|
|
10
|
+
* 4. Submit (submitTransaction)
|
|
11
|
+
*/
|
|
12
|
+
export declare function transferNight(masterWallet: WalletContext, receiverAddress: string, amount: bigint): Promise<string>;
|
|
13
|
+
export declare function fundAccount(masterWallet: WalletContext, address: string, amount?: bigint): Promise<FundedAccount>;
|
|
14
|
+
export declare function fundAccountFromMnemonic(masterWallet: WalletContext, name: string, mnemonic: string, config: NetworkConfig, amount?: bigint): Promise<FundedAccount>;
|
|
15
|
+
export declare function fundAccountsFromFile(masterWallet: WalletContext, filePath: string, config: NetworkConfig): Promise<FundedAccount[]>;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import * as ledger from '@midnight-ntwrk/ledger-v7';
|
|
3
|
+
import { PublicKey as UnshieldedPublicKey } from '@midnight-ntwrk/wallet-sdk-unshielded-wallet';
|
|
4
|
+
import { DevnetError } from './types.js';
|
|
5
|
+
import { DEFAULT_NIGHT_AMOUNT, MAX_ACCOUNTS_PER_BATCH } from './config.js';
|
|
6
|
+
import { initWalletFromMnemonic, waitForFunds, registerNightForDust, closeWallet, getWalletBalances, } from './wallet.js';
|
|
7
|
+
let logger = null;
|
|
8
|
+
export function setLogger(l) {
|
|
9
|
+
logger = l;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Transfer NIGHT tokens using the 4-step recipe pattern:
|
|
13
|
+
* 1. Build recipe (transferTransaction)
|
|
14
|
+
* 2. Sign recipe (signRecipe)
|
|
15
|
+
* 3. Finalize (finalizeRecipe)
|
|
16
|
+
* 4. Submit (submitTransaction)
|
|
17
|
+
*/
|
|
18
|
+
export async function transferNight(masterWallet, receiverAddress, amount) {
|
|
19
|
+
logger?.info({ receiverAddress, amount: amount.toString() }, 'Transferring NIGHT...');
|
|
20
|
+
const ttl = new Date(Date.now() + 30 * 60 * 1000); // 30-minute TTL
|
|
21
|
+
// Step 1: Build recipe via transferTransaction
|
|
22
|
+
const recipe = await masterWallet.wallet.transferTransaction([
|
|
23
|
+
{
|
|
24
|
+
type: 'unshielded',
|
|
25
|
+
outputs: [
|
|
26
|
+
{
|
|
27
|
+
type: ledger.nativeToken().raw,
|
|
28
|
+
receiverAddress,
|
|
29
|
+
amount,
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
], {
|
|
34
|
+
shieldedSecretKeys: masterWallet.shieldedSecretKeys,
|
|
35
|
+
dustSecretKey: masterWallet.dustSecretKey,
|
|
36
|
+
}, { ttl });
|
|
37
|
+
// Step 2: Sign with unshielded keystore
|
|
38
|
+
const signed = await masterWallet.wallet.signRecipe(recipe, (data) => masterWallet.unshieldedKeystore.signData(data));
|
|
39
|
+
// Step 3: Finalize
|
|
40
|
+
const finalized = await masterWallet.wallet.finalizeRecipe(signed);
|
|
41
|
+
// Step 4: Submit
|
|
42
|
+
const txHash = await masterWallet.wallet.submitTransaction(finalized);
|
|
43
|
+
logger?.info({ txHash }, 'Transfer complete');
|
|
44
|
+
return String(txHash);
|
|
45
|
+
}
|
|
46
|
+
export async function fundAccount(masterWallet, address, amount = DEFAULT_NIGHT_AMOUNT) {
|
|
47
|
+
// Check master wallet has sufficient balance
|
|
48
|
+
const balances = await getWalletBalances(masterWallet);
|
|
49
|
+
if (balances.unshielded < amount) {
|
|
50
|
+
throw new DevnetError(`Insufficient master wallet balance: ${balances.unshielded} < ${amount}`, 'INSUFFICIENT_BALANCE', 'The master wallet does not have enough NIGHT to fund this account.');
|
|
51
|
+
}
|
|
52
|
+
const txHash = await transferNight(masterWallet, address, amount);
|
|
53
|
+
logger?.info({ address, txHash }, 'Account funded');
|
|
54
|
+
return {
|
|
55
|
+
name: address.slice(0, 12) + '...',
|
|
56
|
+
address,
|
|
57
|
+
amount,
|
|
58
|
+
txHash,
|
|
59
|
+
hasDust: false,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export async function fundAccountFromMnemonic(masterWallet, name, mnemonic, config, amount = DEFAULT_NIGHT_AMOUNT) {
|
|
63
|
+
logger?.info({ name }, 'Deriving wallet from mnemonic...');
|
|
64
|
+
const recipientCtx = await initWalletFromMnemonic(mnemonic, config);
|
|
65
|
+
// Get recipient address from unshielded keystore
|
|
66
|
+
const address = UnshieldedPublicKey.fromKeyStore(recipientCtx.unshieldedKeystore).address;
|
|
67
|
+
// Transfer NIGHT from master
|
|
68
|
+
const txHash = await transferNight(masterWallet, address, amount);
|
|
69
|
+
// Wait for recipient to see funds
|
|
70
|
+
logger?.info({ name }, 'Waiting for recipient to sync funds...');
|
|
71
|
+
await waitForFunds(recipientCtx.wallet);
|
|
72
|
+
// Register DUST
|
|
73
|
+
const hasDust = await registerNightForDust(recipientCtx);
|
|
74
|
+
// Close recipient wallet
|
|
75
|
+
await closeWallet(recipientCtx);
|
|
76
|
+
return { name, address, amount, txHash, hasDust };
|
|
77
|
+
}
|
|
78
|
+
export async function fundAccountsFromFile(masterWallet, filePath, config) {
|
|
79
|
+
const raw = await readFile(filePath, 'utf-8');
|
|
80
|
+
let accountsFile;
|
|
81
|
+
try {
|
|
82
|
+
accountsFile = JSON.parse(raw);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
throw new DevnetError(`Invalid JSON in accounts file: ${filePath}`, 'INVALID_ACCOUNTS_FILE');
|
|
86
|
+
}
|
|
87
|
+
if (!accountsFile.accounts || !Array.isArray(accountsFile.accounts)) {
|
|
88
|
+
throw new DevnetError('Accounts file must contain an "accounts" array', 'INVALID_ACCOUNTS_FILE');
|
|
89
|
+
}
|
|
90
|
+
if (accountsFile.accounts.length > MAX_ACCOUNTS_PER_BATCH) {
|
|
91
|
+
throw new DevnetError(`Maximum ${MAX_ACCOUNTS_PER_BATCH} accounts per batch. Got ${accountsFile.accounts.length}.`, 'TOO_MANY_ACCOUNTS');
|
|
92
|
+
}
|
|
93
|
+
const funded = [];
|
|
94
|
+
for (const account of accountsFile.accounts) {
|
|
95
|
+
if (account.mnemonic) {
|
|
96
|
+
const result = await fundAccountFromMnemonic(masterWallet, account.name, account.mnemonic, config);
|
|
97
|
+
funded.push(result);
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
throw new DevnetError(`Account "${account.name}" has no mnemonic`, 'INVALID_ACCOUNT_ENTRY');
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return funded;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=funding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"funding.js","sourceRoot":"","sources":["../../src/core/funding.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { NetworkConfig } from './types.js';
|
|
2
|
+
export interface ServiceHealth {
|
|
3
|
+
healthy: boolean;
|
|
4
|
+
responseTime?: number;
|
|
5
|
+
error?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface HealthReport {
|
|
8
|
+
node: ServiceHealth;
|
|
9
|
+
indexer: ServiceHealth;
|
|
10
|
+
proofServer: ServiceHealth;
|
|
11
|
+
allHealthy: boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function checkAllHealth(config?: NetworkConfig): Promise<HealthReport>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { defaultConfig } from './config.js';
|
|
2
|
+
async function checkEndpoint(url) {
|
|
3
|
+
const start = Date.now();
|
|
4
|
+
try {
|
|
5
|
+
const response = await fetch(url, { signal: AbortSignal.timeout(5000) });
|
|
6
|
+
return {
|
|
7
|
+
healthy: response.ok,
|
|
8
|
+
responseTime: Date.now() - start,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
catch (err) {
|
|
12
|
+
return {
|
|
13
|
+
healthy: false,
|
|
14
|
+
responseTime: Date.now() - start,
|
|
15
|
+
error: err instanceof Error ? err.message : String(err),
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export async function checkAllHealth(config) {
|
|
20
|
+
const cfg = config ?? defaultConfig;
|
|
21
|
+
const indexerOrigin = new URL(cfg.indexer).origin;
|
|
22
|
+
const [node, indexer, proofServer] = await Promise.all([
|
|
23
|
+
checkEndpoint(`${cfg.node}/health`),
|
|
24
|
+
checkEndpoint(`${indexerOrigin}/ready`),
|
|
25
|
+
checkEndpoint(`${cfg.proofServer}/version`),
|
|
26
|
+
]);
|
|
27
|
+
return {
|
|
28
|
+
node,
|
|
29
|
+
indexer,
|
|
30
|
+
proofServer,
|
|
31
|
+
allHealthy: node.healthy && indexer.healthy && proofServer.healthy,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/core/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAgB5C,KAAK,UAAU,aAAa,CAAC,GAAW;IACtC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzE,OAAO;YACL,OAAO,EAAE,QAAQ,CAAC,EAAE;YACpB,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;SACjC,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,KAAK;YACd,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;YAChC,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAsB;IACzD,MAAM,GAAG,GAAG,MAAM,IAAI,aAAa,CAAC;IACpC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAClD,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACrD,aAAa,CAAC,GAAG,GAAG,CAAC,IAAI,SAAS,CAAC;QACnC,aAAa,CAAC,GAAG,aAAa,QAAQ,CAAC;QACvC,aAAa,CAAC,GAAG,GAAG,CAAC,WAAW,UAAU,CAAC;KAC5C,CAAC,CAAC;IAEH,OAAO;QACL,IAAI;QACJ,OAAO;QACP,WAAW;QACX,UAAU,EAAE,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,IAAI,WAAW,CAAC,OAAO;KACnE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// src/core/logger.ts
|
|
2
|
+
import pino from 'pino';
|
|
3
|
+
export function createLogger(level = 'info') {
|
|
4
|
+
return pino({
|
|
5
|
+
level,
|
|
6
|
+
transport: {
|
|
7
|
+
target: 'pino-pretty',
|
|
8
|
+
options: {
|
|
9
|
+
colorize: true,
|
|
10
|
+
translateTime: 'SYS:standard',
|
|
11
|
+
ignore: 'pid,hostname',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +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;IACjD,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;aACvB;SACF;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Logger } from 'pino';
|
|
2
|
+
import type { NetworkConfig, NetworkStatus, ServiceStatus } from './types.js';
|
|
3
|
+
import { type WalletContext } from './wallet.js';
|
|
4
|
+
export declare class NetworkManager {
|
|
5
|
+
private status;
|
|
6
|
+
private masterWallet;
|
|
7
|
+
private logger;
|
|
8
|
+
readonly config: NetworkConfig;
|
|
9
|
+
constructor(config?: NetworkConfig);
|
|
10
|
+
setLogger(l: Logger): void;
|
|
11
|
+
getStatus(): NetworkStatus;
|
|
12
|
+
getMasterWallet(): WalletContext | null;
|
|
13
|
+
detectRunningNetwork(): Promise<void>;
|
|
14
|
+
ensureWallet(): Promise<WalletContext>;
|
|
15
|
+
start(opts: {
|
|
16
|
+
pull: boolean;
|
|
17
|
+
}): Promise<'started' | 'already-running'>;
|
|
18
|
+
stop(opts: {
|
|
19
|
+
removeVolumes: boolean;
|
|
20
|
+
}): Promise<void>;
|
|
21
|
+
restart(opts: {
|
|
22
|
+
pull: boolean;
|
|
23
|
+
removeVolumes: boolean;
|
|
24
|
+
}): Promise<void>;
|
|
25
|
+
getServices(): Promise<ServiceStatus[]>;
|
|
26
|
+
getLogs(opts: {
|
|
27
|
+
service?: 'node' | 'indexer' | 'proof-server';
|
|
28
|
+
lines?: number;
|
|
29
|
+
}): Promise<string>;
|
|
30
|
+
shutdown(): Promise<void>;
|
|
31
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { DevnetError } from './types.js';
|
|
2
|
+
import { defaultConfig } from './config.js';
|
|
3
|
+
import { composeUp, composeDown, composePs, composeLogs } from './docker.js';
|
|
4
|
+
import { initMasterWallet, registerNightForDust, closeWallet, } from './wallet.js';
|
|
5
|
+
export class NetworkManager {
|
|
6
|
+
status = 'stopped';
|
|
7
|
+
masterWallet = null;
|
|
8
|
+
logger = null;
|
|
9
|
+
config;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.config = config ?? defaultConfig;
|
|
12
|
+
}
|
|
13
|
+
setLogger(l) {
|
|
14
|
+
this.logger = l;
|
|
15
|
+
}
|
|
16
|
+
getStatus() {
|
|
17
|
+
return this.status;
|
|
18
|
+
}
|
|
19
|
+
getMasterWallet() {
|
|
20
|
+
return this.masterWallet;
|
|
21
|
+
}
|
|
22
|
+
async detectRunningNetwork() {
|
|
23
|
+
try {
|
|
24
|
+
const services = await composePs();
|
|
25
|
+
const allRunning = services.length >= 3 &&
|
|
26
|
+
services.every((s) => s.status === 'running');
|
|
27
|
+
if (allRunning) {
|
|
28
|
+
this.logger?.info('Detected running network containers');
|
|
29
|
+
this.status = 'running';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// Docker not available or compose not set up — stay stopped
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async ensureWallet() {
|
|
37
|
+
if (this.status !== 'running') {
|
|
38
|
+
throw new DevnetError('Network is not running. Call start-network first.', 'NETWORK_NOT_RUNNING');
|
|
39
|
+
}
|
|
40
|
+
if (!this.masterWallet) {
|
|
41
|
+
this.logger?.info('Auto-initializing master wallet...');
|
|
42
|
+
this.masterWallet = await initMasterWallet(this.config);
|
|
43
|
+
await registerNightForDust(this.masterWallet);
|
|
44
|
+
}
|
|
45
|
+
return this.masterWallet;
|
|
46
|
+
}
|
|
47
|
+
async start(opts) {
|
|
48
|
+
if (this.status === 'running') {
|
|
49
|
+
return 'already-running';
|
|
50
|
+
}
|
|
51
|
+
this.status = 'starting';
|
|
52
|
+
try {
|
|
53
|
+
await composeUp({ pull: opts.pull });
|
|
54
|
+
this.masterWallet = await initMasterWallet(this.config);
|
|
55
|
+
await registerNightForDust(this.masterWallet);
|
|
56
|
+
this.status = 'running';
|
|
57
|
+
this.logger?.info('Network started and master wallet initialized');
|
|
58
|
+
return 'started';
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
try {
|
|
62
|
+
await composeDown({ removeVolumes: false });
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// best-effort cleanup
|
|
66
|
+
}
|
|
67
|
+
this.status = 'stopped';
|
|
68
|
+
throw err;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async stop(opts) {
|
|
72
|
+
this.status = 'stopping';
|
|
73
|
+
try {
|
|
74
|
+
if (this.masterWallet) {
|
|
75
|
+
await closeWallet(this.masterWallet);
|
|
76
|
+
this.masterWallet = null;
|
|
77
|
+
}
|
|
78
|
+
await composeDown({ removeVolumes: opts.removeVolumes });
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
this.status = 'stopped';
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async restart(opts) {
|
|
85
|
+
await this.stop({ removeVolumes: opts.removeVolumes });
|
|
86
|
+
await this.start({ pull: opts.pull });
|
|
87
|
+
}
|
|
88
|
+
async getServices() {
|
|
89
|
+
return composePs();
|
|
90
|
+
}
|
|
91
|
+
async getLogs(opts) {
|
|
92
|
+
return composeLogs(opts);
|
|
93
|
+
}
|
|
94
|
+
async shutdown() {
|
|
95
|
+
if (this.masterWallet) {
|
|
96
|
+
await closeWallet(this.masterWallet);
|
|
97
|
+
this.masterWallet = null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=network-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-manager.js","sourceRoot":"","sources":["../../src/core/network-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface NetworkConfig {
|
|
2
|
+
readonly indexer: string;
|
|
3
|
+
readonly indexerWS: string;
|
|
4
|
+
readonly node: string;
|
|
5
|
+
readonly proofServer: string;
|
|
6
|
+
readonly networkId: string;
|
|
7
|
+
}
|
|
8
|
+
export type NetworkStatus = 'stopped' | 'starting' | 'running' | 'stopping';
|
|
9
|
+
export type ServiceName = 'node' | 'indexer' | 'proof-server';
|
|
10
|
+
export interface ServiceStatus {
|
|
11
|
+
name: ServiceName;
|
|
12
|
+
containerName: string;
|
|
13
|
+
status: 'running' | 'stopped' | 'unhealthy' | 'unknown';
|
|
14
|
+
port: number;
|
|
15
|
+
url: string;
|
|
16
|
+
}
|
|
17
|
+
export interface NetworkState {
|
|
18
|
+
status: NetworkStatus;
|
|
19
|
+
services: ServiceStatus[];
|
|
20
|
+
}
|
|
21
|
+
export interface WalletBalances {
|
|
22
|
+
unshielded: bigint;
|
|
23
|
+
shielded: bigint;
|
|
24
|
+
dust: bigint;
|
|
25
|
+
total: bigint;
|
|
26
|
+
}
|
|
27
|
+
export interface FundedAccount {
|
|
28
|
+
name: string;
|
|
29
|
+
address: string;
|
|
30
|
+
amount: bigint;
|
|
31
|
+
txHash: string;
|
|
32
|
+
hasDust: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface GeneratedAccount {
|
|
35
|
+
name: string;
|
|
36
|
+
mnemonic?: string;
|
|
37
|
+
privateKey?: string;
|
|
38
|
+
address: string;
|
|
39
|
+
}
|
|
40
|
+
export interface AccountsFileFormat {
|
|
41
|
+
accounts: Array<{
|
|
42
|
+
name: string;
|
|
43
|
+
mnemonic?: string;
|
|
44
|
+
privateKey?: string;
|
|
45
|
+
}>;
|
|
46
|
+
}
|
|
47
|
+
export declare class DevnetError extends Error {
|
|
48
|
+
readonly code: string;
|
|
49
|
+
readonly suggestion?: string | undefined;
|
|
50
|
+
constructor(message: string, code: string, suggestion?: string | undefined);
|
|
51
|
+
}
|