@lightprotocol/zk-compression-cli 0.27.1-alpha.4 → 0.27.1-alpha.6

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.
Binary file
Binary file
@@ -119,11 +119,15 @@ async function initTestEnv({ additionalPrograms, skipSystemAccounts, indexer = t
119
119
  });
120
120
  await (0, process_1.waitForServers)([{ port: rpcPort, path: "/health" }]);
121
121
  await (0, process_1.confirmServerStability)(`http://127.0.0.1:${rpcPort}/health`);
122
+ await (0, process_1.confirmRpcReadiness)(`http://127.0.0.1:${rpcPort}`);
122
123
  if (indexer) {
123
124
  const config = (0, utils_1.getConfig)();
124
125
  config.indexerUrl = `http://127.0.0.1:${indexerPort}`;
125
126
  (0, utils_1.setConfig)(config);
126
- await (0, processPhotonIndexer_1.startIndexer)(`http://127.0.0.1:${rpcPort}`, indexerPort, checkPhotonVersion, photonDatabaseUrl);
127
+ const proverUrlForIndexer = prover
128
+ ? `http://127.0.0.1:${proverPort}`
129
+ : undefined;
130
+ await (0, processPhotonIndexer_1.startIndexer)(`http://127.0.0.1:${rpcPort}`, indexerPort, checkPhotonVersion, photonDatabaseUrl, proverUrlForIndexer);
127
131
  }
128
132
  if (prover) {
129
133
  const config = (0, utils_1.getConfig)();
@@ -33,3 +33,13 @@ export declare function waitForServers(servers: {
33
33
  path: string;
34
34
  }[]): Promise<void>;
35
35
  export declare function confirmServerStability(url: string, attempts?: number): Promise<void>;
36
+ /**
37
+ * Confirms that the Solana RPC is fully ready to process requests.
38
+ * This goes beyond HTTP availability and verifies the RPC can handle actual Solana requests.
39
+ *
40
+ * @param rpcUrl - The RPC endpoint URL
41
+ * @param maxAttempts - Maximum number of attempts (default: 30)
42
+ * @param delayMs - Delay between attempts in milliseconds (default: 500ms)
43
+ * @throws Error if RPC doesn't become ready within maxAttempts
44
+ */
45
+ export declare function confirmRpcReadiness(rpcUrl: string, maxAttempts?: number, delayMs?: number): Promise<void>;
@@ -8,6 +8,7 @@ exports.execute = execute;
8
8
  exports.spawnBinary = spawnBinary;
9
9
  exports.waitForServers = waitForServers;
10
10
  exports.confirmServerStability = confirmServerStability;
11
+ exports.confirmRpcReadiness = confirmRpcReadiness;
11
12
  const tslib_1 = require("tslib");
12
13
  const child_process_1 = require("child_process");
13
14
  const path_1 = tslib_1.__importDefault(require("path"));
@@ -242,3 +243,50 @@ async function confirmServerStability(url, attempts = 20) {
242
243
  throw error;
243
244
  }
244
245
  }
