@constellation-network/node-pilot 0.14.0-testnet → 0.16.0-intnet

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 CHANGED
@@ -21,7 +21,7 @@ $ npm install -g @constellation-network/node-pilot
21
21
  $ cpilot COMMAND
22
22
  running command...
23
23
  $ cpilot (--version|-v)
24
- @constellation-network/node-pilot/0.14.0-testnet darwin-arm64 node-v22.15.0
24
+ @constellation-network/node-pilot/0.16.0-intnet darwin-arm64 node-v22.15.0
25
25
  $ cpilot --help [COMMAND]
26
26
  USAGE
27
27
  $ cpilot COMMAND
@@ -72,7 +72,7 @@ EXAMPLES
72
72
  $ cpilot clean
73
73
  ```
74
74
 
75
- _See code: [src/commands/clean.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.14.0-testnet/src/commands/clean.ts)_
75
+ _See code: [src/commands/clean.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.16.0-intnet/src/commands/clean.ts)_
76
76
 
77
77
  ## `cpilot config`
78
78
 
@@ -89,7 +89,7 @@ EXAMPLES
89
89
  $ cpilot config
90
90
  ```
91
91
 
92
- _See code: [src/commands/config.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.14.0-testnet/src/commands/config.ts)_
92
+ _See code: [src/commands/config.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.16.0-intnet/src/commands/config.ts)_
93
93
 
94
94
  ## `cpilot config get [NAME]`
95
95
 
@@ -113,7 +113,7 @@ EXAMPLES
113
113
  $ cpilot config get gl0:CL_PUBLIC_HTTP_PORT
114
114
  ```
115
115
 
116
- _See code: [src/commands/config/get.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.14.0-testnet/src/commands/config/get.ts)_
116
+ _See code: [src/commands/config/get.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.16.0-intnet/src/commands/config/get.ts)_
117
117
 
118
118
  ## `cpilot config set NAME VALUE`
119
119
 
@@ -136,7 +136,7 @@ EXAMPLES
136
136
  $ cpilot config set gl0:CL_PUBLIC_HTTP_PORT 9000
137
137
  ```
138
138
 
139
- _See code: [src/commands/config/set.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.14.0-testnet/src/commands/config/set.ts)_
139
+ _See code: [src/commands/config/set.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.16.0-intnet/src/commands/config/set.ts)_
140
140
 
141
141
  ## `cpilot help [COMMAND]`
142
142
 
@@ -173,7 +173,7 @@ EXAMPLES
173
173
  $ cpilot info
174
174
  ```
175
175
 
176
- _See code: [src/commands/info.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.14.0-testnet/src/commands/info.ts)_
176
+ _See code: [src/commands/info.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.16.0-intnet/src/commands/info.ts)_
177
177
 
178
178
  ## `cpilot logs LAYER`
179
179
 
@@ -199,7 +199,7 @@ EXAMPLES
199
199
  $ cpilot logs
200
200
  ```
201
201
 
202
- _See code: [src/commands/logs.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.14.0-testnet/src/commands/logs.ts)_
202
+ _See code: [src/commands/logs.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.16.0-intnet/src/commands/logs.ts)_
203
203
 
204
204
  ## `cpilot restart [LAYER]`
205
205
 
@@ -227,7 +227,7 @@ EXAMPLES
227
227
  $ cpilot restart
228
228
  ```
229
229
 
230
- _See code: [src/commands/restart.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.14.0-testnet/src/commands/restart.ts)_
230
+ _See code: [src/commands/restart.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.16.0-intnet/src/commands/restart.ts)_
231
231
 
232
232
  ## `cpilot shutdown`
233
233
 
@@ -244,7 +244,7 @@ EXAMPLES
244
244
  $ cpilot shutdown
245
245
  ```
246
246
 
247
- _See code: [src/commands/shutdown.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.14.0-testnet/src/commands/shutdown.ts)_
247
+ _See code: [src/commands/shutdown.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.16.0-intnet/src/commands/shutdown.ts)_
248
248
 
249
249
  ## `cpilot status`
250
250
 
