@paimaexample/npm-midnight-proof-server 0.3.15

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/binary.js ADDED
@@ -0,0 +1,69 @@
1
+ const os = require("os");
2
+ const fs = require("fs");
3
+ const axios = require("axios");
4
+ const extract = require("extract-zip");
5
+ const path = require("path");
6
+
7
+ /**
8
+ * Returns platform string matching the naming convention used for hosted binaries.
9
+ * Example outputs: linux-amd64, macos-arm64
10
+ */
11
+ function getPlatform() {
12
+ const platform = os.platform();
13
+ let arch = os.arch();
14
+
15
+ if (arch === "x64") {
16
+ arch = "amd64";
17
+ }
18
+
19
+ // For macOS return macos-<arch> to allow unsupported detection
20
+ if (platform === "darwin") {
21
+ return `macos-${arch}`;
22
+ }
23
+
24
+ // Assume Linux or other UNIX variants default to arch only (amd64/arm64)
25
+ return arch;
26
+ }
27
+
28
+ function getBinaryUrl() {
29
+ const platform = getPlatform();
30
+ const supportedPlatforms = require("./package.json").supportedPlatforms;
31
+
32
+ if (!supportedPlatforms.includes(platform)) {
33
+ throw new Error(`Unsupported platform for binary execution: ${platform}`);
34
+ }
35
+
36
+ // TODO: Replace placeholder link with real URL once available
37
+ return `https://paima-midnight.nyc3.cdn.digitaloceanspaces.com/binaries/midnight-proof-server-${platform}.zip`;
38
+ }
39
+
40
+ async function downloadAndSaveBinary() {
41
+ const url = getBinaryUrl();
42
+ console.log(`Downloading midnight proof server binary from ${url}`);
43
+
44
+ const response = await axios.get(url, { responseType: "stream" });
45
+ const zipPath = path.join(__dirname, "proof-server.zip");
46
+ const writer = fs.createWriteStream(zipPath);
47
+
48
+ response.data.pipe(writer);
49
+
50
+ return new Promise((resolve, reject) => {
51
+ writer.on("finish", resolve);
52
+ writer.on("error", reject);
53
+ });
54
+ }
55
+
56
+ async function unzipBinary() {
57
+ const zipPath = path.join(__dirname, "proof-server.zip");
58
+ const destDir = path.join(__dirname, "proof-server");
59
+
60
+ await extract(zipPath, { dir: destDir });
61
+ fs.unlinkSync(zipPath);
62
+ }
63
+
64
+ async function binary() {
65
+ await downloadAndSaveBinary();
66
+ await unzipBinary();
67
+ }
68
+
69
+ module.exports = { binary, getPlatform };
package/docker.js ADDED
@@ -0,0 +1,124 @@
1
+ const { spawn, exec, execSync } = require("child_process");
2
+ const { promisify } = require("util");
3
+ const execAsync = promisify(exec);
4
+
5
+ const IMAGE_NAME = "midnightnetwork/proof-server";
6
+ const CONTAINER_NAME = "midnight-proof-server";
7
+
8
+ async function checkIfDockerExists() {
9
+ try {
10
+ await execAsync("docker --version");
11
+ return true;
12
+ } catch {
13
+ return false;
14
+ }
15
+ }
16
+
17
+ async function pullDockerImage(tag = "latest") {
18
+ return new Promise((resolve, reject) => {
19
+ const child = spawn("docker", ["pull", `${IMAGE_NAME}:${tag}`], {
20
+ stdio: "inherit",
21
+ });
22
+ child.on(
23
+ "exit",
24
+ (
25
+ code,
26
+ ) => (code === 0
27
+ ? resolve()
28
+ : reject(new Error(`docker pull exited with ${code}`))),
29
+ );
30
+ child.on("error", reject);
31
+ });
32
+ }
33
+
34
+ /**
35
+ * Checks if a container with the given name exists (running or stopped)
36
+ * @param {string} containerName - Name of the container to check
37
+ * @returns {Promise<boolean>} True if container exists, false otherwise
38
+ */
39
+ async function checkIfContainerExists(containerName) {
40
+ try {
41
+ const { stdout } = await execAsync(
42
+ `docker ps -aq -f name=^${containerName}$`,
43
+ );
44
+ return stdout.trim().length > 0;
45
+ } catch {
46
+ return false;
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Checks if a container is currently running
52
+ * @param {string} containerName - Name of the container to check
53
+ * @returns {Promise<boolean>} True if container is running, false otherwise
54
+ */
55
+ async function checkIfContainerRunning(containerName) {
56
+ try {
57
+ const { stdout } = await execAsync(
58
+ `docker ps -q -f name=^${containerName}$`,
59
+ );
60
+ return stdout.trim().length > 0;
61
+ } catch {
62
+ return false;
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Runs the proof server container. Maps port 6300 by default. Additional CLI args are passed as command args.
68
+ * @param {Object} env Env vars to set inside container.
69
+ * @param {Array<string>} args CLI args.
70
+ * @param {string} tag Docker tag.
71
+ */
72
+ async function runDockerContainer(
73
+ env = process.env,
74
+ args = [],
75
+ tag = "latest",
76
+ ) {
77
+ const containerExists = await checkIfContainerExists(CONTAINER_NAME);
78
+ const containerRunning = await checkIfContainerRunning(CONTAINER_NAME);
79
+
80
+ if (containerRunning) {
81
+ console.log(`Container ${CONTAINER_NAME} is already running`);
82
+ // Attach to the running container to see logs
83
+ const child = spawn("docker", ["logs", "-f", CONTAINER_NAME], {
84
+ stdio: "inherit",
85
+ });
86
+ return child;
87
+ }
88
+
89
+ if (containerExists) {
90
+ console.log(`Starting existing container: ${CONTAINER_NAME}`);
91
+ const child = spawn("docker", ["start", "-a", CONTAINER_NAME], {
92
+ stdio: "inherit",
93
+ });
94
+ return child;
95
+ }
96
+
97
+ // Container doesn't exist, create and run new one
98
+ console.log(`Creating new container: ${CONTAINER_NAME}`);
99
+
100
+ const dockerArgs = [
101
+ "run",
102
+ "--name",
103
+ CONTAINER_NAME,
104
+ "-p",
105
+ "6300:6300",
106
+ ];
107
+
108
+ // pass env vars
109
+ Object.entries(env).forEach(([k, v]) => {
110
+ if (v) dockerArgs.push("-e", `${k}=${v}`);
111
+ });
112
+
113
+ dockerArgs.push(`${IMAGE_NAME}:${tag}`);
114
+
115
+ if (args.length > 0) dockerArgs.push(...args);
116
+
117
+ console.log(
118
+ `Running proof server with Docker: docker ${dockerArgs.join(" ")}`,
119
+ );
120
+ const child = spawn("docker", dockerArgs, { stdio: "inherit" });
121
+ return child;
122
+ }
123
+
124
+ module.exports = { checkIfDockerExists, pullDockerImage, runDockerContainer };
package/index.js ADDED
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env node
2
+ const fs = require("fs");
3
+ const path = require("path");
4
+ const os = require("os");
5
+
6
+ const { binary, getPlatform } = require("./binary.js");
7
+ const { runMidnightProofServer } = require("./run_midnight_proof_server.js");
8
+ const { checkIfDockerExists, pullDockerImage, runDockerContainer } = require(
9
+ "./docker.js",
10
+ );
11
+
12
+ function checkIfBinaryExists() {
13
+ return fs.existsSync(path.join(__dirname, "proof-server", "proof-server"));
14
+ }
15
+
16
+ function isBinarySupported() {
17
+ const supported = require("./package.json").supportedPlatforms;
18
+ return supported.includes(getPlatform());
19
+ }
20
+
21
+ function showUsage() {
22
+ console.log(`\nUsage: npm-midnight-proof-server [options] [args...]\n
23
+ Options:
24
+ --docker Force use of Docker container
25
+ --binary Force binary execution (Linux only)
26
+ --help, -h Show this help message\n`);
27
+ }
28
+
29
+ function parseFlags(argv) {
30
+ const flags = {
31
+ useDocker: false,
32
+ useBinary: false,
33
+ showHelp: false,
34
+ remaining: [],
35
+ };
36
+ for (const arg of argv) {
37
+ if (arg === "--docker") flags.useDocker = true;
38
+ else if (arg === "--binary") flags.useBinary = true;
39
+ else if (arg === "--help" || arg === "-h") flags.showHelp = true;
40
+ else flags.remaining.push(arg);
41
+ }
42
+ return flags;
43
+ }
44
+
45
+ async function runWithBinary(env, args) {
46
+ if (!checkIfBinaryExists()) {
47
+ console.log("Binary not found, downloading...");
48
+ await binary();
49
+ }
50
+ return runMidnightProofServer(env, args);
51
+ }
52
+
53
+ async function runWithDocker(env, args) {
54
+ if (!(await checkIfDockerExists())) {
55
+ console.error("Docker is required but not installed or not running.");
56
+ process.exit(1);
57
+ }
58
+ await pullDockerImage();
59
+ return runDockerContainer(env, args);
60
+ }
61
+
62
+ (async () => {
63
+ const flags = parseFlags(process.argv.slice(2));
64
+ const env = process.env;
65
+
66
+ if (flags.showHelp) {
67
+ showUsage();
68
+ process.exit(0);
69
+ }
70
+
71
+ if (flags.useDocker && flags.useBinary) {
72
+ console.error("Cannot use both --docker and --binary flags simultaneously");
73
+ process.exit(1);
74
+ }
75
+
76
+ if (flags.useDocker) {
77
+ await runWithDocker(env, flags.remaining);
78
+ return;
79
+ }
80
+
81
+ if (flags.useBinary) {
82
+ if (!isBinarySupported()) {
83
+ console.error(
84
+ `Binary execution not supported on platform ${getPlatform()}`,
85
+ );
86
+ process.exit(1);
87
+ }
88
+ await runWithBinary(env, flags.remaining);
89
+ return;
90
+ }
91
+
92
+ // Automatic selection
93
+ if (isBinarySupported()) {
94
+ await runWithBinary(env, flags.remaining);
95
+ } else {
96
+ console.log(
97
+ "Binary not supported on this platform, falling back to Docker...",
98
+ );
99
+ await runWithDocker(env, flags.remaining);
100
+ }
101
+ })();
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@paimaexample/npm-midnight-proof-server",
3
+ "version": "0.3.15",
4
+ "description": "A wrapper for the Midnight proof server binary",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "npm-midnight-proof-server": "index.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node index.js"
11
+ },
12
+ "supportedPlatforms": [
13
+ "linux-amd64",
14
+ "linux-arm64"
15
+ ],
16
+ "dependencies": {
17
+ "axios": "^1.6.8",
18
+ "extract-zip": "^2.0.1"
19
+ },
20
+ "type": "commonjs",
21
+ "author": "Paima Studios",
22
+ "license": "ISC"
23
+ }
@@ -0,0 +1,43 @@
1
+ const { spawn } = require("child_process");
2
+ const path = require("path");
3
+ const { getPlatform } = require("./binary.js");
4
+
5
+ /**
6
+ * Executes the midnight-proof-server binary as a child process.
7
+ * @param {Object} env Environment variables to pass to the child process.
8
+ * @param {Array<string>} args Optional CLI arguments to forward to the binary.
9
+ * @returns {import('child_process').ChildProcess}
10
+ */
11
+ function runMidnightProofServer(env = process.env, args = []) {
12
+ const platform = getPlatform();
13
+ const binaryName = `midnight-proof-server-${platform}`;
14
+ const binaryPath = path.join(__dirname, "proof-server", binaryName);
15
+
16
+ console.log(`Starting midnight proof server binary at: ${binaryPath}`);
17
+
18
+ const child = spawn(binaryPath, args, {
19
+ env,
20
+ stdio: "inherit",
21
+ cwd: path.join(__dirname, "proof-server"),
22
+ });
23
+
24
+ child.on("spawn", () => {
25
+ console.log(`midnight-proof-server spawned with PID: ${child.pid}`);
26
+ });
27
+
28
+ child.on("error", (error) => {
29
+ console.error("Failed to start midnight proof server:", error);
30
+ });
31
+
32
+ child.on("exit", (code, signal) => {
33
+ if (code !== null) {
34
+ console.log(`midnight proof server exited with code: ${code}`);
35
+ } else {
36
+ console.log(`midnight proof server terminated by signal: ${signal}`);
37
+ }
38
+ });
39
+
40
+ return child;
41
+ }
42
+
43
+ module.exports = { runMidnightProofServer };