246
+ /**
247
+ * Confirms that the Solana RPC is fully ready to process requests.
248
+ * This goes beyond HTTP availability and verifies the RPC can handle actual Solana requests.
249
+ *
250
+ * @param rpcUrl - The RPC endpoint URL
251
+ * @param maxAttempts - Maximum number of attempts (default: 30)
252
+ * @param delayMs - Delay between attempts in milliseconds (default: 500ms)
253
+ * @throws Error if RPC doesn't become ready within maxAttempts
254
+ */
255
+ async function confirmRpcReadiness(rpcUrl, maxAttempts = 30, delayMs = 500) {
256
+ let lastError;
257
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
258
+ try {
259
+ const response = await axios_1.default.post(rpcUrl, {
260
+ jsonrpc: "2.0",
261
+ id: 1,
262
+ method: "getHealth",
263
+ params: [],
264
+ }, {
265
+ headers: { "Content-Type": "application/json" },
266
+ timeout: 3000,
267
+ });
268
+ if (response.data?.result === "ok") {
269
+ console.log(`RPC is ready after ${attempt} attempt${attempt > 1 ? "s" : ""}.`);
270
+ return;
271
+ }
272
+ // Response received but not "ok"
273
+ lastError = new Error(`RPC returned unexpected result: ${JSON.stringify(response.data)}`);
274
+ }
275
+ catch (error) {
276
+ lastError = error;
277
+ // Log connection errors only on later attempts to reduce noise
278
+ if (attempt > 5 && attempt % 5 === 0) {
279
+ const errorMsg = error instanceof Error ? error.message : String(error);
280
+ console.log(`RPC not ready yet (attempt ${attempt}/${maxAttempts}): ${errorMsg}`);
281
+ }
282
+ }
283
+ // Don't sleep after the last attempt
284
+ if (attempt < maxAttempts) {
285
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
286
+ }
287
+ }
288
+ // If we get here, all attempts failed
289
+ const errorMsg = lastError instanceof Error ? lastError.message : String(lastError);
290
+ const totalTime = Math.round((maxAttempts * delayMs) / 1000);
291
+ throw new Error(`RPC failed to become ready after ${maxAttempts} attempts (~${totalTime}s). Last error: ${errorMsg}`);
292
+ }
@@ -1,2 +1,2 @@
1
- export declare function startIndexer(rpcUrl: string, indexerPort: number, checkPhotonVersion?: boolean, photonDatabaseUrl?: string): Promise<undefined>;
1
+ export declare function startIndexer(rpcUrl: string, indexerPort: number, checkPhotonVersion?: boolean, photonDatabaseUrl?: string, proverUrl?: string): Promise<undefined>;
2
2
  export declare function killIndexer(): Promise<void>;
@@ -32,7 +32,7 @@ function getPhotonInstallMessage() {
32
32
  return `\nPhoton indexer ${constants_1.PHOTON_VERSION} not found. Please install it by running: "cargo install photon-indexer --version ${constants_1.PHOTON_VERSION} --locked --force"`;
33
33
  }
34
34
  }
