@bullpenfi/cli 0.1.0

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 ADDED
@@ -0,0 +1,22 @@
1
+ # @bullpenfi/cli
2
+
3
+ CLI for Bullpen prediction markets.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g @bullpenfi/cli
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```bash
14
+ bullpen --version
15
+ bullpen auth login
16
+ bullpen portfolio balances
17
+ ```
18
+
19
+ ## Learn More
20
+
21
+ - [GitHub Releases](https://github.com/BullpenFi/bullpen-cli-releases/releases)
22
+ - [Documentation](https://bullpen.fi)
package/bin/bullpen ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env node
2
+
3
+ "use strict";
4
+
5
+ const path = require("path");
6
+ const { spawnSync } = require("child_process");
7
+
8
+ const binaryPath = path.join(__dirname, "bullpen-native");
9
+
10
+ const fs = require("fs");
11
+ if (!fs.existsSync(binaryPath)) {
12
+ console.error(
13
+ "Error: bullpen native binary not found.\n" +
14
+ "The postinstall script may have failed. Try running:\n\n" +
15
+ " npm rebuild @bullpenfi/cli\n"
16
+ );
17
+ process.exit(1);
18
+ }
19
+
20
+ const result = spawnSync(binaryPath, process.argv.slice(2), {
21
+ stdio: "inherit",
22
+ });
23
+
24
+ if (result.error) {
25
+ console.error(`Failed to execute bullpen: ${result.error.message}`);
26
+ process.exit(1);
27
+ }
28
+
29
+ process.exit(result.status);
package/package.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "@bullpenfi/cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI for Bullpen prediction markets",
5
+ "bin": {
6
+ "bullpen": "bin/bullpen"
7
+ },
8
+ "scripts": {
9
+ "postinstall": "node scripts/postinstall.js"
10
+ },
11
+ "os": ["darwin", "linux"],
12
+ "cpu": ["x64", "arm64"],
13
+ "license": "MIT",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/BullpenFi/bullpen-cli-releases"
17
+ }
18
+ }
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+
3
+ const https = require("https");
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ const { execSync } = require("child_process");
7
+ const os = require("os");
8
+
9
+ const TARGETS = {
10
+ "darwin-arm64": "aarch64-apple-darwin",
11
+ "darwin-x64": "x86_64-apple-darwin",
12
+ "linux-x64": "x86_64-unknown-linux-musl",
13
+ "linux-arm64": "aarch64-unknown-linux-musl",
14
+ };
15
+
16
+ function getTarget() {
17
+ const key = `${process.platform}-${process.arch}`;
18
+ const target = TARGETS[key];
19
+ if (!target) {
20
+ throw new Error(
21
+ `Unsupported platform: ${process.platform} ${process.arch}. ` +
22
+ `Supported: ${Object.keys(TARGETS).join(", ")}`
23
+ );
24
+ }
25
+ return target;
26
+ }
27
+
28
+ function download(url) {
29
+ return new Promise((resolve, reject) => {
30
+ https
31
+ .get(url, (res) => {
32
+ // Handle GitHub 302 redirects to S3
33
+ if (res.statusCode === 302 || res.statusCode === 301) {
34
+ const redirectUrl = res.headers.location;
35
+ if (!redirectUrl) {
36
+ reject(new Error("Redirect with no location header"));
37
+ return;
38
+ }
39
+ download(redirectUrl).then(resolve).catch(reject);
40
+ return;
41
+ }
42
+
43
+ if (res.statusCode !== 200) {
44
+ reject(
45
+ new Error(`Download failed with status ${res.statusCode}: ${url}`)
46
+ );
47
+ return;
48
+ }
49
+
50
+ const chunks = [];
51
+ res.on("data", (chunk) => chunks.push(chunk));
52
+ res.on("end", () => resolve(Buffer.concat(chunks)));
53
+ res.on("error", reject);
54
+ })
55
+ .on("error", reject);
56
+ });
57
+ }
58
+
59
+ async function main() {
60
+ const target = getTarget();
61
+ const version = require("../package.json").version;
62
+ const tarballName = `bullpen-${version}-${target}.tar.gz`;
63
+ const downloadUrl = `https://github.com/BullpenFi/bullpen-cli-releases/releases/download/v${version}/${tarballName}`;
64
+
65
+ const binDir = path.join(__dirname, "..", "bin");
66
+ const binaryPath = path.join(binDir, "bullpen-native");
67
+ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "bullpen-"));
68
+ const tarballPath = path.join(tmpDir, tarballName);
69
+
70
+ try {
71
+ console.log(`Downloading bullpen v${version} for ${target}...`);
72
+ console.log(` ${downloadUrl}`);
73
+
74
+ const data = await download(downloadUrl);
75
+ fs.writeFileSync(tarballPath, data);
76
+ console.log(`Download complete (${(data.length / 1024 / 1024).toFixed(1)} MB)`);
77
+
78
+ // Extract the tarball
79
+ console.log("Extracting binary...");
80
+ execSync(`tar xzf "${tarballPath}" -C "${tmpDir}"`);
81
+
82
+ // Find the bullpen binary in the extracted contents
83
+ const candidates = ["bullpen", `bullpen-${target}`, path.join(target, "bullpen")];
84
+ let extractedBinary = null;
85
+
86
+ for (const candidate of candidates) {
87
+ const candidatePath = path.join(tmpDir, candidate);
88
+ if (fs.existsSync(candidatePath)) {
89
+ extractedBinary = candidatePath;
90
+ break;
91
+ }
92
+ }
93
+
94
+ if (!extractedBinary) {
95
+ // Search recursively for the binary
96
+ const files = execSync(`find "${tmpDir}" -name bullpen -type f`)
97
+ .toString()
98
+ .trim()
99
+ .split("\n")
100
+ .filter(Boolean);
101
+ if (files.length > 0) {
102
+ extractedBinary = files[0];
103
+ }
104
+ }
105
+
106
+ if (!extractedBinary) {
107
+ throw new Error(
108
+ "Could not find bullpen binary in the downloaded tarball. " +
109
+ `Contents: ${execSync(`ls -la "${tmpDir}"`).toString()}`
110
+ );
111
+ }
112
+
113
+ // Ensure bin directory exists
114
+ if (!fs.existsSync(binDir)) {
115
+ fs.mkdirSync(binDir, { recursive: true });
116
+ }
117
+
118
+ // Move binary to final location
119
+ fs.copyFileSync(extractedBinary, binaryPath);
120
+ fs.chmodSync(binaryPath, 0o755);
121
+
122
+ console.log(`bullpen v${version} installed successfully.`);
123
+ } catch (err) {
124
+ console.error(`\nError installing bullpen: ${err.message}`);
125
+ console.error(
126
+ "You can try reinstalling with: npm rebuild @bullpenfi/cli"
127
+ );
128
+ process.exit(1);
129
+ } finally {
130
+ // Clean up temp directory
131
+ try {
132
+ execSync(`rm -rf "${tmpDir}"`);
133
+ } catch (_) {
134
+ // Ignore cleanup errors
135
+ }
136
+ }
137
+ }
138
+
139
+ main();