@constellation-network/node-pilot 0.0.1

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 (81) hide show
  1. package/README.md +213 -0
  2. package/bin/dev.cmd +3 -0
  3. package/bin/dev.js +19 -0
  4. package/bin/run.cmd +3 -0
  5. package/bin/run.js +15 -0
  6. package/dist/checks/check-hardware.d.ts +3 -0
  7. package/dist/checks/check-hardware.js +50 -0
  8. package/dist/checks/check-initial-setup.d.ts +3 -0
  9. package/dist/checks/check-initial-setup.js +15 -0
  10. package/dist/checks/check-layers.d.ts +7 -0
  11. package/dist/checks/check-layers.js +87 -0
  12. package/dist/checks/check-network.d.ts +6 -0
  13. package/dist/checks/check-network.js +72 -0
  14. package/dist/checks/check-project.d.ts +6 -0
  15. package/dist/checks/check-project.js +108 -0
  16. package/dist/clm.d.ts +9 -0
  17. package/dist/clm.js +30 -0
  18. package/dist/commands/config/get.d.ts +9 -0
  19. package/dist/commands/config/get.js +37 -0
  20. package/dist/commands/config/set.d.ts +11 -0
  21. package/dist/commands/config/set.js +41 -0
  22. package/dist/commands/config.d.ts +6 -0
  23. package/dist/commands/config.js +65 -0
  24. package/dist/commands/info.d.ts +6 -0
  25. package/dist/commands/info.js +32 -0
  26. package/dist/commands/logs.d.ts +12 -0
  27. package/dist/commands/logs.js +28 -0
  28. package/dist/commands/restart.d.ts +6 -0
  29. package/dist/commands/restart.js +25 -0
  30. package/dist/commands/shutdown.d.ts +6 -0
  31. package/dist/commands/shutdown.js +18 -0
  32. package/dist/commands/status.d.ts +6 -0
  33. package/dist/commands/status.js +22 -0
  34. package/dist/commands/test.d.ts +6 -0
  35. package/dist/commands/test.js +13 -0
  36. package/dist/config-store.d.ts +109 -0
  37. package/dist/config-store.js +151 -0
  38. package/dist/helpers/config-helper.d.ts +14 -0
  39. package/dist/helpers/config-helper.js +39 -0
  40. package/dist/helpers/docker-helper.d.ts +7 -0
  41. package/dist/helpers/docker-helper.js +37 -0
  42. package/dist/helpers/env-templates.d.ts +4 -0
  43. package/dist/helpers/env-templates.js +33 -0
  44. package/dist/helpers/github-helper.d.ts +3 -0
  45. package/dist/helpers/github-helper.js +13 -0
  46. package/dist/helpers/key-file-helper.d.ts +9 -0
  47. package/dist/helpers/key-file-helper.js +136 -0
  48. package/dist/helpers/project-helper.d.ts +9 -0
  49. package/dist/helpers/project-helper.js +85 -0
  50. package/dist/helpers/prompt-helper.d.ts +8 -0
  51. package/dist/helpers/prompt-helper.js +135 -0
  52. package/dist/index.d.ts +1 -0
  53. package/dist/index.js +1 -0
  54. package/dist/info/cluster-info.d.ts +1 -0
  55. package/dist/info/cluster-info.js +16 -0
  56. package/dist/services/cluster-service.d.ts +9 -0
  57. package/dist/services/cluster-service.js +67 -0
  58. package/dist/services/fastforward-service.d.ts +14 -0
  59. package/dist/services/fastforward-service.js +84 -0
  60. package/dist/services/node-service.d.ts +10 -0
  61. package/dist/services/node-service.js +117 -0
  62. package/dist/services/shell-service.d.ts +9 -0
  63. package/dist/services/shell-service.js +53 -0
  64. package/dist/styles.d.ts +4 -0
  65. package/dist/styles.js +5 -0
  66. package/dist/types.d.ts +22 -0
  67. package/dist/types.js +1 -0
  68. package/oclif.manifest.json +241 -0
  69. package/package.json +98 -0
  70. package/projects/hypergraph/Dockerfile +41 -0
  71. package/projects/hypergraph/docker-compose.yml +54 -0
  72. package/projects/hypergraph/entrypoint.sh +35 -0
  73. package/projects/hypergraph/layers/gl1.env +3 -0
  74. package/projects/hypergraph/networks/integrationnet.env +9 -0
  75. package/projects/hypergraph/networks/mainnet.env +8 -0
  76. package/projects/hypergraph/networks/testnet.env +9 -0
  77. package/projects/hypergraph/pilot.env +2 -0
  78. package/projects/hypergraph/scripts/docker-build.sh +7 -0
  79. package/projects/hypergraph/scripts/install-dependencies.sh +318 -0
  80. package/projects/hypergraph/scripts/install.sh +149 -0
  81. package/projects/scripts/docker-cleanup.sh +64 -0