35
- async function startIndexer(rpcUrl, indexerPort, checkPhotonVersion = true, photonDatabaseUrl) {
35
+ async function startIndexer(rpcUrl, indexerPort, checkPhotonVersion = true, photonDatabaseUrl, proverUrl) {
36
36
  await killIndexer();
37
37
  const resolvedOrNull = which_1.default.sync("photon", { nothrow: true });
38
38
  if (resolvedOrNull === null ||
@@ -51,6 +51,9 @@ async function startIndexer(rpcUrl, indexerPort, checkPhotonVersion = true, phot
51
51
  if (photonDatabaseUrl) {
52
52
  args.push("--db-url", photonDatabaseUrl);
53
53
  }
54
+ if (proverUrl) {
55
+ args.push("--prover-url", proverUrl);
56
+ }
54
57
  (0, process_1.spawnBinary)(constants_1.INDEXER_PROCESS_NAME, args);
55
58
  await (0, process_1.waitForServers)([{ port: indexerPort, path: "/getIndexerHealth" }]);
56
59
  console.log("Indexer started successfully!");
@@ -76,7 +76,7 @@ async function startProver(proverPort, redisUrl) {
76
76
  await killProver();
77
77
  await (0, process_1.killProcessByPort)(proverPort);
78
78
  const args = ["start"];
79
- args.push("--keys-dir", KEYS_DIR);
79
+ args.push("--keys-dir", KEYS_DIR + "/");
80
80
  args.push("--prover-address", `0.0.0.0:${proverPort}`);
81
81
  args.push("--auto-download", "true");
82
82
  if (redisUrl) {
@@ -584,6 +584,45 @@
584
584
  "index.js"
585
585
  ]
586
586
  },
587
+ "start-prover": {
588
+ "aliases": [],
589
+ "args": {},
590
+ "description": "Start gnark prover",
591
+ "flags": {
592
+ "prover-port": {
593
+ "description": "Enable Light Prover server on this port.",
594
+ "name": "prover-port",
595
+ "required": false,
596
+ "default": 3001,
597
+ "hasDynamicHelp": false,
598
+ "multiple": false,
599
+ "type": "option"
600
+ },
601
+ "redisUrl": {
602
+ "description": "Redis URL to use for the prover (e.g. redis://localhost:6379)",
603
+ "name": "redisUrl",
604
+ "required": false,
605
+ "hasDynamicHelp": false,
606
+ "multiple": false,
607
+ "type": "option"
608
+ }
609
+ },
610
+ "hasDynamicHelp": false,
611
+ "hiddenAliases": [],
612
+ "id": "start-prover",
613
+ "pluginAlias": "@lightprotocol/zk-compression-cli",
614
+ "pluginName": "@lightprotocol/zk-compression-cli",
615
+ "pluginType": "core",
616
+ "strict": true,
617
+ "enableJsonFlag": false,
618
+ "isESM": false,
619
+ "relativePath": [
620
+ "dist",
621
+ "commands",
622
+ "start-prover",
623
+ "index.js"
624
+ ]
625
+ },
587
626
  "token-balance": {
588
627
  "aliases": [],
589
628
  "args": {},
@@ -682,45 +721,6 @@
682
721
  "index.js"
683
722
  ]
684
723
  },
685
- "start-prover": {
686
- "aliases": [],
687
- "args": {},
688
- "description": "Start gnark prover",
689
- "flags": {
690
- "prover-port": {
691
- "description": "Enable Light Prover server on this port.",
692
- "name": "prover-port",
693
- "required": false,
694
- "default": 3001,
695
- "hasDynamicHelp": false,
696
- "multiple": false,
697
- "type": "option"
698
- },
699
- "redisUrl": {
700
- "description": "Redis URL to use for the prover (e.g. redis://localhost:6379)",
701
- "name": "redisUrl",
702
- "required": false,
703
- "hasDynamicHelp": false,
704
- "multiple": false,
705
- "type": "option"
706
- }
707
- },
708
- "hasDynamicHelp": false,
709
- "hiddenAliases": [],
710
- "id": "start-prover",
711
- "pluginAlias": "@lightprotocol/zk-compression-cli",
712
- "pluginName": "@lightprotocol/zk-compression-cli",
713
- "pluginType": "core",
714
- "strict": true,
715
- "enableJsonFlag": false,
716
- "isESM": false,
717
- "relativePath": [
718
- "dist",
719
- "commands",
720
- "start-prover",
721
- "index.js"
722
- ]
723
- },
724
724
  "test-validator": {
725
725
  "aliases": [],
726
726
  "args": {},
@@ -908,5 +908,5 @@
908
908
  ]
909
909
  }
910
910
  },
911
- "version": "0.27.1-alpha.4"
911
+ "version": "0.27.1-alpha.6"
912
912
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightprotocol/zk-compression-cli",
3
- "version": "0.27.1-alpha.4",
3
+ "version": "0.27.1-alpha.6",
4
4
  "description": "ZK Compression: Secure Scaling on Solana",
5
5
  "maintainers": [
6
6
  {
@@ -49,8 +49,8 @@
49
49
  "tweetnacl": "^1.0.3",
50
50
  "wait-on": "^7.2.0",
51
51
  "which": "^5.0.0",
52
- "@lightprotocol/compressed-token": "0.22.1-alpha.2",
53
- "@lightprotocol/stateless.js": "0.22.1-alpha.1"
52
+ "@lightprotocol/compressed-token": "0.22.1-alpha.4",
53
+ "@lightprotocol/stateless.js": "0.22.1-alpha.3"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@eslint/js": "9.36.0",