@lightprotocol/zk-compression-cli 0.27.1-alpha.1 → 0.27.1-alpha.11

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 (104) hide show
  1. package/accounts/address_merkle_tree_amt1Ayt45jfbdw5YSo7iz6WZxUmnZsQTYXy82hVwyC2.json +1 -1
  2. package/accounts/address_merkle_tree_queue_aq1S9z4reTSQAdgWHGD2zDaS39sjGrAxbR31vxJ2F4F.json +1 -1
  3. package/accounts/batch_address_merkle_tree_EzKE84aVTkCUhDHLELqyJaq1Y7UVVmqxXqZjVHwHY3rK.json +14 -1
  4. package/accounts/{batch_state_merkle_tree_2_2Yb3fGo2E9aWLjY8KuESaqurYpGGhEeJr7eynKrSgXwS.json → batch_address_merkle_tree_amt2kaJA14v3urZbZvnc5v2np8jqvc4Z8zDep5wbtzx.json} +1 -1
  5. package/accounts/{batch_state_merkle_tree_HLKs5NJ8FXkJg8BrzJt56adFYYuwg5etzDtBbQYTsixu.json → batch_state_merkle_tree_bmt1LryLZUMmF7ZtqESaw7wifBXLfXHQYoE4GAmrahU.json} +1 -1
  6. package/accounts/batch_state_merkle_tree_bmt2UxoBxB9xWev4BkLvkGdapsz6sZGkzViPNph7VFi.json +1 -0
  7. package/accounts/batch_state_merkle_tree_bmt3ccLd4bqSVZVeCJnH1F6C8jNygAhaDfxDwePyyGb.json +1 -0
  8. package/accounts/batch_state_merkle_tree_bmt4d3p1a4YQgk9PeZv5s4DBUmbF5NxqYpk9HGjQsd8.json +1 -0
  9. package/accounts/batch_state_merkle_tree_bmt5yU97jC88YXTuSukYHa8Z5Bi2ZDUtmzfkDTA2mG2.json +1 -0
  10. package/accounts/{batched_output_queue_2_12wJT3xYd46rtjeqDU6CrtT8unqLjPiheggzqhN9YsyB.json → batched_output_queue_oq1na8gojfdUhsfCpyjNt6h4JaDWtHf1yQj4koBWfto.json} +1 -1
  11. package/accounts/{batched_output_queue_6L7SzhYB3anwEQ9cphpJ1U7Scwj57bx2xueReg7R9cKU.json → batched_output_queue_oq2UkeMsJLfXt2QHzim242SUi3nvjJs8Pn7Eac9H9vg.json} +1 -1
  12. package/accounts/batched_output_queue_oq3AxjekBWgo64gpauB6QtuZNesuv19xrhaC1ZM1THQ.json +1 -0
  13. package/accounts/batched_output_queue_oq4ypwvVGzCUMoiKKHWh4S1SgZJ9vCvKpcz6RT6A8dq.json +1 -0
  14. package/accounts/batched_output_queue_oq5oh5ZR3yGomuQgFduNDzjtGvVWfDRGLuDVjv9a96P.json +1 -0
  15. package/accounts/compressible_config_pda_ACXg8a7VaqecBWrSbdu73W4Pg9gsqXJ3EXAqkHyhvVXg.json +1 -0
  16. package/accounts/config_counter_pda_8gH9tmziWsS8Wc4fnoN5ax3jsSumNYoRDuSBvmH2GMH8.json +1 -0
  17. package/accounts/{test_batched_cpi_context_7Hp52chxaew8bW1ApR4fck2bh6Y8qA1pu3qwH6N9zaLj.json → cpi_context_cpi15BoVPKgEPw5o8wc2T816GE7b378nMXnhH3Xbq4y.json} +1 -1
  18. package/accounts/cpi_context_cpi1uHzrEhBG733DoEJNgHCyRS3XmmyVNZx5fonubE4.json +1 -1
  19. package/accounts/cpi_context_cpi2cdhkH5roePvcudTgUL8ppEBfTay1desGh8G8QxK.json +1 -1
  20. package/accounts/{cpi_context_batched_2_HwtjxDvFEXiWnzeMeWkMBzpQN45A95rTJNZmz1Z3pe8R.json → cpi_context_cpi2yGapXUR3As5SjnHBAVvmApNiLsbeZpF3euWnW6B.json} +1 -14
  21. package/accounts/cpi_context_cpi3mbwMpSX8FAGMZVP85AwxqCaQMfEk9Em1v8QK9Rf.json +1 -0
  22. package/accounts/cpi_context_cpi4yyPDc4bCgHAnsenunGA8Y77j3XEDyjgfyCKgcoc.json +1 -0
  23. package/accounts/cpi_context_cpi5ZTjdgYpZ1Xr7B1cMLLUE81oTtJbNNAyKary2nV6.json +1 -0
  24. package/accounts/epoch_pda_34w7KcLBXabMkHuXE2fY368vFe6kP3v5EJn8nPvQ8SKn.json +1 -1
  25. package/accounts/forester_epoch_pda_3FBt1BPQHCQkS8k3wrUXMfB6JBhtMhEqQXueHRw2ojZV.json +1 -1
  26. package/accounts/governance_authority_pda_CuEtcKkkbTn6qy2qxqDswq5U2ADsqoipYDAYfRvxPjcp.json +1 -1
  27. package/accounts/group_pda_24rt4RgeyjUCWGS2eF7L7gyNMuz6JWdqYpAvb1KRoHxs.json +1 -1
  28. package/accounts/merkle_tree_pubkey_smt1NamzXdq4AMqS2fS2F1i5KTYPZRhoHgWx38d8WsT.json +1 -1
  29. package/accounts/merkle_tree_pubkey_smt2rJAFdyJJupwMKAqTNAJwvjhmiZ4JYGZmbVRw1Ho.json +1 -1
  30. package/accounts/nullifier_queue_pubkey_nfq1NvQDJ2GEgnS8zt9prAe8rjjpAW1zFkrvZoBR148.json +1 -1
  31. package/accounts/nullifier_queue_pubkey_nfq2hgS7NYemXsFaFUCe3EMXSDSfnZnAe27jC6aPP1X.json +1 -1
  32. package/accounts/registered_forester_pda_2KNqEh23Se8AHecuzR1UkxL26euq2qXSpQPTH1jH7VqU.json +1 -1
  33. package/accounts/rent_sponsor_pda_r18WwUxfG8kQ69bQPAB2jV6zGNKy3GosFGctjQoV4ti.json +1 -0
  34. package/bin/account_compression.so +0 -0
  35. package/bin/light_compressed_token.so +0 -0
  36. package/bin/light_registry.so +0 -0
  37. package/bin/light_system_program_pinocchio.so +0 -0
  38. package/dist/commands/approve-and-mint-to/index.js +26 -29
  39. package/dist/commands/balance/index.js +12 -11
  40. package/dist/commands/compress-sol/index.js +13 -13
  41. package/dist/commands/compress-spl/index.js +19 -19
  42. package/dist/commands/config/config.js +67 -33
  43. package/dist/commands/create-mint/index.js +19 -20
  44. package/dist/commands/create-token-pool/index.js +9 -9
  45. package/dist/commands/decompress-sol/index.js +13 -13
  46. package/dist/commands/decompress-spl/index.js +19 -19
  47. package/dist/commands/init/index.js +8 -8
  48. package/dist/commands/merge-token-accounts/index.js +13 -14
  49. package/dist/commands/mint-to/index.js +24 -25
  50. package/dist/commands/start-prover/index.d.ts +0 -3
  51. package/dist/commands/start-prover/index.js +13 -58
  52. package/dist/commands/test-validator/index.d.ts +4 -2
  53. package/dist/commands/test-validator/index.js +107 -109
  54. package/dist/commands/token-balance/index.js +15 -15
  55. package/dist/commands/transfer/index.js +23 -24
  56. package/dist/psp-utils/download.js +1 -1
  57. package/dist/utils/constants.d.ts +2 -2
  58. package/dist/utils/constants.js +2 -3
  59. package/dist/utils/downloadProverBinary.d.ts +7 -0
  60. package/dist/utils/downloadProverBinary.js +107 -0
  61. package/dist/utils/initTestEnv.d.ts +12 -5
  62. package/dist/utils/initTestEnv.js +89 -16
  63. package/dist/utils/process.d.ts +10 -0
  64. package/dist/utils/process.js +56 -6
  65. package/dist/utils/processPhotonIndexer.d.ts +1 -1
  66. package/dist/utils/processPhotonIndexer.js +7 -4
  67. package/dist/utils/processProverServer.d.ts +1 -2
  68. package/dist/utils/processProverServer.js +70 -86
  69. package/dist/utils/proverVersion.generated.d.ts +1 -0
  70. package/dist/utils/proverVersion.generated.js +5 -0
  71. package/dist/utils/utils.d.ts +4 -0
  72. package/dist/utils/utils.js +44 -3
  73. package/oclif.manifest.json +173 -221
  74. package/package.json +63 -64
  75. package/test_bin/dev +4 -7
  76. package/test_bin/run +2 -2
  77. package/bin/forester +0 -0
  78. package/bin/forester.toml +0 -15
  79. package/bin/light_system_program.so +0 -0
  80. package/bin/prover-darwin-arm64 +0 -0
  81. package/bin/prover-darwin-x64 +0 -0
  82. package/bin/prover-linux-arm64 +0 -0
  83. package/bin/prover-linux-x64 +0 -0
  84. package/bin/proving-keys/combined_26_1_1.key +0 -0
  85. package/bin/proving-keys/combined_26_1_2.key +0 -0
  86. package/bin/proving-keys/combined_26_2_1.key +0 -0
  87. package/bin/proving-keys/combined_32_40_1_1.key +0 -0
  88. package/bin/proving-keys/combined_32_40_1_2.key +0 -0
  89. package/bin/proving-keys/combined_32_40_2_1.key +0 -0
  90. package/bin/proving-keys/inclusion_32_1.key +0 -0
  91. package/bin/proving-keys/inclusion_32_2.key +0 -0
  92. package/bin/proving-keys/inclusion_32_3.key +0 -0
  93. package/bin/proving-keys/inclusion_32_4.key +0 -0
  94. package/bin/proving-keys/mainnet_inclusion_26_1.key +0 -0
  95. package/bin/proving-keys/mainnet_inclusion_26_2.key +0 -0
  96. package/bin/proving-keys/mainnet_inclusion_26_3.key +0 -0
  97. package/bin/proving-keys/mainnet_inclusion_26_4.key +0 -0
  98. package/bin/proving-keys/non-inclusion_26_1.key +0 -0
  99. package/bin/proving-keys/non-inclusion_26_2.key +0 -0
  100. package/bin/proving-keys/non-inclusion_40_1.key +0 -0
  101. package/bin/proving-keys/non-inclusion_40_2.key +0 -0
  102. package/bin/proving-keys/non-inclusion_40_3.key +0 -0
  103. package/bin/proving-keys/non-inclusion_40_4.key +0 -0
  104. package/test_bin/lut.json +0 -1