@@ -0,0 +1,37 @@
1
+ import { Args, Command } from '@oclif/core';
2
+ import { commonEnvNames, configStore, layerEnvNames } from "../../config-store.js";
3
+ import { configHelper } from "../../helpers/config-helper.js";
4
+ export default class ConfigGet extends Command {
5
+ static args = {
6
+ name: Args.string({ description: 'configuration to get' }),
7
+ };
8
+ static description = 'Show all configuration settings or a specific one';
9
+ static examples = [
10
+ '<%= config.bin %> <%= command.id %>',
11
+ '<%= config.bin %> <%= command.id %> CL_EXTERNAL_IP',
12
+ '<%= config.bin %> <%= command.id %> gl0:CL_PUBLIC_HTTP_PORT',
13
+ ];
14
+ async run() {
15
+ configHelper.assertProject('No configuration found. ');
16
+ const { args } = await this.parse(ConfigGet);
17
+ const info = configStore.getEnvInfo();
18
+ const { layersToRun } = configStore.getProjectInfo();
19
+ const common = info.common;
20
+ const layers = info.layers;
21
+ if (Object.keys(args).length === 0 || args.name === undefined) {
22
+ const commonsList = Object.keys(commonEnvNames).sort().map(k => ({ name: k, value: common[k] }));
23
+ const layersList = layersToRun.map(l => (Object.keys(layerEnvNames).map(k => ({ name: `${l}:${k}`, value: layers[l][k] }))));
24
+ // const layersList = layersToRun.map(l => (Object.keys(layerEnvNames).map(k => `${l}:${k}="${green(layers[l][k] || '')}"`)))
25
+ configHelper.showEnvInfoList(commonsList);
26
+ configHelper.showEnvInfoList(layersList.flat());
27
+ }
28
+ else if (args.name.includes(':')) {
29
+ const [layer, name] = args.name.split(':');
30
+ configHelper.showEnvInfo(args.name, layers[layer][name]);
31
+ }
32
+ else {
33
+ // const props = keyof EnvCommonInfo
34
+ configHelper.showEnvInfo(args.name, common[args.name]);
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,11 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class ConfigSet extends Command {
3
+ static args: {
4
+ name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
+ value: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
+ };
7
+ static description: string;
8
+ static examples: string[];
9
+ logErrorAndExit(message: string): void;
10
+ run(): Promise<void>;
11
+ }
@@ -0,0 +1,41 @@
1
+ import { Args, Command } from '@oclif/core';
2
+ import { commonEnvNames, configStore, layerEnvNames } from "../../config-store.js";
3
+ import { configHelper } from "../../helpers/config-helper.js";
4
+ export default class ConfigSet extends Command {
5
+ static args = {
6
+ name: Args.string({ description: 'configuration name', required: true }),
7
+ value: Args.string({ description: 'the value to set to the configuration', required: true }),
8
+ };
9
+ static description = 'Set a configuration setting';
10
+ static examples = [
11
+ '<%= config.bin %> <%= command.id %> CL_EXTERNAL_IP 127.0.0.1',
12
+ '<%= config.bin %> <%= command.id %> gl0:CL_PUBLIC_HTTP_PORT 9000',
13
+ ];
14
+ logErrorAndExit(message) {
15
+ this.log(message);
16
+ this.exit(0);
17
+ }
18
+ async run() {
19
+ configHelper.assertProject('No configuration found. ');
20
+ const { args } = await this.parse(ConfigSet);
21
+ const { layersToRun } = configStore.getProjectInfo();
22
+ if (args.name.includes(':')) {
23
+ const [layer, name] = args.name.split(':');
24
+ if (!layersToRun.includes(layer)) {
25
+ this.logErrorAndExit(`Invalid layer: ${layer}. Available layers: ${layersToRun.join(',')}`);
26
+ }
27
+ const validLayer = layer;
28
+ if (!Object.hasOwn(layerEnvNames, name)) {
29
+ this.logErrorAndExit(`Invalid layer configuration name: ${name}`);
30
+ }
31
+ configStore.setEnvLayerInfo(validLayer, { [name]: args.value });
32
+ }
33
+ else {
34
+ const { name } = args;
35
+ if (!Object.hasOwn(commonEnvNames, name)) {
36
+ this.logErrorAndExit(`Invalid configuration name: ${name}`);
37
+ }
38
+ configStore.setEnvCommonInfo({ [name]: args.value });
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,6 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Config extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
@@ -0,0 +1,65 @@
1
+ import { select } from '@inquirer/prompts';
2
+ import { Command } from '@oclif/core';
3
+ import { checkNetwork } from "../checks/check-network.js";
4
+ import { checkProject } from "../checks/check-project.js";
5
+ import { clm } from "../clm.js";
6
+ import { configStore } from "../config-store.js";
7
+ import { configHelper } from "../helpers/config-helper.js";
8
+ import { dockerHelper } from "../helpers/docker-helper.js";
9
+ import { keyFileHelper } from "../helpers/key-file-helper.js";
10
+ import { promptHelper } from "../helpers/prompt-helper.js";
11
+ export default class Config extends Command {
12
+ static description = 'Update configuration settings';
13
+ static examples = [
14
+ '<%= config.bin %> <%= command.id %>'
15
+ ];
16
+ async run() {
17
+ configHelper.assertProject('No configuration found. ');
18
+ let { name } = configStore.getProjectInfo();
19
+ name = name.charAt(0).toUpperCase() + name.slice(1);
20
+ const answer = await select({
21
+ choices: [
22
+ { name: 'Auto Restart', value: 'autoRestart' },
23
+ { name: 'External IP Address', value: 'externalIp' },
24
+ { name: 'Java Memory', value: 'javaMemory' },
25
+ { name: 'Key File', value: 'keyFile' },
26
+ { name: `${name} - Layers To Run`, value: 'layersToRun' },
27
+ { name: `Network (mainnet, testnet or intnet)`, value: 'network' },
28
+ ],
29
+ message: 'What would you like to change?:',
30
+ });
31
+ // eslint-disable-next-line unicorn/prefer-switch
32
+ if (answer === 'autoRestart') {
33
+ await promptHelper.configureAutoRestart();
34
+ }
35
+ else if (answer === 'externalIp') {
36
+ await checkNetwork.configureIpAddress();
37
+ }
38
+ else if (answer === 'javaMemory') {
39
+ await promptHelper.configureJavaMemoryArguments();
40
+ if (await dockerHelper.isRunning()) {
41
+ clm.preStep('The validator node must be restarted before changes can be applied.');
42
+ await promptHelper.doYouWishToContinue();
43
+ await dockerHelper.dockerDown();
44
+ await dockerHelper.dockerUp();
45
+ }
46
+ }
47
+ else if (answer === 'keyFile') {
48
+ await keyFileHelper.showKeyFileInfo();
49
+ await keyFileHelper.promptForKeyFile();
50
+ }
51
+ else if (answer === 'layersToRun') {
52
+ if (await dockerHelper.isRunning()) {
53
+ clm.preStep('The validator node must be stopped first.');
54
+ await promptHelper.doYouWishToContinue();
55
+ await dockerHelper.dockerDown();
56
+ }
57
+ await promptHelper.selectLayers();
58
+ await promptHelper.configureJavaMemoryArguments();
59
+ }
60
+ else if (answer === 'network') {
61
+ await promptHelper.selectNetwork();
62
+ await checkProject.runInstall();
63
+ }
64
+ }
65
+ }
@@ -0,0 +1,6 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Info extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
@@ -0,0 +1,32 @@
1
+ import { Command } from '@oclif/core';
2
+ import { configStore } from "../config-store.js";
3
+ import { configHelper } from "../helpers/config-helper.js";
4
+ export default class Info extends Command {
5
+ static description = 'Display general info about the validator node';
6
+ static examples = [
7
+ '<%= config.bin %> <%= command.id %>',
8
+ ];
9
+ async run() {
10
+ configHelper.assertProject('No project info found. ');
11
+ const projectInfo = configStore.getProjectInfo();
12
+ const networkInfo = configStore.getNetworkInfo();
13
+ // Project Name
14
+ configHelper.showEnvInfo('Project Name', projectInfo.name);
15
+ // DAG Address
16
+ configHelper.showEnvInfo('DAG Address', projectInfo.dagAddress);
17
+ // Node ID
18
+ configHelper.showEnvInfo('Node ID', projectInfo.nodeId);
19
+ // Layers to Run
20
+ configHelper.showEnvInfo('Layers to Run', projectInfo.layersToRun.join(', '));
21
+ // Network type
22
+ configHelper.showEnvInfo('Network', networkInfo.type);
23
+ // Network version
24
+ configHelper.showEnvInfo('Network Version', networkInfo.version);
25
+ // Project Directory
26
+ configHelper.showEnvInfo('Project Directory', projectInfo.projectDir);
27
+ // Fast Forward
28
+ configHelper.showEnvInfo('Fast Forward Enabled', (projectInfo.fastForward === undefined || Boolean(projectInfo.fastForward)).toString());
29
+ // Auto Restart
30
+ configHelper.showEnvInfo('Auto Restart Enabled', Boolean(projectInfo.autoRestart).toString());
31
+ }
32
+ }
@@ -0,0 +1,12 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Logs extends Command {
3
+ static args: {
4
+ layer: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ follow: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ }
@@ -0,0 +1,28 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import path from "node:path";
3
+ import { shellService } from "../services/shell-service.js";
4
+ import { configStore } from "../config-store.js";
5
+ import { configHelper } from "../helpers/config-helper.js";
6
+ export default class Logs extends Command {
7
+ static args = {
8
+ layer: Args.string({ description: 'network layer to view. e.g. gl0' }),
9
+ };
10
+ static description = 'view validator node runtime logs';
11
+ static examples = [
12
+ '<%= config.bin %> <%= command.id %>',
13
+ ];
14
+ static flags = {
15
+ follow: Flags.boolean({ char: 'f', description: 'continuously wait for additional data to be appended' }),
16
+ };
17
+ async run() {
18
+ configHelper.assertProject('No project found. ');
19
+ let tailFlag = '';
20
+ const { flags } = await this.parse(Logs);
21
+ if (flags.follow) {
22
+ tailFlag = '-f';
23
+ }
24
+ const { projectDir } = configStore.getProjectInfo();
25
+ const logPath = path.join(projectDir, 'app-data', 'gl0-logs', 'app.log');
26
+ await shellService.runCommand(`tail ${tailFlag} ${logPath}`).catch(() => 1);
27
+ }
28
+ }
@@ -0,0 +1,6 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Restart extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
@@ -0,0 +1,25 @@
1
+ import { Command } from '@oclif/core';
2
+ import { checkProject } from "../checks/check-project.js";
3
+ import { clm } from "../clm.js";
4
+ import { configStore } from "../config-store.js";
5
+ import { configHelper } from "../helpers/config-helper.js";
6
+ import { dockerHelper } from "../helpers/docker-helper.js";
7
+ import { nodeService } from "../services/node-service.js";
8
+ export default class Restart extends Command {
9
+ static description = 'A full shutdown of the validator node, then restart';
10
+ static examples = [
11
+ '<%= config.bin %> <%= command.id %>',
12
+ ];
13
+ async run() {
14
+ configHelper.assertProject('No project found. ');
15
+ const { layersToRun } = configStore.getProjectInfo();
16
+ await nodeService.leaveClusterAllLayers();
17
+ await nodeService.pollForLayersState(layersToRun, 'Offline');
18
+ clm.preStep('Stopping the node...');
19
+ await dockerHelper.dockerDown();
20
+ clm.preStep('Checking for a new version...');
21
+ await checkProject.runUpgrade();
22
+ clm.preStep('Starting the node...');
23
+ await dockerHelper.dockerUp();
24
+ }
25
+ }
@@ -0,0 +1,6 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Shutdown extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
@@ -0,0 +1,18 @@
1
+ import { Command } from '@oclif/core';
2
+ import { configStore } from "../config-store.js";
3
+ import { dockerHelper } from "../helpers/docker-helper.js";
4
+ import { nodeService } from "../services/node-service.js";
5
+ import { configHelper } from "../helpers/config-helper.js";
6
+ export default class Shutdown extends Command {
7
+ static description = 'A full shutdown of the validator node';
8
+ static examples = [
9
+ '<%= config.bin %> <%= command.id %>',
10
+ ];
11
+ async run() {
12
+ configHelper.assertProject('No project found. ');
13
+ const { layersToRun } = configStore.getProjectInfo();
14
+ await nodeService.leaveClusterAllLayers();
15
+ await nodeService.pollForLayersState(layersToRun, 'Offline');
16
+ await dockerHelper.dockerDown();
17
+ }
18
+ }
@@ -0,0 +1,6 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Status extends Command {
3
+ static description: string;
4
+ run(): Promise<void>;
5
+ }
6
+ export declare function checkInstallationAndConfigurationStatus(): Promise<void>;
@@ -0,0 +1,22 @@
1
+ import { Command } from '@oclif/core';
2
+ import { checkInitialSetup } from "../checks/check-initial-setup.js";
3
+ import { checkLayers } from "../checks/check-layers.js";
4
+ import { checkProject } from "../checks/check-project.js";
5
+ import { keyFileHelper } from "../helpers/key-file-helper.js";
6
+ export default class Status extends Command {
7
+ // eslint-disable-next-line no-warning-comments
8
+ // TODO add -f flag to continuously monitor status
9
+ static description = 'Display node status and configuration settings';
10
+ async run() {
11
+ await checkInstallationAndConfigurationStatus();
12
+ }
13
+ }
14
+ export async function checkInstallationAndConfigurationStatus() {
15
+ await checkInitialSetup.firstTimeRun();
16
+ await checkProject.projectInstallation();
17
+ await checkProject.releaseVersion();
18
+ await keyFileHelper.promptIfNoKeyFile();
19
+ await checkLayers.layersRunning();
20
+ await checkLayers.layersReadyToJoin();
21
+ await checkLayers.layersStatus();
22
+ }
@@ -0,0 +1,6 @@
1
+ import { Command } from "@oclif/core";
2
+ export default class Test extends Command {
3
+ static description: string;
4
+ static hidden: boolean;
5
+ run(): Promise<void>;
6
+ }
@@ -0,0 +1,13 @@
1
+ import { Command } from "@oclif/core";
2
+ import fs from "node:fs";
3
+ export default class Test extends Command {
4
+ static description = 'node pilot test command';
5
+ static hidden = true;
6
+ async run() {
7
+ // await promptHelper.configureJavaMemoryArguments();
8
+ const r = fs.statfsSync('/');
9
+ const totalSpace = (r.bsize * r.blocks / (1024 * 1024 * 1024)).toFixed(2);
10
+ const totalFreeSpace = (r.bsize * r.bfree / (1024 * 1024 * 1024)).toFixed(2);
11
+ console.log(totalSpace, totalFreeSpace);
12
+ }
13
+ }
@@ -0,0 +1,109 @@
1
+ import { TessellationLayer } from "./types.js";
2
+ declare class ConfigStore {
3
+ private pilotStore;
4
+ private projectStore;
5
+ constructor();
6
+ applyNewProjectStore(name: string): Promise<void>;
7
+ changeProjectStore(name: string): void;
8
+ getDockerEnvInfo(): object;
9
+ getEnvCommonInfo(): EnvCommonInfo;
10
+ getEnvInfo(): EnvInfo;
11
+ getEnvLayerInfo(layer: TessellationLayer): EnvLayerInfo;
12
+ getLayerPortInfo(layer: TessellationLayer): PortInfo;
13
+ getNetworkEnvInfo(network: NetworkType): EnvCommonInfo;
14
+ getNetworkInfo(): NetworkInfo;
15
+ getProjectInfo(): ProjectInfo;
16
+ getSystemInfo(): SystemInfo;
17
+ hasProjects(): boolean;
18
+ setDockerEnvInfo(info: Partial<{
19
+ DOCKER_IMAGE_VERSION: string;
20
+ DOCKER_USER_ID: string;
21
+ }>): void;
22
+ setEnvCommonInfo(info: Partial<EnvCommonInfo>): void;
23
+ setEnvInfo(info: DeepPartial<EnvInfo>): void;
24
+ setEnvLayerInfo(layer: TessellationLayer, info: Partial<EnvLayerInfo>): void;
25
+ setNetworkEnvInfo(info: NetworkEnvInfo): void;
26
+ setNetworkInfo(info: Partial<NetworkInfo>): void;
27
+ setProjectInfo(info: Partial<ProjectInfo>): void;
28
+ setSystemInfo(info: SystemInfo): void;
29
+ }
30
+ export declare const configStore: ConfigStore;
31
+ type DeepPartial<T> = {
32
+ [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
33
+ };
34
+ export type EnvInfo = {
35
+ common: EnvCommonInfo;
36
+ layers: Record<TessellationLayer, EnvLayerInfo>;
37
+ };
38
+ export type EnvCommonInfo = {
39
+ CL_APP_ENV: string;
40
+ CL_EXTERNAL_IP: string;
41
+ CL_GLOBAL_L0_PEER_HOST: string;
42
+ CL_GLOBAL_L0_PEER_HTTP_PORT: string;
43
+ CL_GLOBAL_L0_PEER_ID: string;
44
+ CL_KEYALIAS: string;
45
+ CL_KEYSTORE: string;
46
+ CL_L0_PEER_HTTP_HOST: string;
47
+ CL_L0_PEER_HTTP_PORT: string;
48
+ CL_L0_PEER_ID: string;
49
+ CL_L0_PEER_P2P_PORT: string;
50
+ CL_L0_TOKEN_IDENTIFIER: string;
51
+ CL_PASSWORD: string;
52
+ };
53
+ export declare const commonEnvNames: {
54
+ CL_APP_ENV: number;
55
+ CL_EXTERNAL_IP: number;
56
+ CL_GLOBAL_L0_PEER_HOST: number;
57
+ CL_GLOBAL_L0_PEER_HTTP_PORT: number;
58
+ CL_GLOBAL_L0_PEER_ID: number;
59
+ CL_KEYALIAS: number;
60
+ CL_KEYSTORE: number;
61
+ CL_L0_PEER_HTTP_HOST: number;
62
+ CL_L0_PEER_HTTP_PORT: number;
63
+ CL_L0_PEER_ID: number;
64
+ CL_L0_TOKEN_IDENTIFIER: number;
65
+ CL_PASSWORD: number;
66
+ };
67
+ export type EnvLayerInfo = {
68
+ CL_CLI_HTTP_PORT: string;
69
+ CL_DOCKER_JAVA_OPTS: string;
70
+ CL_P2P_HTTP_PORT: string;
71
+ CL_PUBLIC_HTTP_PORT: string;
72
+ };
73
+ export declare const layerEnvNames: {
74
+ CL_CLI_HTTP_PORT: number;
75
+ CL_DOCKER_JAVA_OPTS: number;
76
+ CL_P2P_HTTP_PORT: number;
77
+ CL_PUBLIC_HTTP_PORT: number;
78
+ };
79
+ export type SystemInfo = {
80
+ cores?: number;
81
+ disk?: string;
82
+ memory?: string;
83
+ platform?: string;
84
+ };
85
+ export type NetworkType = 'integrationnet' | 'mainnet' | 'testnet';
86
+ export type ProjectInfo = {
87
+ autoRestart: boolean;
88
+ autoStart: boolean;
89
+ autoUpdate: boolean;
90
+ dagAddress: string;
91
+ fastForward: boolean;
92
+ homeDir: string;
93
+ layersToRun: TessellationLayer[];
94
+ name: string;
95
+ nodeId: string;
96
+ projectDir: string;
97
+ };
98
+ export type NetworkInfo = {
99
+ supportedTypes: NetworkType[];
100
+ type: NetworkType;
101
+ version: string;
102
+ };
103
+ export type NetworkEnvInfo = Record<NetworkType, EnvCommonInfo>;
104
+ export type PortInfo = {
105
+ CLI: string;
106
+ P2P: string;
107
+ PUBLIC: string;
108
+ };
109
+ export {};
@@ -0,0 +1,151 @@
1
+ import { input } from "@inquirer/prompts";
2
+ import { JSONStorage } from "node-localstorage";
3
+ import fs from "node:fs";
4
+ import os from "node:os";
5
+ import path from "node:path";
6
+ import { clm } from "./clm.js";
7
+ class EmptyStorage extends JSONStorage {
8
+ constructor() { super("/tmp"); }
9
+ getItem(_key) { return null; }
10
+ setItem(_key, _value) { }
11
+ }
12
+ class ConfigStore {
13
+ pilotStore;
14
+ projectStore;
15
+ constructor() {
16
+ const appDir = path.join(os.homedir(), '.node-pilot');
17
+ if (!fs.existsSync(appDir)) {
18
+ fs.mkdirSync(appDir, { recursive: true });
19
+ }
20
+ this.pilotStore = new JSONStorage(path.join(appDir, 'config'));
21
+ const appInfo = this.pilotStore.getItem('pilot');
22
+ if (!appInfo) {
23
+ this.pilotStore.setItem('pilot', { appDir, project: 'undefined', projects: [] });
24
+ }
25
+ const { project } = this.pilotStore.getItem('pilot');
26
+ this.projectStore = project === 'undefined' ? new EmptyStorage() : new JSONStorage(path.join(appDir, project, 'config'));
27
+ }
28
+ async applyNewProjectStore(name) {
29
+ const { appDir, projects } = this.pilotStore.getItem('pilot');
30
+ const projectDir = path.join(appDir, name);
31
+ if (projects.includes(name)) {
32
+ const answer = await input({ default: 'n', message: `Project ${name} already exists. Do you want to reinstall? (y/n):` });
33
+ if (answer === 'y') {
34
+ this.projectStore = new JSONStorage(path.join(projectDir, 'config'));
35
+ this.projectStore.clear();
36
+ fs.rmSync(projectDir, { force: true, recursive: true });
37
+ this.pilotStore.setItem('pilot', { appDir, project: name, projects });
38
+ }
39
+ else {
40
+ clm.error(`Project ${name} already exists.`);
41
+ }
42
+ }
43
+ else {
44
+ this.pilotStore.setItem('pilot', { appDir, project: name, projects: [...projects, name] });
45
+ }
46
+ fs.mkdirSync(path.join(projectDir, 'config'), { recursive: true });
47
+ this.projectStore = new JSONStorage(path.join(projectDir, 'config'));
48
+ this.setDockerEnvInfo({ DOCKER_IMAGE_VERSION: 'test' });
49
+ this.setProjectInfo({ name, projectDir });
50
+ this.setEnvInfo({ common: { CL_GLOBAL_L0_PEER_HTTP_PORT: '9000' }, layers: { gl0: { CL_PUBLIC_HTTP_PORT: "9000" } } });
51
+ }
52
+ changeProjectStore(name) {
53
+ const { appDir, projects } = this.pilotStore.getItem('pilot');
54
+ if (projects && projects.includes(name)) {
55
+ this.projectStore = new JSONStorage(path.join(appDir, name, 'config'));
56
+ }
57
+ else {
58
+ throw new Error(`Project ${name} doesn't exist.`);
59
+ }
60
+ }
61
+ getDockerEnvInfo() {
62
+ return this.projectStore.getItem('docker');
63
+ }
64
+ getEnvCommonInfo() {
65
+ return this.projectStore.getItem('env')?.common;
66
+ }
67
+ getEnvInfo() {
68
+ return this.projectStore.getItem('env');
69
+ }
70
+ getEnvLayerInfo(layer) {
71
+ const envInfo = this.projectStore.getItem('env');
72
+ if (!envInfo)
73
+ return {};
74
+ return { ...envInfo.common, ...envInfo.layers[layer] };
75
+ }
76
+ getLayerPortInfo(layer) {
77
+ const layerInfo = this.getEnvLayerInfo(layer);
78
+ return { CLI: layerInfo.CL_CLI_HTTP_PORT, P2P: layerInfo.CL_P2P_HTTP_PORT, PUBLIC: layerInfo.CL_PUBLIC_HTTP_PORT };
79
+ }
80
+ getNetworkEnvInfo(network) {
81
+ const info = this.projectStore.getItem('network-env');
82
+ return info ? info[network] : {};
83
+ }
84
+ getNetworkInfo() {
85
+ return this.projectStore.getItem('network');
86
+ }
87
+ getProjectInfo() {
88
+ return this.projectStore.getItem('project');
89
+ }
90
+ getSystemInfo() {
91
+ return this.pilotStore.getItem('system');
92
+ }
93
+ hasProjects() {
94
+ const { projects } = this.pilotStore.getItem('pilot');
95
+ return projects.length > 0;
96
+ }
97
+ setDockerEnvInfo(info) {
98
+ const oldInfo = this.projectStore.getItem('docker');
99
+ this.projectStore.setItem('docker', { ...oldInfo, ...info });
100
+ }
101
+ setEnvCommonInfo(info) {
102
+ const oldInfo = this.projectStore.getItem('env');
103
+ this.projectStore.setItem('env', { common: { ...oldInfo.common, ...info }, layers: oldInfo.layers });
104
+ }
105
+ setEnvInfo(info) {
106
+ const oldInfo = this.projectStore.getItem('env');
107
+ this.projectStore.setItem('env', { ...oldInfo, ...info });
108
+ }
109
+ setEnvLayerInfo(layer, info) {
110
+ const envInfo = this.projectStore.getItem('env');
111
+ const { common, layers } = envInfo;
112
+ this.projectStore.setItem('env', { common, layers: { ...layers, [layer]: { ...layers[layer], ...info } } });
113
+ }
114
+ setNetworkEnvInfo(info) {
115
+ const oldInfo = this.projectStore.getItem('network-env');
116
+ this.projectStore.setItem('network-env', { ...oldInfo, ...info });
117
+ }
118
+ setNetworkInfo(info) {
119
+ const oldInfo = this.projectStore.getItem('network');
120
+ this.projectStore.setItem('network', { ...oldInfo, ...info });
121
+ }
122
+ setProjectInfo(info) {
123
+ const oldInfo = this.projectStore.getItem('project');
124
+ this.projectStore.setItem('project', { ...oldInfo, ...info });
125
+ }
126
+ setSystemInfo(info) {
127
+ const oldInfo = this.projectStore.getItem('system');
128
+ this.pilotStore.setItem('system', { ...oldInfo, ...info });
129
+ }
130
+ }
131
+ export const configStore = new ConfigStore();
132
+ export const commonEnvNames = {
133
+ CL_APP_ENV: 1,
134
+ CL_EXTERNAL_IP: 1,
135
+ CL_GLOBAL_L0_PEER_HOST: 1,
136
+ CL_GLOBAL_L0_PEER_HTTP_PORT: 1,
137
+ CL_GLOBAL_L0_PEER_ID: 1,
138
+ CL_KEYALIAS: 1,
139
+ CL_KEYSTORE: 1,
140
+ CL_L0_PEER_HTTP_HOST: 1,
141
+ CL_L0_PEER_HTTP_PORT: 1,
142
+ CL_L0_PEER_ID: 1,
143
+ CL_L0_TOKEN_IDENTIFIER: 1,
144
+ CL_PASSWORD: 1
145
+ };
146
+ export const layerEnvNames = {
147
+ CL_CLI_HTTP_PORT: 1,
148
+ CL_DOCKER_JAVA_OPTS: 1,
149
+ CL_P2P_HTTP_PORT: 1,
150
+ CL_PUBLIC_HTTP_PORT: 1,
151
+ };
@@ -0,0 +1,14 @@
1
+ import dotenv from "dotenv";
2
+ export declare const configHelper: {
3
+ assertProject(prefix?: string): void;
4
+ getReleaseInfo(): Promise<{
5
+ network: string;
6
+ version: string;
7
+ } | undefined>;
8
+ parseEnvFile(filePath: string): dotenv.DotenvParseOutput;
9
+ showEnvInfo(name: string, value: string): void;
10
+ showEnvInfoList(list: {
11
+ name: string;
12
+ value: string;
13
+ }[]): void;
14
+ };