@@ -258,7 +258,7 @@ DESCRIPTION
258
258
  Display node status and configuration settings
259
259
  ```
260
260
 
261
- _See code: [src/commands/status.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.14.0-testnet/src/commands/status.ts)_
261
+ _See code: [src/commands/status.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.16.0-intnet/src/commands/status.ts)_
262
262
 
263
263
  ## `cpilot uninstall`
264
264
 
@@ -275,5 +275,5 @@ EXAMPLES
275
275
  $ cpilot uninstall
276
276
  ```
277
277
 
278
- _See code: [src/commands/uninstall.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.14.0-testnet/src/commands/uninstall.ts)_
278
+ _See code: [src/commands/uninstall.ts](https://github.com/Constellation-Labs/node-pilot/blob/v0.16.0-intnet/src/commands/uninstall.ts)_
279
279
  <!-- commandsstop -->
@@ -0,0 +1,5 @@
1
+ export declare const checkDiskSpace: {
2
+ checkDiskUsage(): Promise<void>;
3
+ getDockerReclaimableDiskUsage(): Promise<string>;
4
+ getReclaimableDiskSpace(area: "data" | "logs"): Promise<string>;
5
+ };
@@ -0,0 +1,78 @@
1
+ import { clm } from "../clm.js";
2
+ import { configStore } from "../config-store.js";
3
+ import { shellService } from "../services/shell-service.js";
4
+ // Utility to parse human-readable sizes (e.g., 10M, 2.5G) to bytes
5
+ function parseSize(sizeStr) {
6
+ const multipliers = { '': 1, 'G': 1024 ** 3, 'K': 1024, 'M': 1024 ** 2, 'P': 1024 ** 5, 'T': 1024 ** 4 };
7
+ const match = sizeStr.match(/([\d.]+)([KMGTP]?)/i);
8
+ if (!match)
9
+ return 0;
10
+ const num = Number.parseFloat(match[1]);
11
+ const unit = match[2].toUpperCase();
12
+ return num * (multipliers[unit] || 1);
13
+ }
14
+ // Utility to format bytes to human-readable string
15
+ function formatBytes(bytes) {
16
+ if (bytes < 1024)
17
+ return `${bytes} B`;
18
+ const units = ['K', 'M', 'G', 'T', 'P'];
19
+ let i = -1;
20
+ do {
21
+ bytes /= 1024;
22
+ i++;
23
+ } while (bytes >= 1024 && i < units.length - 1);
24
+ return `${bytes.toFixed(2)}${units[i]}`;
25
+ }
26
+ export const checkDiskSpace = {
27
+ async checkDiskUsage() {
28
+ const logSize = await this.getReclaimableDiskSpace('logs');
29
+ const dataSize = await this.getReclaimableDiskSpace('data');
30
+ console.log(`\n${logSize} ${dataSize}`);
31
+ await this.getDockerReclaimableDiskUsage();
32
+ },
33
+ async getDockerReclaimableDiskUsage() {
34
+ // Get docker system disk usage summary
35
+ const output = await shellService.runCommandWithOutput('docker system df --format "{{json .}}"');
36
+ // docker system df --format outputs one JSON object per line
37
+ let totalBytes = 0;
38
+ const details = [];
39
+ for (const line of output.split('\n')) {
40
+ if (!line.trim())
41
+ continue;
42
+ try {
43
+ const obj = JSON.parse(line);
44
+ // Try to sum up reclaimable space from images, containers, volumes, and build cache
45
+ if (obj.Reclaimable && obj.Reclaimable !== "") {
46
+ // Reclaimable is like "1.23GB (45%)" or "123MB (10%)"
47
+ const match = obj.Reclaimable.match(/([\d.]+)\s*([KMGTP]?B)/i);
48
+ if (match) {
49
+ const num = Number.parseFloat(match[1]);
50
+ const unit = match[2].replace('B', ''); // Remove trailing B
51
+ const multipliers = { '': 1, 'G': 1024 ** 3, 'K': 1024, 'M': 1024 ** 2, 'P': 1024 ** 5, 'T': 1024 ** 4 };
52
+ totalBytes += num * (multipliers[unit.toUpperCase()] || 1);
53
+ details.push(`${obj.Type}: ${match[0]}`);
54
+ }
55
+ }
56
+ }
57
+ catch {
58
+ // Ignore parse errors
59
+ }
60
+ }
61
+ clm.preStep(`Docker reclaimable disk usage: ${formatBytes(totalBytes)}${details.length > 0 ? ' (' + details.join(', ') + ')' : ''}`);
62
+ return formatBytes(totalBytes);
63
+ },
64
+ async getReclaimableDiskSpace(area) {
65
+ const { layersToRun } = configStore.getProjectInfo();
66
+ const logPaths = layersToRun.map(l => `${l}/${area}`).join(' ');
67
+ const logTable = await shellService.runProjectCommandWithOutput(`du -sh ${logPaths}`);
68
+ let totalBytes = 0;
69
+ const lines = logTable.split('\n');
70
+ for (const line of lines) {
71
+ const [size] = line.trim().split(/\s+/);
72
+ if (size)
73
+ totalBytes += parseSize(size);
74
+ }
75
+ clm.preStep(`Total reclaimable disk space in ${area}: ${formatBytes(totalBytes)}`);
76
+ return formatBytes(totalBytes);
77
+ }
78
+ };
@@ -45,8 +45,9 @@ export const checkInitialSetup = {
45
45
  const usersWithPilot = [];
46
46
  for (const folder of userFolders) {
47
47
  const dirPath = path.join(homeFolder, folder, '.node-pilot');
48
+ const prefix = isLinux ? 'sudo ' : '';
48
49
  // eslint-disable-next-line no-await-in-loop
49
- const exists = await shellService.runCommandWithOutput(`sudo test -d "${dirPath}" && echo 1 || echo 0`);
50
+ const exists = await shellService.runCommandWithOutput(`${prefix}test -d "${dirPath}" && echo 1 || echo 0`);
50
51
  if (exists === '1')
51
52
  usersWithPilot.push(folder);
52
53
  }
@@ -26,6 +26,7 @@ export const checkNetwork = {
26
26
  if (!isDockerRunning && found) {
27
27
  clm.warn('Node ID already exists in the cluster.');
28
28
  clm.warn('You need to shutdown your node from a previous installation before continuing.');
29
+ clm.warn('If you recently left the cluster, you may need to wait for your Node Id to be cleared. ~1 minute');
29
30
  clm.error(`Or to change the node ID, configure the Key File: use ${chalk.cyan('cpilot config')}, and select ${chalk.cyan('Key File')}`);
30
31
  }
31
32
  // configStore.setProjectFlag('duplicateNodeIdChecked', true);
@@ -1,3 +1,4 @@
1
+ import fs from "node:fs";
1
2
  import os from "node:os";
2
3
  import semver from "semver";
3
4
  import { clm } from "../clm.js";
@@ -72,6 +73,14 @@ export const checkNodePilot = {
72
73
  if (hasMajorMinorChange) {
73
74
  clm.step('Updating scripts and configuration files...');
74
75
  projectHelper.upgradeHypergraph();
76
+ if (fs.existsSync('/var/run/reboot-required')) {
77
+ clm.warn('A system update and reboot is required.');
78
+ await promptHelper.doYouWishToContinue();
79
+ await shellService.runCommand('sudo apt-get update && sudo apt-get upgrade -y');
80
+ if (await promptHelper.confirmPrompt('Do you want to reboot now?')) {
81
+ await shellService.runCommand('sudo reboot');
82
+ }
83
+ }
75
84
  }
76
85
  clm.postStep('Update completed. Run cpilot again to use the latest version');
77
86
  process.exit(0);
@@ -16,6 +16,11 @@ function getJavaMemoryOptions(network, mem) {
16
16
  // return `-Xms${mem}g -Xmx${mem}g -XX:+UnlockExperimentalVMOptions${linuxOpt} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./heap_dumps/ -XX:+ExitOnOutOfMemoryError`;
17
17
  return `-Xms${mem}g -Xmx${mem}g${linuxOpt} -XX:+UseStringDeduplication`;
18
18
  }
19
+ if (network === 'integrationnet') {
20
+ const linuxOpt = (os.platform() === 'linux') ? ' -XX:+UseZGC -XX:+ZGenerational' : '';
21
+ // return `-Xms${mem}g -Xmx${mem}g -XX:+UnlockExperimentalVMOptions${linuxOpt} -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./heap_dumps/ -XX:+ExitOnOutOfMemoryError`;
22
+ return `-Xms${mem - 2}g -Xmx${mem}g${linuxOpt} -XX:+UseStringDeduplication`;
23
+ }
19
24
  return `-Xms1024M -Xmx${mem}g -Xss256K`;
20
25
  }
21
26
  export const checkProject = {
@@ -48,7 +53,7 @@ export const checkProject = {
48
53
  answer--;
49
54
  let subLayerMem = 0;
50
55
  let mainLayerMem = 0;
51
- if (currentNetwork === 'testnet') {
56
+ if (currentNetwork === 'testnet' || currentNetwork === 'integrationnet') {
52
57
  // Divide equally between layers with max of 10GB each
53
58
  subLayerMem = layersToRun.length > 1 ? Math.floor(answer / 3) : 0;
54
59
  subLayerMem = Math.min(subLayerMem, 5);
@@ -9,6 +9,7 @@ import { configHelper } from "../helpers/config-helper.js";
9
9
  import { keyFileHelper } from "../helpers/key-file-helper.js";
10
10
  import { projectHelper } from "../helpers/project-helper.js";
11
11
  import { promptHelper } from "../helpers/prompt-helper.js";
12
+ import { delegatedStakingService } from "../services/delegated-staking-service.js";
12
13
  export default class Config extends Command {
13
14
  static description = 'Update configuration settings';
14
15
  static examples = [
@@ -20,12 +21,13 @@ export default class Config extends Command {
20
21
  // name = name.charAt(0).toUpperCase() + name.slice(1);
21
22
  const answer = await select({
22
23
  choices: [
23
- { name: 'External IP Address', value: 'externalIp' },
24
- { name: `Discord Alerts`, value: 'discordAlerts' },
25
- { name: 'Java Memory', value: 'javaMemory' },
26
24
  { name: 'Key File', value: 'keyFile' },
25
+ { name: 'Java Memory', value: 'javaMemory' },
26
+ { name: `Discord Alerts`, value: 'discordAlerts' },
27
+ { name: `Delegated Staking`, value: 'delegatedStaking' },
27
28
  { name: 'Layers To Run', value: 'layersToRun' },
28
- { name: `Hypergraph Network`, value: 'network' },
29
+ { name: 'Constellation Network', value: 'network' },
30
+ { name: 'External IP Address', value: 'externalIp' },
29
31
  ],
30
32
  message: 'What would you like to change?:',
31
33
  });
@@ -36,6 +38,9 @@ export default class Config extends Command {
36
38
  else if (answer === 'discordAlerts') {
37
39
  await checkNodePilot.promptDiscordRegistration();
38
40
  }
41
+ else if (answer === 'delegatedStaking') {
42
+ await delegatedStakingService.configureNodeParams();
43
+ }
39
44
  else if (answer === 'javaMemory') {
40
45
  await promptHelper.shutdownNodeIfRunning();
41
46
  await checkProject.configureJavaMemoryArguments();
@@ -4,7 +4,7 @@ import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { getRandomNode } from "../services/get-random-node.js";
7
- import { StatusTable } from "../helpers/status-table.js";
7
+ import { checkDiskSpace } from "../checks/check-disk-space.js";
8
8
  export default class Test extends Command {
9
9
  static description = 'node pilot test command';
10
10
  static hidden = true;
@@ -18,7 +18,10 @@ export default class Test extends Command {
18
18
  //
19
19
  // await archiverService.syncToLatestSnapshot();
20
20
  // await archiverService.checkLogsForMissingSnapshots();
21
- await StatusTable.run();
21
+ // await StatusTable.run();
22
+ await checkDiskSpace.checkDiskUsage();
23
+ // await delegatedStakingService.postNodeParams(0.08, "Doc Holliday", 'Come and get "som\'e" rewards!', {hash: "0000000000000000000000000000000000000000000000000000000000000000", ordinal: 123_456});
24
+ // await delegatedStakingService.configureNodeParams();
22
25
  // console.log(semver.parse("0.11.0-testnet")?.compare('0.11.0'));
23
26
  // await checkNodePilot.checkVersion();
24
27
  }
@@ -29,7 +29,7 @@ export const projectHelper = {
29
29
  }
30
30
  if (deleteJars) {
31
31
  // eslint-disable-next-line no-await-in-loop
32
- await shellService.runProjectCommand(`sudo rm -rf ${layer}/dist`);
32
+ await shellService.runProjectCommand(`sudo rm -rf dist`);
33
33
  }
34
34
  }
35
35
  clm.postStep('Cleanup complete');
@@ -110,7 +110,7 @@ export const statusTableHeader = [
110
110
  { color: 'white', formatter: formatState, headerColor: 'whiteBright', value: 'Cluster State', width: 16 },
111
111
  { color: 'white', formatter: formatCpu, headerColor: 'whiteBright', value: 'CPU Usage', width: 12 },
112
112
  { color: 'white', formatter: formatMem, headerColor: 'whiteBright', value: 'Mem Usage', width: 12 },
113
- { color: 'white', formatter: formatError, headerColor: 'whiteBright', value: 'Error', width: 22 },
113
+ { color: 'white', formatter: formatError, headerColor: 'whiteBright', value: 'Last Error', width: 22 },
114
114
  ];
115
115
  export const glHeader1 = [
116
116
  // { color: 'white', headerColor: 'whiteBright', value: 'Network' },
@@ -124,5 +124,5 @@ export const glHeader2 = [
124
124
  { color: 'white', formatter: formatState, headerColor: 'whiteBright', value: 'Cluster State', width: 22 },
125
125
  { color: 'white', formatter: formatCpu, headerColor: 'whiteBright', value: 'CPU Usage', width: 13 },
126
126
  { color: 'white', formatter: formatMem, headerColor: 'whiteBright', value: 'Mem Usage', width: 16 },
127
- { color: 'white', formatter: formatError, headerColor: 'whiteBright', value: 'Error', width: 22 },
127
+ { color: 'white', formatter: formatError, headerColor: 'whiteBright', value: 'Last Error', width: 22 },
128
128
  ];
@@ -5,10 +5,13 @@ export declare const clusterService: {
5
5
  getClusterNodeInfo(layer?: TessellationLayer): Promise<NodeInfo>;
6
6
  getLatestConsensusInfo(layer?: TessellationLayer): Promise<ClusterConsensusInfo>;
7
7
  getLayer0(): "gl0" | "ml0";
8
+ getNodeParams(id: string): Promise<any>;
8
9
  getReleaseVersion(): Promise<string>;
9
10
  getSourceNodeInfo(layer: TessellationLayer): Promise<NodeInfo>;
10
11
  getSourceNodeLatestOrdinal(layer: TessellationLayer): Promise<number>;
11
12
  getSourceNodeOrdinalHash(layer: TessellationLayer, ordinal: number): Promise<string>;
12
- makeClusterRequest(path: string, layer?: TessellationLayer): Promise<any>;
13
+ makeClusterRequestGet(path: string, layer?: TessellationLayer): Promise<any>;
14
+ makeClusterRequestPost(path: string, body: string, layer?: TessellationLayer): Promise<any>;
13
15
  makeSourceNodeRequest(path: string, layer: TessellationLayer): Promise<any>;
16
+ postNodeParams(body: string, layer?: TessellationLayer): Promise<string>;
14
17
  };
@@ -30,17 +30,20 @@ export const clusterService = {
30
30
  spinner.stop();
31
31
  },
32
32
  async getClusterInfo(layer) {
33
- return this.makeClusterRequest('cluster/info', layer);
33
+ return this.makeClusterRequestGet('cluster/info', layer);
34
34
  },
35
35
  async getClusterNodeInfo(layer) {
36
- return this.makeClusterRequest('node/info', layer);
36
+ return this.makeClusterRequestGet('node/info', layer);
37
37
  },
38
38
  async getLatestConsensusInfo(layer) {
39
- return this.makeClusterRequest('consensus/latest/peers', layer);
39
+ return this.makeClusterRequestGet('consensus/latest/peers', layer);
40
40
  },
41
41
  getLayer0() {
42
42
  return configStore.getProjectInfo().layersToRun.includes('gl0') ? 'gl0' : 'ml0';
43
43
  },
44
+ async getNodeParams(id) {
45
+ return this.makeClusterRequestGet(`node-params/${id}`, 'gl0');
46
+ },
44
47
  async getReleaseVersion() {
45
48
  return this.getClusterNodeInfo().then(i => i.version);
46
49
  },
@@ -53,20 +56,40 @@ export const clusterService = {
53
56
  async getSourceNodeOrdinalHash(layer, ordinal) {
54
57
  return this.makeSourceNodeRequest(`global-snapshots/${ordinal}/hash`, layer);
55
58
  },
56
- async makeClusterRequest(path, layer) {
59
+ async makeClusterRequestGet(path, layer) {
57
60
  layer = layer || this.getLayer0();
58
61
  const { type } = configStore.getNetworkInfo();
59
62
  const envLayerInfo = configStore.getEnvLayerInfo(type, layer);
60
63
  if (envLayerInfo.CL_LB) {
61
64
  return fetch(`${envLayerInfo.CL_LB}/${path}`)
62
- .then(res => res.json())
65
+ .then(res => {
66
+ if (res.ok) {
67
+ return res.json();
68
+ }
69
+ if (res.status === 404) {
70
+ return null;
71
+ }
72
+ clm.debug(`Error ${res.status}. statusText: ${res.statusText}`);
73
+ throw new Error('Error');
74
+ })
63
75
  .catch(() => {
64
- clm.debug(`Failed to get node info from ${envLayerInfo.CL_LB}. Attempting source node...`);
76
+ clm.debug(`Failed to get node info from ${envLayerInfo.CL_LB}/${path}. Attempting source node...`);
65
77
  return this.makeSourceNodeRequest(path, layer);
66
78
  });
67
79
  }
68
80
  return this.makeSourceNodeRequest(path, layer);
69
81
  },
82
+ async makeClusterRequestPost(path, body, layer) {
83
+ layer = layer || this.getLayer0();
84
+ const { type } = configStore.getNetworkInfo();
85
+ const envLayerInfo = configStore.getEnvLayerInfo(type, layer);
86
+ return fetch(`${envLayerInfo.CL_LB}/${path}`, {
87
+ body,
88
+ headers: { 'Content-Type': 'application/json' },
89
+ method: 'POST'
90
+ })
91
+ .then(res => res.json());
92
+ },
70
93
  async makeSourceNodeRequest(path, layer) {
71
94
  const { type } = configStore.getNetworkInfo();
72
95
  const { CL_PUBLIC_HTTP_PORT } = configStore.getEnvLayerInfo(type, layer);
@@ -77,5 +100,8 @@ export const clusterService = {
77
100
  .catch(() => {
78
101
  throw new Error(`Unable to connect to source node at http://${CL_L0_PEER_HTTP_HOST}:${CL_PUBLIC_HTTP_PORT}/${path}`);
79
102
  });
103
+ },
104
+ async postNodeParams(body, layer) {
105
+ return this.makeClusterRequestPost(`node-params`, body, layer);
80
106
  }
81
107
  };
@@ -0,0 +1,26 @@
1
+ export declare const delegatedStakingService: {
2
+ configureNodeParams(): Promise<void>;
3
+ generateNodeParamPayload(rewardFraction: number, name: string, description: string, lastRef: {
4
+ hash: string;
5
+ ordinal: number;
6
+ }): Promise<string>;
7
+ getNodeParams(): Promise<{
8
+ description: string;
9
+ lastRef: {
10
+ hash: string;
11
+ ordinal: number;
12
+ };
13
+ name: string;
14
+ rewardFraction: number;
15
+ reward?: undefined;
16
+ } | {
17
+ description: string;
18
+ lastRef: {
19
+ hash: string;
20
+ ordinal: number;
21
+ };
22
+ name: string;
23
+ reward: number;
24
+ rewardFraction?: undefined;
25
+ }>;
26
+ };
@@ -0,0 +1,65 @@
1
+ import { input } from "@inquirer/prompts";
2
+ import chalk from "chalk";
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import { clm } from "../clm.js";
6
+ import { configStore } from "../config-store.js";
7
+ import { clusterService } from "./cluster-service.js";
8
+ import { shellService } from "./shell-service.js";
9
+ export const delegatedStakingService = {
10
+ async configureNodeParams() {
11
+ const np = await this.getNodeParams();
12
+ if (np.name) {
13
+ clm.postStep(String('\nEdit node parameters:\n\n Name: ' + chalk.cyan(np.name) + '\n Description: ' + chalk.cyan(np.description) + '\n Reward: ' + chalk.cyan(np.reward + '%') + "\n"));
14
+ }
15
+ else {
16
+ clm.postStep(String('------------------------------\nDelegated Staking Registration\n------------------------------\nFill out the parameters to enable delegation to your Validator Node:\n'));
17
+ }
18
+ const name = await input({
19
+ default: np.name, message: 'Name (5-140 chars):',
20
+ required: true, validate: (value) => value.length > 5 && value.length < 140
21
+ });
22
+ const description = await input({
23
+ default: np.description, message: 'Description (5-140 chars):',
24
+ required: true, validate: (value) => value.length > 5 && value.length < 140
25
+ });
26
+ const reward = await input({
27
+ default: String(np.reward), message: 'Commission % (5-10):', required: true,
28
+ validate: (value) => Number(value) >= 5 && Number(value) <= 10
29
+ });
30
+ const rewardFraction = Math.floor(Number(reward) * 1_000_000) / 100_000_000;
31
+ const payload = await this.generateNodeParamPayload(rewardFraction, name, description, np.lastRef);
32
+ // console.log(JSON.stringify(JSON.parse(payload),null,2));
33
+ const hash = await clusterService.postNodeParams(payload, 'gl0');
34
+ console.log(hash);
35
+ const { type } = configStore.getNetworkInfo();
36
+ clm.postStep(`Delegated Staking Page: https://${type}.dagexplorer.io/staking`);
37
+ },
38
+ async generateNodeParamPayload(rewardFraction, name, description, lastRef) {
39
+ name = name.replaceAll(/['"]/g, match => `\\${match}`);
40
+ description = description.replaceAll(/['"]/g, match => `\\${match}`);
41
+ rewardFraction = Math.max(.05, Math.min(.1, rewardFraction));
42
+ const env = configStore.getEnvInfo();
43
+ const { projectDir } = configStore.getProjectInfo();
44
+ fs.writeFileSync(path.join(projectDir, 'parent.json'), JSON.stringify(lastRef));
45
+ const command = `java -jar dist/wallet.jar create-node-params --reward-fraction ${rewardFraction} --name $'${name}' --description $'${description}' -p 'parent.json'`;
46
+ await shellService.runProjectCommand(command, env);
47
+ return fs.readFileSync(path.join(projectDir, 'event'), 'utf8');
48
+ },
49
+ async getNodeParams() {
50
+ const { nodeId } = configStore.getProjectInfo();
51
+ return clusterService.getNodeParams(nodeId)
52
+ .then((params) => {
53
+ if (!params) {
54
+ return { description: '', lastRef: { hash: '0000000000000000000000000000000000000000000000000000000000000000', ordinal: 0 }, name: '', rewardFraction: 5 };
55
+ }
56
+ // console.log(JSON.stringify(params,null,2));
57
+ return {
58
+ description: params.latest.value.nodeMetadataParameters.description,
59
+ lastRef: params.lastRef,
60
+ name: params.latest.value.nodeMetadataParameters.name,
61
+ reward: params.latest.value.delegatedStakeRewardParameters.rewardFraction / 1_000_000
62
+ };
63
+ });
64
+ }
65
+ };
@@ -7,6 +7,7 @@ export const migrationService = {
7
7
  const migrations = {
8
8
  '0.12.5': m0125,
9
9
  '0.13.9': m0139,
10
+ '0.14.0-intnet.1': m0140intnet1,
10
11
  // add more migrations as needed
11
12
  };
12
13
  const { version = '0.0.0' } = configStore.getProjectInfo();
@@ -31,6 +32,9 @@ export const migrationService = {
31
32
  configStore.setProjectInfo({ version: currentVersion.toString() });
32
33
  }
33
34
  };
35
+ function m0140intnet1() {
36
+ configStore.setProjectFlag('javaMemoryChecked', false);
37
+ }
34
38
  function m0139() {
35
39
  clm.step('Running migration 0.13.9...');
36
40
  configStore.setProjectFlag('javaMemoryChecked', false);
@@ -8,7 +8,7 @@ export const systemdService = {
8
8
  async install() {
9
9
  const platform = os.platform();
10
10
  if (platform !== 'linux') {
11
- clm.warn('Node Pilot services can only be installed on Linux systems. Skipping systemd service installation.\n');
11
+ clm.warn('systemd services can only be installed on Linux systems. Skipping...\n');
12
12
  return;
13
13
  }
14
14
  const scriptFile = path.resolve(path.dirname(fileURLToPath(import.meta.url)), `../../scripts/install_services.sh`);
@@ -22,7 +22,7 @@ export const systemdService = {
22
22
  async uninstall() {
23
23
  const platform = os.platform();
24
24
  if (platform !== 'linux') {
25
- clm.warn('Node Pilot services can only be installed on Linux systems. Skipping systemd service uninstallation.\n');
25
+ clm.warn('systemd services can only be installed on Linux systems. Skipping...\n');
26
26
  }
27
27
  const scriptFile = path.resolve(path.dirname(fileURLToPath(import.meta.url)), `../../scripts/uninstall_services.sh`);
28
28
  if (!fs.existsSync(scriptFile)) {
@@ -363,5 +363,5 @@
363
363
  ]
364
364
  }
365
365
  },
366
- "version": "0.14.0-testnet"
366
+ "version": "0.16.0-intnet"
367
367
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@constellation-network/node-pilot",
3
3
  "description": "An easy deployment and monitoring tool for Constellation nodes.",
4
- "version": "0.14.0-testnet",
4
+ "version": "0.16.0-intnet",
5
5
  "author": "Frank Fox",
6
6
  "bin": {
7
7
  "cpilot": "bin/run.js"
@@ -21,7 +21,7 @@
21
21
  "version": "oclif readme && git add README.md",
22
22
  "start": "./bin/dev.js",
23
23
  "debug": "DEBUG=true ./bin/dev.js",
24
- "pub": "npm publish --access public --tag testnet"
24
+ "pub": "npm publish --access public --tag intnet"
25
25
  },
26
26
  "types": "dist/index.d.ts",
27
27
  "engines": {
@@ -39,7 +39,7 @@ COPY dist/gl0.jar /app/jars/gl0.jar
39
39
  #COPY ./health-check /health-check
40
40
  #RUN chmod +x /health-check/bin/run.sh
41
41
  #RUN chmod +x /health-check/bin/hydrate.sh
42
- RUN npm install -g "@constellation-network/node-pilot-health-check@0.0.28"
42
+ RUN npm install -g "@constellation-network/node-pilot-health-check@0.0.31"
43
43
 
44
44
  # Add entrypoint
45
45
  COPY ./entrypoint.sh /app/entrypoint.sh
@@ -218,8 +218,8 @@ check_curl() {
218
218
 
219
219
  # Run all checks
220
220
  echo "🔍 Checking and installing required dependencies..."
221
- check_java
222
- check_java_home
221
+ #check_java
222
+ #check_java_home
223
223
  check_jq
224
224
  check_wget
225
225
  check_curl