@@ -1,103 +1,84 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.killProver = killProver;
4
- exports.isProverRunningWithFlags = isProverRunningWithFlags;
5
4
  exports.startProver = startProver;
6
5
  exports.getProverNameByArch = getProverNameByArch;
7
6
  exports.getProverPathByArch = getProverPathByArch;
8
7
  exports.healthCheck = healthCheck;
9
8
  const tslib_1 = require("tslib");
10
9
  const path_1 = tslib_1.__importDefault(require("path"));
10
+ const os_1 = tslib_1.__importDefault(require("os"));
11
+ const fs_1 = tslib_1.__importDefault(require("fs"));
12
+ const child_process_1 = require("child_process");
11
13
  const process_1 = require("./process");
12
14
  const constants_1 = require("./constants");
13
- const find_process_1 = tslib_1.__importDefault(require("find-process"));
14
- const KEYS_DIR = "proving-keys/";
15
+ const downloadProverBinary_1 = require("./downloadProverBinary");
16
+ const LIGHT_CONFIG_DIR = path_1.default.join(os_1.default.homedir(), ".config", "light");
17
+ const PROVER_BIN_DIR = path_1.default.join(LIGHT_CONFIG_DIR, "bin");
18
+ const KEYS_DIR = path_1.default.join(LIGHT_CONFIG_DIR, "proving-keys");
15
19
  async function killProver() {
16
20
  await (0, process_1.killProcess)(getProverNameByArch());
17
21
  await (0, process_1.killProcess)(constants_1.LIGHT_PROVER_PROCESS_NAME);
18
22
  }
