persolator-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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Persolator (https://persolator.xyz)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,255 @@
1
+ # persolator-cli
2
+
3
+ > Official CLI for [Persolator](https://persolator.xyz) — permissionless perpetual futures on Solana Devnet.
4
+
5
+ ```
6
+ PERSOLATOR · CLI · Solana Devnet Tooling
7
+ https://persolator.xyz
8
+ ```
9
+
10
+ ## What is this?
11
+
12
+ `persolator-cli` lets you interact with the Persolator protocol from your terminal:
13
+
14
+ - **Create SPL tokens** on Solana devnet — ready to launch as perpetual futures markets
15
+ - **Request devnet SOL** airdrops to pay for transaction fees
16
+ - **List active markets** from the Persolator protocol
17
+
18
+ No VPS or server required. Everything runs on your local machine against Solana devnet.
19
+
20
+ ---
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install -g persolator-cli
26
+ ```
27
+
28
+ Or use without installing:
29
+
30
+ ```bash
31
+ npx persolator-cli --help
32
+ ```
33
+
34
+ ---
35
+
36
+ ## Requirements
37
+
38
+ - **Node.js** >= 18
39
+ - **Solana keypair** — generate one with the Solana CLI:
40
+
41
+ ```bash
42
+ # Install Solana CLI
43
+ sh -c "$(curl -sSfL https://release.solana.com/stable/install)"
44
+
45
+ # Generate a new keypair (saved to ~/.config/solana/id.json)
46
+ solana-keygen new
47
+ ```
48
+
49
+ ---
50
+
51
+ ## Commands
52
+
53
+ ### `persolator airdrop`
54
+
55
+ Request devnet SOL to your wallet (needed to pay for transaction fees).
56
+
57
+ ```bash
58
+ persolator airdrop
59
+ # Requests 2 SOL by default
60
+
61
+ persolator airdrop --amount 5
62
+ # Max 5 SOL per request (Solana devnet limit)
63
+
64
+ persolator airdrop --keypair ./my-wallet.json
65
+ ```
66
+
67
+ **Options:**
68
+
69
+ | Flag | Default | Description |
70
+ |------|---------|-------------|
71
+ | `-a, --amount <sol>` | `2` | SOL amount (0.1 – 5) |
72
+ | `-k, --keypair <path>` | `~/.config/solana/id.json` | Path to keypair file |
73
+ | `--rpc <url>` | Solana devnet | Custom RPC endpoint |
74
+
75
+ ---
76
+
77
+ ### `persolator create-token`
78
+
79
+ Create a new SPL token on Solana devnet. The mint address it generates can be used to launch a perpetual futures market on Persolator.
80
+
81
+ ```bash
82
+ # Minimal — just name and symbol
83
+ persolator create-token --name "My Token" --symbol MTK
84
+
85
+ # With initial supply (minted to your wallet)
86
+ persolator create-token \
87
+ --name "Test USDC" \
88
+ --symbol tUSDC \
89
+ --decimals 6 \
90
+ --supply 1000000
91
+
92
+ # Custom keypair
93
+ persolator create-token \
94
+ --name "My Token" \
95
+ --symbol MTK \
96
+ --keypair ./deployer.json
97
+ ```
98
+
99
+ **Options:**
100
+
101
+ | Flag | Default | Description |
102
+ |------|---------|-------------|
103
+ | `-n, --name <name>` | required | Token name |
104
+ | `-s, --symbol <symbol>` | required | Token symbol (e.g. MTK) |
105
+ | `-d, --decimals <n>` | `9` | Number of decimal places |
106
+ | `--supply <amount>` | — | Initial token supply (optional) |
107
+ | `-k, --keypair <path>` | `~/.config/solana/id.json` | Path to keypair file |
108
+ | `--rpc <url>` | Solana devnet | Custom RPC endpoint |
109
+
110
+ **Output example:**
111
+
112
+ ```
113
+ ─────────────────────────────────────────────────────
114
+ → Token Created Successfully
115
+ ─────────────────────────────────────────────────────
116
+ Name My Token
117
+ Symbol MTK
118
+ Mint Address 7xK4mPqR...YZab
119
+ Decimals 9
120
+ Authority 8Fgh3...mNop
121
+ Explorer https://explorer.solana.com/address/7xK4...?cluster=devnet
122
+ ─────────────────────────────────────────────────────
123
+
124
+ ✓ Mint address ready to use on Persolator!
125
+
126
+ → Next step — launch a perpetual market on Persolator:
127
+ → https://persolator.xyz/launch
128
+ → Paste this mint address: 7xK4mPqR...YZab
129
+ ```
130
+
131
+ ---
132
+
133
+ ### `persolator markets`
134
+
135
+ List all active markets on the Persolator protocol.
136
+
137
+ ```bash
138
+ persolator markets
139
+
140
+ # Point to a self-hosted instance
141
+ persolator markets --api https://api.persolator.xyz
142
+ ```
143
+
144
+ **Options:**
145
+
146
+ | Flag | Default | Description |
147
+ |------|---------|-------------|
148
+ | `--api <url>` | `https://api.persolator.xyz` | Persolator API base URL |
149
+
150
+ ---
151
+
152
+ ## Full Workflow: From Zero to Market
153
+
154
+ ```bash
155
+ # 1. Install the CLI
156
+ npm install -g persolator-cli
157
+
158
+ # 2. Generate a Solana keypair (skip if you already have one)
159
+ solana-keygen new
160
+ # Saves to: ~/.config/solana/id.json
161
+
162
+ # 3. Get devnet SOL for transaction fees
163
+ persolator airdrop --amount 2
164
+
165
+ # 4. Create your SPL token
166
+ persolator create-token \
167
+ --name "My Project Token" \
168
+ --symbol MPT \
169
+ --decimals 9
170
+
171
+ # 5. Copy the mint address from the output, then go to:
172
+ # https://persolator.xyz/launch
173
+ # Paste the mint address → configure leverage, fees → sign & deploy
174
+
175
+ # 6. Verify your market is live
176
+ persolator markets
177
+ ```
178
+
179
+ ---
180
+
181
+ ## Keypair Options
182
+
183
+ The CLI looks for a keypair in this order:
184
+
185
+ 1. `--keypair <path>` flag
186
+ 2. `$SOLANA_KEYPAIR` environment variable
187
+ 3. `~/.config/solana/id.json` (Solana CLI default)
188
+
189
+ ```bash
190
+ # Use environment variable
191
+ export SOLANA_KEYPAIR=/path/to/id.json
192
+ persolator create-token --name "Test" --symbol TST
193
+
194
+ # Use flag
195
+ persolator create-token --name "Test" --symbol TST --keypair ./my-key.json
196
+ ```
197
+
198
+ ---
199
+
200
+ ## Custom RPC
201
+
202
+ By default the CLI connects to Solana's public devnet RPC. For better performance you can use a private endpoint:
203
+
204
+ ```bash
205
+ persolator create-token \
206
+ --name "Test" \
207
+ --symbol TST \
208
+ --rpc https://api.devnet.solana.com
209
+ ```
210
+
211
+ Free devnet RPC providers: [Helius](https://helius.dev), [QuickNode](https://quicknode.com), [Alchemy](https://alchemy.com)
212
+
213
+ ---
214
+
215
+ ## Programmatic Usage
216
+
217
+ The CLI is also importable as a library:
218
+
219
+ ```ts
220
+ import { cmdCreateToken } from "persolator-cli/commands/create-token";
221
+
222
+ await cmdCreateToken({
223
+ name: "My Token",
224
+ symbol: "MTK",
225
+ decimals: "9",
226
+ supply: "1000000",
227
+ keypair: "./id.json",
228
+ });
229
+ ```
230
+
231
+ ---
232
+
233
+ ## Security
234
+
235
+ - **Never share your keypair file.** It contains your private key.
236
+ - The CLI only connects to Solana **devnet** by default — no real funds are at risk.
237
+ - All source code is open source: [github.com/persolator/persolator-cli](https://github.com/persolator/persolator-cli)
238
+
239
+ ---
240
+
241
+ ## Links
242
+
243
+ | | |
244
+ |--|--|
245
+ | Website | https://persolator.xyz |
246
+ | App | https://persolator.xyz/markets |
247
+ | GitHub | https://github.com/persolator |
248
+ | X / Twitter | https://x.com/persolator_xyz |
249
+ | npm | https://npmjs.com/package/persolator-cli |
250
+
251
+ ---
252
+
253
+ ## License
254
+
255
+ MIT © [Persolator](https://persolator.xyz)
@@ -0,0 +1,7 @@
1
+ export interface AirdropOptions {
2
+ amount: string;
3
+ keypair?: string;
4
+ rpc?: string;
5
+ }
6
+ export declare function cmdAirdrop(opts: AirdropOptions): Promise<void>;
7
+ //# sourceMappingURL=airdrop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"airdrop.d.ts","sourceRoot":"","sources":["../../src/commands/airdrop.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,iBA2DpD"}
@@ -0,0 +1,55 @@
1
+ import { Connection, LAMPORTS_PER_SOL, clusterApiUrl } from "@solana/web3.js";
2
+ import { loadKeypair } from "../lib/keypair.js";
3
+ import { header, success, info, error, label, divider } from "../lib/logger.js";
4
+ import ora from "ora";
5
+ export async function cmdAirdrop(opts) {
6
+ header();
7
+ const amount = parseFloat(opts.amount);
8
+ if (isNaN(amount) || amount <= 0 || amount > 5) {
9
+ error("Amount must be between 0.1 and 5 SOL (devnet limit)");
10
+ process.exit(1);
11
+ }
12
+ let keypair;
13
+ try {
14
+ keypair = loadKeypair(opts.keypair);
15
+ }
16
+ catch (e) {
17
+ error(e.message);
18
+ process.exit(1);
19
+ }
20
+ const rpcUrl = opts.rpc ?? clusterApiUrl("devnet");
21
+ const connection = new Connection(rpcUrl, "confirmed");
22
+ const balanceBefore = await connection.getBalance(keypair.publicKey);
23
+ const spinner = ora({
24
+ text: `Requesting ${amount} SOL airdrop on devnet...`,
25
+ color: "cyan",
26
+ }).start();
27
+ try {
28
+ const sig = await connection.requestAirdrop(keypair.publicKey, amount * LAMPORTS_PER_SOL);
29
+ spinner.text = "Confirming airdrop transaction...";
30
+ const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
31
+ await connection.confirmTransaction({ signature: sig, blockhash, lastValidBlockHeight }, "confirmed");
32
+ const balanceAfter = await connection.getBalance(keypair.publicKey);
33
+ spinner.succeed("Airdrop confirmed!");
34
+ console.log("");
35
+ divider();
36
+ info("Airdrop Details");
37
+ divider();
38
+ label("Wallet", keypair.publicKey.toBase58());
39
+ label("Amount", `${amount} SOL`);
40
+ label("Balance before", `${(balanceBefore / LAMPORTS_PER_SOL).toFixed(4)} SOL`);
41
+ label("Balance after", `${(balanceAfter / LAMPORTS_PER_SOL).toFixed(4)} SOL`);
42
+ label("Tx Signature", sig);
43
+ label("Explorer", `https://explorer.solana.com/tx/${sig}?cluster=devnet`);
44
+ divider();
45
+ console.log("");
46
+ success("Airdrop complete! You can now create tokens and launch markets.");
47
+ console.log("");
48
+ }
49
+ catch (e) {
50
+ spinner.fail("Airdrop failed");
51
+ error(e.message ?? String(e));
52
+ process.exit(1);
53
+ }
54
+ }
55
+ //# sourceMappingURL=airdrop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"airdrop.js","sourceRoot":"","sources":["../../src/commands/airdrop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export interface CreateTokenOptions {
2
+ name: string;
3
+ symbol: string;
4
+ decimals: string;
5
+ supply?: string;
6
+ keypair?: string;
7
+ rpc?: string;
8
+ }
9
+ export declare function cmdCreateToken(opts: CreateTokenOptions): Promise<void>;
10
+ //# sourceMappingURL=create-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-token.d.ts","sourceRoot":"","sources":["../../src/commands/create-token.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,kBAAkB,iBAqG5D"}
@@ -0,0 +1,91 @@
1
+ import { Connection, LAMPORTS_PER_SOL, clusterApiUrl, } from "@solana/web3.js";
2
+ import { createMint, getOrCreateAssociatedTokenAccount, mintTo, getMint, } from "@solana/spl-token";
3
+ import { loadKeypair } from "../lib/keypair.js";
4
+ import { header, success, info, error, warn, label, divider } from "../lib/logger.js";
5
+ import ora from "ora";
6
+ export async function cmdCreateToken(opts) {
7
+ header();
8
+ const decimals = parseInt(opts.decimals, 10);
9
+ if (isNaN(decimals) || decimals < 0 || decimals > 18) {
10
+ error("Decimals must be between 0 and 18");
11
+ process.exit(1);
12
+ }
13
+ const supply = opts.supply ? parseFloat(opts.supply) : 0;
14
+ let payer;
15
+ try {
16
+ payer = loadKeypair(opts.keypair);
17
+ }
18
+ catch (e) {
19
+ error(e.message);
20
+ process.exit(1);
21
+ }
22
+ const rpcUrl = opts.rpc ?? clusterApiUrl("devnet");
23
+ const connection = new Connection(rpcUrl, "confirmed");
24
+ // Check balance
25
+ const balance = await connection.getBalance(payer.publicKey);
26
+ if (balance < 0.01 * LAMPORTS_PER_SOL) {
27
+ error(`Insufficient SOL balance: ${(balance / LAMPORTS_PER_SOL).toFixed(4)} SOL`);
28
+ warn('Run: persolator airdrop --amount 2');
29
+ process.exit(1);
30
+ }
31
+ info(`Creating SPL token on Solana devnet...`);
32
+ info(` Name: ${opts.name}`);
33
+ info(` Symbol: ${opts.symbol}`);
34
+ info(` Decimals: ${decimals}`);
35
+ if (supply > 0)
36
+ info(` Supply: ${supply.toLocaleString()} tokens`);
37
+ console.log("");
38
+ // 1. Create mint
39
+ const spinner = ora({ text: "Creating mint account...", color: "magenta" }).start();
40
+ let mint;
41
+ try {
42
+ mint = await createMint(connection, payer, payer.publicKey, payer.publicKey, decimals);
43
+ spinner.succeed(`Mint created: ${mint.toBase58()}`);
44
+ }
45
+ catch (e) {
46
+ spinner.fail("Failed to create mint");
47
+ error(e.message ?? String(e));
48
+ process.exit(1);
49
+ }
50
+ // 2. Optional: mint initial supply
51
+ let ataAddress;
52
+ if (supply > 0) {
53
+ const spinner2 = ora({ text: "Creating token account & minting supply...", color: "cyan" }).start();
54
+ try {
55
+ const ata = await getOrCreateAssociatedTokenAccount(connection, payer, mint, payer.publicKey);
56
+ const amount = BigInt(Math.round(supply * Math.pow(10, decimals)));
57
+ await mintTo(connection, payer, mint, ata.address, payer, amount);
58
+ ataAddress = ata.address.toBase58();
59
+ spinner2.succeed(`Minted ${supply.toLocaleString()} ${opts.symbol} to your wallet`);
60
+ }
61
+ catch (e) {
62
+ spinner2.warn("Supply minting failed (token was still created)");
63
+ warn(e.message ?? String(e));
64
+ }
65
+ }
66
+ // 3. Verify
67
+ const mintInfo = await getMint(connection, mint);
68
+ console.log("");
69
+ divider();
70
+ info("Token Created Successfully");
71
+ divider();
72
+ label("Name", opts.name);
73
+ label("Symbol", opts.symbol);
74
+ label("Mint Address", mint.toBase58());
75
+ label("Decimals", mintInfo.decimals.toString());
76
+ label("Authority", mintInfo.mintAuthority?.toBase58() ?? "none");
77
+ if (ataAddress) {
78
+ label("Token Account", ataAddress);
79
+ label("Supply", `${supply.toLocaleString()} ${opts.symbol}`);
80
+ }
81
+ label("Explorer", `https://explorer.solana.com/address/${mint.toBase58()}?cluster=devnet`);
82
+ divider();
83
+ console.log("");
84
+ success("Mint address ready to use on Persolator!");
85
+ console.log("");
86
+ info("Next step — launch a perpetual market on Persolator:");
87
+ info(` https://persolator.xyz/launch`);
88
+ info(` Paste this mint address: ${mint.toBase58()}`);
89
+ console.log("");
90
+ }
91
+ //# sourceMappingURL=create-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-token.js","sourceRoot":"","sources":["../../src/commands/create-token.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export interface MarketsOptions {
2
+ api?: string;
3
+ }
4
+ export declare function cmdMarkets(opts: MarketsOptions): Promise<void>;
5
+ //# sourceMappingURL=markets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markets.d.ts","sourceRoot":"","sources":["../../src/commands/markets.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,iBAsDpD"}
@@ -0,0 +1,53 @@
1
+ import { header, info, label, divider, error, success } from "../lib/logger.js";
2
+ import chalk from "chalk";
3
+ export async function cmdMarkets(opts) {
4
+ header();
5
+ const base = (opts.api ?? "https://api.persolator.xyz").replace(/\/$/, "");
6
+ const spinner = (await import("ora")).default({
7
+ text: `Fetching markets from ${base}...`,
8
+ color: "cyan",
9
+ }).start();
10
+ let markets;
11
+ try {
12
+ const res = await fetch(`${base}/api/markets`);
13
+ if (!res.ok)
14
+ throw new Error(`HTTP ${res.status}: ${res.statusText}`);
15
+ const data = await res.json();
16
+ markets = data.markets ?? [];
17
+ spinner.succeed(`Found ${markets.length} active market${markets.length !== 1 ? "s" : ""}`);
18
+ }
19
+ catch (e) {
20
+ spinner.fail("Failed to fetch markets");
21
+ error(e.message ?? String(e));
22
+ process.exit(1);
23
+ }
24
+ if (markets.length === 0) {
25
+ info("No markets found. Be the first to launch one!");
26
+ info(" persolator launch (coming soon)");
27
+ info(` https://persolator.xyz/launch`);
28
+ return;
29
+ }
30
+ console.log("");
31
+ divider();
32
+ info("Persolator Markets");
33
+ divider();
34
+ for (const m of markets) {
35
+ const change = m.priceChange24h ?? 0;
36
+ const color = change >= 0 ? chalk.hex("#22c55e") : chalk.hex("#ef4444");
37
+ const arrow = change >= 0 ? "↑" : "↓";
38
+ console.log("");
39
+ label("Market", m.symbol);
40
+ label("Price", `$${Number(m.price ?? 0).toFixed(4)}`);
41
+ label("24h", color(`${arrow} ${Math.abs(change).toFixed(2)}%`));
42
+ label("Volume", `$${Number(m.volume24h ?? 0).toLocaleString()}`);
43
+ label("Open Int.", `$${Number(m.openInterest ?? 0).toLocaleString()}`);
44
+ label("Max Lev", `${m.maxLeverage ?? "—"}x`);
45
+ label("Creator", m.creatorWallet ? `${m.creatorWallet.slice(0, 8)}...` : "—");
46
+ }
47
+ console.log("");
48
+ divider();
49
+ console.log("");
50
+ success(`Trade at https://persolator.xyz/markets`);
51
+ console.log("");
52
+ }
53
+ //# sourceMappingURL=markets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markets.js","sourceRoot":"","sources":["../../src/commands/markets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { cmdCreateToken } from "./commands/create-token.js";
4
+ import { cmdAirdrop } from "./commands/airdrop.js";
5
+ import { cmdMarkets } from "./commands/markets.js";
6
+ const program = new Command();
7
+ program
8
+ .name("persolator")
9
+ .description("Official CLI for Persolator — permissionless perpetual futures on Solana")
10
+ .version("0.1.0");
11
+ // ── create-token ──────────────────────────────────────────────────────────────
12
+ program
13
+ .command("create-token")
14
+ .description("Create a new SPL token on Solana devnet (ready to use as a Persolator market)")
15
+ .requiredOption("-n, --name <name>", "Token name (e.g. \"My Test Token\")")
16
+ .requiredOption("-s, --symbol <symbol>", "Token symbol (e.g. MTT)")
17
+ .option("-d, --decimals <n>", "Token decimals", "9")
18
+ .option("--supply <amount>", "Initial supply to mint to your wallet (optional)")
19
+ .option("-k, --keypair <path>", "Path to Solana keypair JSON file")
20
+ .option("--rpc <url>", "Custom Solana RPC endpoint (default: devnet)")
21
+ .action(cmdCreateToken);
22
+ // ── airdrop ───────────────────────────────────────────────────────────────────
23
+ program
24
+ .command("airdrop")
25
+ .description("Request a devnet SOL airdrop (max 5 SOL per request)")
26
+ .option("-a, --amount <sol>", "Amount of SOL to request", "2")
27
+ .option("-k, --keypair <path>", "Path to Solana keypair JSON file")
28
+ .option("--rpc <url>", "Custom Solana RPC endpoint (default: devnet)")
29
+ .action(cmdAirdrop);
30
+ // ── markets ───────────────────────────────────────────────────────────────────
31
+ program
32
+ .command("markets")
33
+ .description("List all active Persolator markets")
34
+ .option("--api <url>", "Persolator API base URL", "https://api.persolator.xyz")
35
+ .action(cmdMarkets);
36
+ program.parse();
37
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAU,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAU,uBAAuB,CAAC;AAEvD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,YAAY,CAAC;KAClB,WAAW,CAAC,0EAA0E,CAAC;KACvF,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,iFAAiF;AAEjF,OAAO;KACJ,OAAO,CAAC,cAAc,CAAC;KACvB,WAAW,CAAC,+EAA+E,CAAC;KAC5F,cAAc,CAAC,mBAAmB,EAAU,sCAAsC,CAAC;KACnF,cAAc,CAAC,uBAAuB,EAAM,yBAAyB,CAAC;KACtE,MAAM,CAAC,oBAAoB,EAAiB,gBAAgB,EAAE,GAAG,CAAC;KAClE,MAAM,CAAC,mBAAmB,EAAkB,kDAAkD,CAAC;KAC/F,MAAM,CAAC,sBAAsB,EAAe,kCAAkC,CAAC;KAC/E,MAAM,CAAC,aAAa,EAAwB,8CAA8C,CAAC;KAC3F,MAAM,CAAC,cAAc,CAAC,CAAC;AAE1B,iFAAiF;AAEjF,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,sDAAsD,CAAC;KACnE,MAAM,CAAC,oBAAoB,EAAiB,0BAA0B,EAAE,GAAG,CAAC;KAC5E,MAAM,CAAC,sBAAsB,EAAe,kCAAkC,CAAC;KAC/E,MAAM,CAAC,aAAa,EAAwB,8CAA8C,CAAC;KAC3F,MAAM,CAAC,UAAU,CAAC,CAAC;AAEtB,iFAAiF;AAEjF,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,aAAa,EAAwB,yBAAyB,EAAE,4BAA4B,CAAC;KACpG,MAAM,CAAC,UAAU,CAAC,CAAC;AAEtB,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { Keypair } from "@solana/web3.js";
2
+ export declare function loadKeypair(filePath?: string): Keypair;
3
+ export declare function keypairPath(filePath?: string): string;
4
+ //# sourceMappingURL=keypair.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keypair.d.ts","sourceRoot":"","sources":["../../src/lib/keypair.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAK1C,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAoBtD;AAED,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAIrD"}
@@ -0,0 +1,29 @@
1
+ import { Keypair } from "@solana/web3.js";
2
+ import { readFileSync, existsSync } from "fs";
3
+ import { resolve, join } from "path";
4
+ import { homedir } from "os";
5
+ export function loadKeypair(filePath) {
6
+ const paths = [
7
+ filePath && resolve(filePath),
8
+ process.env.SOLANA_KEYPAIR,
9
+ join(homedir(), ".config", "solana", "id.json"),
10
+ ].filter(Boolean);
11
+ for (const p of paths) {
12
+ if (existsSync(p)) {
13
+ const raw = readFileSync(p, "utf8");
14
+ const arr = JSON.parse(raw);
15
+ return Keypair.fromSecretKey(Uint8Array.from(arr));
16
+ }
17
+ }
18
+ throw new Error("No keypair found.\n" +
19
+ " Generate one: solana-keygen new\n" +
20
+ " Or pass: --keypair /path/to/id.json");
21
+ }
22
+ export function keypairPath(filePath) {
23
+ if (filePath)
24
+ return resolve(filePath);
25
+ if (process.env.SOLANA_KEYPAIR)
26
+ return process.env.SOLANA_KEYPAIR;
27
+ return join(homedir(), ".config", "solana", "id.json");
28
+ }
29
+ //# sourceMappingURL=keypair.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keypair.js","sourceRoot":"","sources":["../../src/lib/keypair.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,MAAM,UAAU,WAAW,CAAC,QAAiB;IAC3C,MAAM,KAAK,GAAG;QACZ,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,cAAc;QAC1B,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC;KAChD,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC;IAE9B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YAClB,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;YACpC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAa,CAAC;YACxC,OAAO,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CACb,qBAAqB;QACrB,sCAAsC;QACtC,6CAA6C,CAC9C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAiB;IAC3C,IAAI,QAAQ;QAAE,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAClE,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare function header(): void;
2
+ export declare function success(msg: string): void;
3
+ export declare function info(msg: string): void;
4
+ export declare function warn(msg: string): void;
5
+ export declare function error(msg: string): void;
6
+ export declare function label(key: string, value: string): void;
7
+ export declare function divider(): void;
8
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAKA,wBAAgB,MAAM,SAKrB;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,QAElC;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,QAE/B;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,QAE/B;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,QAEhC;AAED,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAE/C;AAED,wBAAgB,OAAO,SAEtB"}
@@ -0,0 +1,28 @@
1
+ import chalk from "chalk";
2
+ const BRAND = chalk.hex("#e040fb").bold("PERSOLATOR");
3
+ const SEP = chalk.white.dim("·");
4
+ export function header() {
5
+ console.log("");
6
+ console.log(` ${BRAND} ${SEP} ${chalk.hex("#22d3ee")("CLI")} ${SEP} ${chalk.hex("#00ff88").dim("Solana Devnet Tooling")}`);
7
+ console.log(` ${chalk.dim("https://persolator.xyz")}`);
8
+ console.log("");
9
+ }
10
+ export function success(msg) {
11
+ console.log(` ${chalk.hex("#00ff88")("✓")} ${msg}`);
12
+ }
13
+ export function info(msg) {
14
+ console.log(` ${chalk.hex("#22d3ee")("→")} ${msg}`);
15
+ }
16
+ export function warn(msg) {
17
+ console.log(` ${chalk.yellow("!")} ${chalk.yellow(msg)}`);
18
+ }
19
+ export function error(msg) {
20
+ console.log(` ${chalk.red("✗")} ${chalk.red(msg)}`);
21
+ }
22
+ export function label(key, value) {
23
+ console.log(` ${chalk.dim(key.padEnd(20))} ${chalk.white(value)}`);
24
+ }
25
+ export function divider() {
26
+ console.log(` ${chalk.dim("─".repeat(52))}`);
27
+ }
28
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AACtD,MAAM,GAAG,GAAK,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEnC,MAAM,UAAU,MAAM;IACpB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,IAAI,GAAG,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,uBAAuB,CAAC,EAAE,CAAC,CAAC;IAC5H,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC;IACxD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,GAAW;IAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAW;IAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAW,EAAE,KAAa;IAC9C,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "persolator-cli",
3
+ "version": "0.1.0",
4
+ "description": "Official CLI for Persolator — create SPL tokens on Solana devnet, manage markets, and interact with the Persolator perpetual futures protocol",
5
+ "keywords": [
6
+ "persolator",
7
+ "solana",
8
+ "spl-token",
9
+ "devnet",
10
+ "perpetual",
11
+ "defi",
12
+ "cli"
13
+ ],
14
+ "author": "Persolator <dev@persolator.xyz> (https://persolator.xyz)",
15
+ "license": "MIT",
16
+ "homepage": "https://persolator.xyz",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/persolator/persolator-cli.git"
20
+ },
21
+ "bugs": {
22
+ "url": "https://github.com/persolator/persolator-cli/issues"
23
+ },
24
+ "type": "module",
25
+ "bin": {
26
+ "persolator": "./dist/index.js"
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "README.md",
31
+ "LICENSE"
32
+ ],
33
+ "scripts": {
34
+ "build": "tsc --project tsconfig.json && node scripts/postbuild.js",
35
+ "dev": "tsx src/index.ts",
36
+ "prepublishOnly": "pnpm build"
37
+ },
38
+ "engines": {
39
+ "node": ">=18.0.0"
40
+ },
41
+ "dependencies": {
42
+ "@solana/spl-token": "^0.4.13",
43
+ "@solana/web3.js": "^1.98.0",
44
+ "chalk": "^5.4.1",
45
+ "commander": "^13.1.0",
46
+ "ora": "^8.2.0"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^22.0.0",
50
+ "tsx": "^4.19.0",
51
+ "typescript": "^5.7.0"
52
+ }
53
+ }