19
- async function isProverRunningWithFlags(runMode, circuits, proverPort, redisUrl) {
20
- // Use find-process to get prover processes by name pattern
21
- const proverProcesses = await (0, find_process_1.default)("name", "prover-");
22
- const expectedArgs = [];
23
- if (runMode) {
24
- expectedArgs.push("--run-mode", runMode);
23
+ /**
24
+ * Gets the version of the installed prover binary
25
+ * Returns null if the binary doesn't exist or version command fails
26
+ */
27
+ function getInstalledProverVersion() {
28
+ const binaryPath = getProverPathByArch();
29
+ if (!fs_1.default.existsSync(binaryPath)) {
30
+ return null;
31
+ }
32
+ try {
33
+ const output = (0, child_process_1.execSync)(`"${binaryPath}" version`, {
34
+ encoding: "utf-8",
35
+ timeout: 5000,
36
+ }).trim();
37
+ // Extract version number (handles "v2.0.6", "light-prover v2.0.6", "2.0.6", etc.)
38
+ const match = output.match(/(\d+\.\d+\.\d+)/);
39
+ return match ? match[1] : null;
40
+ }
41
+ catch (error) {
42
+ return null;
25
43
  }
26
- if (Array.isArray(circuits)) {
27
- for (const c of circuits) {
28
- expectedArgs.push("--circuit", c);
29
- }
44
+ }
45
+ /**
46
+ * Ensures the prover binary exists with the correct version, downloading it if necessary
47
+ */
48
+ async function ensureProverBinary() {
49
+ const binaryPath = getProverPathByArch();
50
+ const binaryName = getProverNameByArch();
51
+ const expectedVersion = (0, downloadProverBinary_1.getProverVersion)();
52
+ const installedVersion = getInstalledProverVersion();
53
+ if (installedVersion === expectedVersion) {
54
+ return;
30
55
  }
31
- if (proverPort) {
32
- expectedArgs.push("--prover-address", `0.0.0.0:${proverPort}`);
56
+ if (installedVersion) {
57
+ console.log(`Prover binary version mismatch. Expected: ${expectedVersion}, Found: ${installedVersion}`);
58
+ console.log("Downloading correct version...");
33
59
  }
34
- if (redisUrl) {
35
- expectedArgs.push("--redis-url", redisUrl);
60
+ else if (fs_1.default.existsSync(binaryPath)) {
61
+ console.log("Prover binary found but version could not be determined. Downloading latest version...");
36
62
  }
37
- let found = false;
38
- for (const proc of proverProcesses) {
39
- if (proc.cmd &&
40
- (proc.cmd.includes("prover-") || proc.name.startsWith("prover-"))) {
41
- console.log("\n[Prover Process Detected]");
42
- console.log(` PID: ${proc.pid}`);
43
- console.log(` Command: ${proc.cmd}`);
44
- let matches = true;
45
- for (const arg of expectedArgs) {
46
- if (!proc.cmd.includes(arg)) {
47
- matches = false;
48
- break;
49
- }
50
- }
51
- if (matches) {
52
- found = true;
53
- console.log("\x1b[32m✔ Prover is already running with the same configuration.\x1b[0m");
54
- console.log(" To restart the prover, stop the process above or use the --force flag.\n");
55
- break;
56
- }
57
- else {
58
- const missing = proc.cmd
59
- ? expectedArgs.filter((arg) => !proc.cmd.includes(arg))
60
- : [];
61
- if (missing.length > 0) {
62
- console.log(` (Not a match for current request. Missing args: ${missing.join(", ")})`);
63
- }
64
- }
65
- }
63
+ else {
64
+ console.log("Prover binary not found. Downloading...");
66
65
  }
67
- if (!found) {
68
- console.log("\x1b[33mNo running prover found with the requested configuration.\x1b[0m");
66
+ try {
67
+ await (0, downloadProverBinary_1.downloadProverBinary)(binaryPath, binaryName);
69
68
  }
70
- return found;
71
- }
72
- async function startProver(proverPort, runMode, circuits = [], force = false, redisUrl) {
73
- if (!force &&
74
- (await isProverRunningWithFlags(runMode, circuits, proverPort))) {
75
- return;
69
+ catch (error) {
70
+ throw new Error(`Failed to download prover binary: ${error instanceof Error ? error.message : String(error)}\n` +
71
+ `Please download manually from: https://github.com/Lightprotocol/light-protocol/releases`);
76
72
  }
77
- console.log("Kill existing prover process...");
73
+ }
74
+ async function startProver(proverPort, redisUrl) {
75
+ await ensureProverBinary();
78
76
  await killProver();
79
77
  await (0, process_1.killProcessByPort)(proverPort);
80
- const keysDir = path_1.default.join(__dirname, "../..", "bin", KEYS_DIR);
81
78
  const args = ["start"];
82
- args.push("--keys-dir", keysDir);
79
+ args.push("--keys-dir", KEYS_DIR + "/");
83
80
  args.push("--prover-address", `0.0.0.0:${proverPort}`);
84
- if (runMode != null) {
85
- args.push("--run-mode", runMode);
86
- }
87
- for (const circuit of circuits) {
88
- args.push("--circuit", circuit);
89
- }
90
- if (runMode != null) {
91
- console.log(`Starting prover in ${runMode} mode...`);
92
- }
93
- else if (circuits && circuits.length > 0) {
94
- console.log(`Starting prover with circuits: ${circuits.join(", ")}...`);
95
- }
96
- if ((!circuits || circuits.length === 0) && runMode == null) {
97
- runMode = "local-rpc";
98
- args.push("--run-mode", runMode);
99
- console.log(`Starting prover with fallback ${runMode} mode...`);
100
- }
81
+ args.push("--auto-download", "true");
101
82
  if (redisUrl) {
102
83
  args.push("--redis-url", redisUrl);
103
84
  }
@@ -106,25 +87,28 @@ async function startProver(proverPort, runMode, circuits = [], force = false, re
106
87
  console.log(`Prover started successfully!`);
107
88
  }
108
89
  function getProverNameByArch() {
109
- const platform = process.platform;
110
- const arch = process.arch;
111
- if (!platform || !arch) {
90
+ const nodePlatform = process.platform;
91
+ const nodeArch = process.arch;
92
+ if (!nodePlatform || !nodeArch) {
112
93
  throw new Error("Unsupported platform or architecture");
113
94
  }
114
- let binaryName = `prover-${platform}-${arch}`;
115
- if (platform.toString() === "windows") {
116
- throw new Error("Windows OS support is not included in this NPM release. Please reach out to team@lightprotocol.com to get the Windows binary.");
117
- //@ts-ignore
95
+ let goPlatform = nodePlatform;
96
+ let goArch = nodeArch;
97
+ if (nodeArch === "x64") {
98
+ goArch = "amd64";
99
+ }
100
+ if (nodePlatform === "win32") {
101
+ goPlatform = "windows";
102
+ }
103
+ let binaryName = `prover-${goPlatform}-${goArch}`;
104
+ if (goPlatform === "windows") {
118
105
  binaryName += ".exe";
119
106
  }
120
107
  return binaryName;
121
108
  }
122
109
  function getProverPathByArch() {
123
- let binaryName = getProverNameByArch();
124
- // We need to provide the full path to the binary because it's not in the PATH.
125
- const binDir = path_1.default.join(__dirname, "../..", "bin");
126
- binaryName = path_1.default.join(binDir, binaryName);
127
- return binaryName;
110
+ const binaryName = getProverNameByArch();
111
+ return path_1.default.join(PROVER_BIN_DIR, binaryName);
128
112
  }
129
113
  async function healthCheck(port, retries = 3, timeout = 3000) {
130
114
  const fetch = (await Promise.resolve().then(() => tslib_1.__importStar(require("node-fetch")))).default;
@@ -0,0 +1 @@
1
+ export declare const PROVER_VERSION = "2.0.7";
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PROVER_VERSION = void 0;
4
+ // Auto-generated from prover/server/VERSION - do not edit manually
5
+ exports.PROVER_VERSION = "2.0.7";
@@ -1,6 +1,10 @@
1
1
  import * as anchor from "@coral-xyz/anchor";
2
2
  import { Keypair } from "@solana/web3.js";
3
3
  import { Rpc } from "@lightprotocol/stateless.js";
4
+ /**
5
+ * Get a Keypair from a secret key file (compatible with Solana CLI)
6
+ */
7
+ export declare function getKeypairFromFile(filepath?: string): Promise<Keypair>;
4
8
  export declare const defaultSolanaWalletKeypair: () => Keypair;
5
9
  export declare const setAnchorProvider: () => Promise<anchor.AnchorProvider>;
6
10
  export declare function rpc(): Rpc;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CustomLoader = exports.setConfig = exports.getConfig = exports.getProverUrl = exports.getIndexerUrl = exports.getSolanaRpcUrl = exports.setAnchorProvider = exports.defaultSolanaWalletKeypair = void 0;
4
+ exports.getKeypairFromFile = getKeypairFromFile;
4
5
  exports.rpc = rpc;
5
6
  exports.getPayer = getPayer;
6
7
  exports.generateSolanaTransactionURL = generateSolanaTransactionURL;
@@ -17,9 +18,45 @@ const web3_js_1 = require("@solana/web3.js");
17
18
  const stateless_js_1 = require("@lightprotocol/stateless.js");
18
19
  const bytes_1 = require("@coral-xyz/anchor/dist/cjs/utils/bytes");
19
20
  const constants_1 = require("./constants");
20
- const helpers_1 = require("@solana-developers/helpers");
21
21
  const cli_spinners_1 = tslib_1.__importDefault(require("cli-spinners"));
22
- require("dotenv").config();
22
+ const dotenv_1 = tslib_1.__importDefault(require("dotenv"));
23
+ dotenv_1.default.config();
24
+ /**
25
+ * Get a Keypair from a secret key file (compatible with Solana CLI)
26
+ */
27
+ async function getKeypairFromFile(filepath) {
28
+ // Default value from Solana CLI
29
+ const DEFAULT_FILEPATH = "~/.config/solana/id.json";
30
+ if (!filepath) {
31
+ filepath = DEFAULT_FILEPATH;
32
+ }
33
+ if (filepath[0] === "~") {
34
+ const home = process.env.HOME || null;
35
+ if (home) {
36
+ filepath = path.join(home, filepath.slice(1));
37
+ }
38
+ }
39
+ let fileContents;
40
+ try {
41
+ fileContents = fs.readFileSync(filepath, "utf8");
42
+ }
43
+ catch {
44
+ throw new Error(`Could not read keypair from file at '${filepath}'`);
45
+ }
46
+ // Parse contents of file
47
+ let parsedFileContents;
48
+ try {
49
+ parsedFileContents = Uint8Array.from(JSON.parse(fileContents));
50
+ }
51
+ catch (error_) {
52
+ const error = error_;
53
+ if (!error.message.includes("Unexpected token")) {
54
+ throw error;
55
+ }
56
+ throw new Error(`Invalid secret key file at '${filepath}'!`);
57
+ }
58
+ return web3_js_1.Keypair.fromSecretKey(parsedFileContents);
59
+ }
23
60
  const defaultSolanaWalletKeypair = () => {
24
61
  const walletPath = process.env.HOME + "/.config/solana/id.json";
25
62
  if (fs.existsSync(walletPath)) {
@@ -52,7 +89,7 @@ function getWalletPath() {
52
89
  return process.env.HOME + "/.config/solana/id.json";
53
90
  }
54
91
  async function getPayer() {
55
- return await (0, helpers_1.getKeypairFromFile)(getWalletPath());
92
+ return await getKeypairFromFile(getWalletPath());
56
93
  }
57
94
  function generateSolanaTransactionURL(transactionType, transactionHash, cluster) {
58
95
  return `https://explorer.solana.com/${transactionType}/${transactionHash}?cluster=${cluster}`;
@@ -131,6 +168,10 @@ const setConfig = (config, filePath) => {
131
168
  };
132
169
  exports.setConfig = setConfig;
133
170
  class CustomLoader {
171
+ message;
172
+ logInterval;
173
+ logTimer;
174
+ startTime;
134
175
  constructor(message, logInterval = 1000) {
135
176
  this.message = message;
136
177
  this.logInterval = logInterval;