@clawdvault/cli 0.1.1 → 0.1.3

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 (3) hide show
  1. package/README.md +298 -33
  2. package/dist/index.js +362 -4
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # @clawdvault/cli
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/@clawdvault/cli.svg)](https://www.npmjs.com/package/@clawdvault/cli)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
3
6
  Command-line interface for [ClawdVault](https://clawdvault.com) - a pump.fun-style token launchpad on Solana.
4
7
 
5
8
  ## Installation
@@ -16,7 +19,7 @@ npx @clawdvault/cli tokens list
16
19
 
17
20
  ## Quick Start
18
21
 
19
- ### Setup Wallet
22
+ ### 1. Setup Wallet
20
23
 
21
24
  ```bash
22
25
  # Generate a new wallet
@@ -26,7 +29,7 @@ clawdvault wallet init
26
29
  export CLAWDVAULT_WALLET=~/.config/solana/id.json
27
30
  ```
28
31
 
29
- ### Read Operations (No Wallet Required)
32
+ ### 2. Read Operations (No Wallet Required)
30
33
 
31
34
  ```bash
32
35
  # List featured tokens
@@ -42,7 +45,7 @@ clawdvault trade quote -m TOKEN_MINT_ADDRESS -t buy -a 0.1
42
45
  clawdvault wallet sol-price
43
46
  ```
44
47
 
45
- ### Write Operations (Wallet Required)
48
+ ### 3. Write Operations (Wallet Required)
46
49
 
47
50
  ```bash
48
51
  # Create a new token
@@ -56,28 +59,185 @@ clawdvault trade sell --mint TOKEN_MINT_ADDRESS --amount 1000000
56
59
 
57
60
  # Sell by percentage
58
61
  clawdvault trade sell --mint TOKEN_MINT_ADDRESS --percent 50
62
+ ```
63
+
64
+ ## Commands Reference
59
65
 
60
- # Native SOL transfer
61
- clawdvault wallet transfer --to RECIPIENT_ADDRESS --sol 0.5
66
+ ### `clawdvault tokens`
67
+
68
+ List and filter tokens.
69
+
70
+ ```bash
71
+ clawdvault tokens list [options]
72
+
73
+ Options:
74
+ -s, --sort <field> Sort by: created_at, market_cap, volume, price
75
+ -p, --page <number> Page number (default: 1)
76
+ -l, --limit <number> Items per page (default: 20)
77
+ --graduated Show only graduated tokens
78
+ --not-graduated Show only non-graduated tokens
79
+ --json Output as JSON
80
+
81
+ Examples:
82
+ clawdvault tokens list --sort market_cap --limit 10
83
+ clawdvault tokens list --graduated --json
62
84
  ```
63
85
 
64
- ### Wallet Operations
86
+ ### `clawdvault token`
87
+
88
+ Token details and creation.
65
89
 
66
90
  ```bash
67
- # Show wallet info
68
- clawdvault wallet info
91
+ # Get token details
92
+ clawdvault token get <mint> [--json]
93
+
94
+ # Create a new token
95
+ clawdvault token create [options]
96
+ -n, --name <name> Token name (required)
97
+ -s, --symbol <symbol> Token symbol (required)
98
+ -d, --description <desc> Description
99
+ -i, --image <path> Image file path (png, jpg, gif)
100
+ --initial-buy <sol> Initial buy amount in SOL
101
+ --twitter <url> Twitter URL
102
+ --telegram <url> Telegram URL
103
+ --website <url> Website URL
104
+ -w, --wallet <path> Wallet file path
105
+
106
+ # Get on-chain stats
107
+ clawdvault token stats <mint> [--json]
108
+
109
+ # Get top holders
110
+ clawdvault token holders <mint> [--json]
111
+
112
+ Examples:
113
+ clawdvault token get 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU
114
+ clawdvault token create -n "Moon Token" -s "MOON" -i ./moon.png
115
+ clawdvault token create --name "Test" --symbol "TEST" --initial-buy 0.5
116
+ ```
117
+
118
+ ### `clawdvault trade`
119
+
120
+ Buy, sell, and get quotes.
121
+
122
+ ```bash
123
+ # Buy tokens
124
+ clawdvault trade buy [options]
125
+ -m, --mint <address> Token mint address (required)
126
+ -a, --sol <amount> SOL amount to spend (required)
127
+ -s, --slippage <percent> Slippage tolerance (default: 1)
128
+ -w, --wallet <path> Wallet file path
129
+ --simulate Simulate only, don't execute
130
+
131
+ # Sell tokens
132
+ clawdvault trade sell [options]
133
+ -m, --mint <address> Token mint address (required)
134
+ -a, --amount <tokens> Token amount to sell
135
+ -p, --percent <percent> Percentage of holdings to sell
136
+ -s, --slippage <percent> Slippage tolerance (default: 1)
137
+ -w, --wallet <path> Wallet file path
138
+ --simulate Simulate only, don't execute
139
+
140
+ Note: Use either --amount or --percent, not both.
141
+
142
+ # Get price quote
143
+ clawdvault trade quote [options]
144
+ -m, --mint <address> Token mint address (required)
145
+ -t, --type <type> Quote type: buy or sell (required)
146
+ -a, --amount <amount> Amount (SOL for buy, tokens for sell)
147
+ --json Output as JSON
148
+
149
+ # View trade history
150
+ clawdvault trade history [options]
151
+ -m, --mint <address> Token mint address (required)
152
+ -l, --limit <number> Number of trades (default: 20)
153
+ --json Output as JSON
154
+
155
+ Examples:
156
+ clawdvault trade buy -m TOKEN_MINT -a 0.1
157
+ clawdvault trade buy -m TOKEN_MINT -a 0.5 -s 2 --simulate
158
+ clawdvault trade sell -m TOKEN_MINT -p 50
159
+ clawdvault trade sell -m TOKEN_MINT -a 1000000
160
+ clawdvault trade quote -m TOKEN_MINT -t buy -a 0.1
161
+ ```
162
+
163
+ ### `clawdvault stream`
164
+
165
+ Real-time data streaming (live trades, prices, chat).
69
166
 
70
- # Check SOL balance
71
- clawdvault wallet sol-balance
167
+ ```bash
168
+ # Stream live trades
169
+ clawdvault stream trades [options]
170
+ -m, --mint <address> Token mint address (required)
171
+ --json Output as JSON (one object per line)
172
+ --append Append mode (simple log format)
173
+
174
+ # Stream token price updates
175
+ clawdvault stream token [options]
176
+ -m, --mint <address> Token mint address (required)
177
+ --json Output as JSON
178
+
179
+ # Stream chat messages
180
+ clawdvault stream chat [options]
181
+ -m, --mint <address> Token mint address (required)
182
+ --json Output as JSON
183
+
184
+ Examples:
185
+ # Watch trades in real-time (table mode)
186
+ clawdvault stream trades -m TOKEN_MINT
187
+
188
+ # Watch trades for scripting (JSON output)
189
+ clawdvault stream trades -m TOKEN_MINT --json
190
+
191
+ # Log trades to file
192
+ clawdvault stream trades -m TOKEN_MINT --append >> trades.log
193
+
194
+ # Monitor price changes
195
+ clawdvault stream token -m TOKEN_MINT
196
+
197
+ # Watch chat
198
+ clawdvault stream chat -m TOKEN_MINT
199
+
200
+ # Pipe to jq for filtering
201
+ clawdvault stream trades -m TOKEN_MINT --json | jq 'select(.type == "buy")'
202
+ ```
203
+
204
+ **Features:**
205
+ - Auto-reconnect on connection loss
206
+ - Graceful shutdown with Ctrl+C
207
+ - Multiple output modes: table (default), append, JSON
208
+ - Table mode clears and updates in-place
209
+ - JSON mode outputs one object per line (great for piping)
210
+
211
+ ### `clawdvault wallet`
212
+
213
+ Wallet management and info.
214
+
215
+ ```bash
216
+ # Show wallet info (address, SOL balance)
217
+ clawdvault wallet info [-w, --wallet <path>]
218
+
219
+ # Generate new wallet
220
+ clawdvault wallet init [-o, --output <path>] [--force]
221
+ Default output: ~/.clawdvault/wallet.json
222
+
223
+ # Get wallet address only
224
+ clawdvault wallet address [-w, --wallet <path>]
72
225
 
73
226
  # Check token balance
74
- clawdvault wallet balance -m TOKEN_MINT_ADDRESS
227
+ clawdvault wallet balance -m, --mint <address> [-w, --wallet <path>]
75
228
 
76
- # Get deposit address
77
- clawdvault wallet address
229
+ # Network status
230
+ clawdvault wallet network [--json]
231
+
232
+ # Current SOL/USD price
233
+ clawdvault wallet sol-price [--json]
78
234
 
79
- # Request devnet SOL (devnet only)
80
- clawdvault wallet airdrop --sol 1
235
+ Examples:
236
+ clawdvault wallet init
237
+ clawdvault wallet init -o ~/my-wallet.json
238
+ clawdvault wallet info
239
+ clawdvault wallet balance -m TOKEN_MINT
240
+ clawdvault wallet address
81
241
  ```
82
242
 
83
243
  ## Configuration
@@ -85,24 +245,34 @@ clawdvault wallet airdrop --sol 1
85
245
  ### Environment Variables
86
246
 
87
247
  ```bash
88
- # Wallet path
248
+ # Wallet path (overrides default locations)
89
249
  export CLAWDVAULT_WALLET=~/.config/solana/id.json
90
250
 
91
251
  # Custom API endpoint
92
252
  export CLAWDVAULT_API_URL=https://clawdvault.com/api
93
253
 
94
- # Solana RPC (default: mainnet)
254
+ # Solana RPC endpoint (default: mainnet)
255
+ export SOLANA_RPC_URL=https://api.mainnet-beta.solana.com
256
+ # For devnet testing:
95
257
  export SOLANA_RPC_URL=https://api.devnet.solana.com
96
258
  ```
97
259
 
260
+ ### Wallet Lookup Order
261
+
262
+ 1. `--wallet` / `-w` flag
263
+ 2. `CLAWDVAULT_WALLET` environment variable
264
+ 3. `~/.clawdvault/wallet.json`
265
+ 4. `~/.config/solana/id.json` (Solana CLI default)
266
+
98
267
  ### Global Options
99
268
 
100
269
  All commands support:
101
270
 
102
271
  ```bash
103
- -w, --wallet <path> # Specify wallet file
104
- --rpc <url> # Specify RPC endpoint
105
- --json # Output as JSON
272
+ -w, --wallet <path> Specify wallet file
273
+ --rpc <url> Specify RPC endpoint
274
+ --json Output as JSON (where applicable)
275
+ -h, --help Show help
106
276
  ```
107
277
 
108
278
  ## Examples
@@ -113,34 +283,129 @@ All commands support:
113
283
  # 1. Generate wallet (first time only)
114
284
  clawdvault wallet init
115
285
 
116
- # 2. Check your address
286
+ # 2. Check your address and fund with SOL
117
287
  clawdvault wallet address
288
+ # Send SOL to this address from an exchange or another wallet
118
289
 
119
- # 3. Fund with SOL (or use airdrop on devnet)
120
- clawdvault wallet airdrop --sol 2
290
+ # 3. Verify SOL balance
291
+ clawdvault wallet info
121
292
 
122
- # 4. Create token
293
+ # 4. Create your token
123
294
  clawdvault token create \
124
295
  --name "Moon Shot" \
125
296
  --symbol "MOON" \
126
- --description "To the moon!" \
297
+ --description "To the moon! 🚀" \
127
298
  --image ./moon.png \
128
- --twitter @moonshot \
129
- --website https://moonshot.io
299
+ --twitter https://twitter.com/moonshot \
300
+ --website https://moonshot.io \
301
+ --initial-buy 0.1
130
302
 
131
- # 5. Check your token
303
+ # 5. Check your new token
132
304
  clawdvault token get YOUR_TOKEN_MINT
133
305
 
134
- # 6. Buy more (optional)
135
- clawdvault trade buy --mint YOUR_TOKEN_MINT --sol 0.5
306
+ # 6. View it on ClawdVault
307
+ echo "https://clawdvault.com/token/YOUR_TOKEN_MINT"
308
+ ```
309
+
310
+ ### Trading Workflow
311
+
312
+ ```bash
313
+ # Get a quote first
314
+ clawdvault trade quote -m TOKEN_MINT -t buy -a 0.5
315
+
316
+ # Simulate the trade (dry run)
317
+ clawdvault trade buy -m TOKEN_MINT -a 0.5 --simulate
318
+
319
+ # Execute the trade
320
+ clawdvault trade buy -m TOKEN_MINT -a 0.5
321
+
322
+ # Check your balance
323
+ clawdvault wallet balance -m TOKEN_MINT
324
+
325
+ # Take profits - sell 25%
326
+ clawdvault trade sell -m TOKEN_MINT -p 25
327
+
328
+ # Or sell specific amount
329
+ clawdvault trade sell -m TOKEN_MINT -a 500000
330
+ ```
331
+
332
+ ### Monitoring
333
+
334
+ ```bash
335
+ # Check token stats
336
+ clawdvault token stats TOKEN_MINT --json
337
+
338
+ # View recent trades
339
+ clawdvault trade history -m TOKEN_MINT -l 50
340
+
341
+ # Check top holders
342
+ clawdvault token holders TOKEN_MINT
136
343
  ```
137
344
 
138
345
  ## Network Support
139
346
 
140
- - **Mainnet**: Production trading with real SOL
141
- - **Devnet**: Free testing with faucet SOL
347
+ | Network | RPC URL | Notes |
348
+ |---------|---------|-------|
349
+ | Mainnet | `https://api.mainnet-beta.solana.com` | Production (default) |
350
+ | Devnet | `https://api.devnet.solana.com` | Free testing |
351
+
352
+ ```bash
353
+ # Use devnet for testing
354
+ export SOLANA_RPC_URL=https://api.devnet.solana.com
355
+ clawdvault tokens list
356
+ ```
357
+
358
+ ## Troubleshooting
359
+
360
+ ### "Error: Wallet not found"
361
+ ```bash
362
+ # Generate a new wallet
363
+ clawdvault wallet init
364
+
365
+ # Or set path to existing wallet
366
+ export CLAWDVAULT_WALLET=~/.config/solana/id.json
367
+ ```
368
+
369
+ ### "Error: Insufficient SOL balance"
370
+ Your wallet needs SOL for transaction fees:
371
+ ```bash
372
+ clawdvault wallet info # Check balance
373
+ # Fund your wallet address with SOL
374
+ ```
375
+
376
+ ### "Error: Slippage exceeded"
377
+ Price moved during transaction. Increase slippage:
378
+ ```bash
379
+ clawdvault trade buy -m MINT -a 0.1 -s 5 # 5% slippage
380
+ ```
381
+
382
+ ### "Error: Token not found"
383
+ - Verify the mint address is correct
384
+ - Token may not be indexed yet (wait a few seconds after creation)
385
+
386
+ ### Transaction stuck/pending
387
+ - Solana network may be congested
388
+ - Check transaction on [Solscan](https://solscan.io)
389
+ - Try again with higher priority fee (coming soon)
390
+
391
+ ### Debug mode
392
+ Add `DEBUG=clawdvault:*` for verbose logging:
393
+ ```bash
394
+ DEBUG=clawdvault:* clawdvault trade buy -m MINT -a 0.1
395
+ ```
396
+
397
+ ## Programmatic Usage
398
+
399
+ You can also use the CLI from Node.js scripts:
400
+
401
+ ```typescript
402
+ import { execSync } from 'child_process';
403
+
404
+ const result = execSync('clawdvault tokens list --json', { encoding: 'utf-8' });
405
+ const tokens = JSON.parse(result);
406
+ ```
142
407
 
143
- Use `--rpc https://api.devnet.solana.com` or set `SOLANA_RPC_URL` for devnet.
408
+ For more control, use the [@clawdvault/sdk](https://www.npmjs.com/package/@clawdvault/sdk) package directly.
144
409
 
145
410
  ## License
146
411
 
package/dist/index.js CHANGED
@@ -24,8 +24,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/index.ts
27
- var import_commander5 = require("commander");
28
- var import_chalk6 = __toESM(require("chalk"));
27
+ var import_commander6 = require("commander");
28
+ var import_chalk7 = __toESM(require("chalk"));
29
29
 
30
30
  // src/commands/tokens.ts
31
31
  var import_commander = require("commander");
@@ -223,6 +223,7 @@ var import_commander2 = require("commander");
223
223
  var import_chalk3 = __toESM(require("chalk"));
224
224
  var import_cli_table32 = __toESM(require("cli-table3"));
225
225
  var fs2 = __toESM(require("fs"));
226
+ var import_sdk3 = require("@clawdvault/sdk");
226
227
  var tokenCommand = new import_commander2.Command("token").description("Token operations");
227
228
  tokenCommand.command("get <mint>").description("Get token details").option("--json", "Output as JSON").action(async (mint, options) => {
228
229
  const spin = spinner("Fetching token...").start();
@@ -411,11 +412,86 @@ tokenCommand.command("holders <mint>").description("Get top token holders").opti
411
412
  handleError(err);
412
413
  }
413
414
  });
415
+ tokenCommand.command("watch <mint>").description("Watch token price in real-time").option("--json", "Output as JSON").action(async (mint, options) => {
416
+ const baseUrl = process.env.CLAWDVAULT_API_URL || "https://clawdvault.com/api";
417
+ console.log(import_chalk3.default.bold(`
418
+ \u{1F4C8} Watching ${shortenAddress(mint)}
419
+ `));
420
+ info(`Connecting to ${baseUrl}...`);
421
+ console.log(import_chalk3.default.dim("Press Ctrl+C to stop\n"));
422
+ const streaming = (0, import_sdk3.createStreaming)(baseUrl);
423
+ const conn = streaming.streamToken(mint);
424
+ const client = createReadOnlyClient();
425
+ let solPrice = 0;
426
+ try {
427
+ const { price } = await client.getSolPrice();
428
+ solPrice = price;
429
+ } catch {
430
+ }
431
+ let tokenInfo = {};
432
+ let lastUpdate = null;
433
+ const displayUpdate = (update) => {
434
+ if (options.json) {
435
+ console.log(JSON.stringify({ ...update, ...tokenInfo }));
436
+ return;
437
+ }
438
+ console.clear();
439
+ console.log(import_chalk3.default.bold(`
440
+ \u{1F4C8} ${tokenInfo.name || "Token"} (${tokenInfo.symbol || shortenAddress(mint)})
441
+ `));
442
+ const table = new import_cli_table32.default({
443
+ style: { head: [], border: [] }
444
+ });
445
+ const priceUsd = solPrice > 0 ? formatUsd(update.price_sol * solPrice) : "-";
446
+ const mcapUsd = solPrice > 0 ? formatUsd(update.market_cap_sol * solPrice) : "-";
447
+ table.push(
448
+ { [import_chalk3.default.cyan("Price (SOL)")]: formatSol(update.price_sol) },
449
+ { [import_chalk3.default.cyan("Price (USD)")]: priceUsd },
450
+ { [import_chalk3.default.cyan("Market Cap (SOL)")]: formatSol(update.market_cap_sol) },
451
+ { [import_chalk3.default.cyan("Market Cap (USD)")]: mcapUsd },
452
+ { [import_chalk3.default.cyan("Bonding Curve SOL")]: formatSol(update.real_sol_reserves) },
453
+ { [import_chalk3.default.cyan("Status")]: update.graduated ? import_chalk3.default.green("\u2713 Graduated") : import_chalk3.default.yellow("Bonding Curve") }
454
+ );
455
+ console.log(table.toString());
456
+ if (lastUpdate && lastUpdate.price_sol !== update.price_sol) {
457
+ const change = (update.price_sol - lastUpdate.price_sol) / lastUpdate.price_sol * 100;
458
+ const changeStr = change >= 0 ? import_chalk3.default.green(`+${change.toFixed(2)}%`) : import_chalk3.default.red(`${change.toFixed(2)}%`);
459
+ console.log(`
460
+ ${import_chalk3.default.dim("Last change:")} ${changeStr}`);
461
+ }
462
+ console.log(import_chalk3.default.dim("\nLast update: " + new Date(update.timestamp).toLocaleTimeString()));
463
+ console.log(import_chalk3.default.dim("Press Ctrl+C to stop"));
464
+ lastUpdate = update;
465
+ };
466
+ conn.onConnect(() => success("Connected to stream"));
467
+ conn.onDisconnect(() => warn("Disconnected - reconnecting..."));
468
+ conn.on("connected", (data) => {
469
+ tokenInfo = { name: data.name, symbol: data.symbol };
470
+ displayUpdate(data);
471
+ });
472
+ conn.on("update", displayUpdate);
473
+ conn.on("trade", (trade) => {
474
+ if (lastUpdate) {
475
+ lastUpdate.price_sol = trade.price_sol;
476
+ displayUpdate(lastUpdate);
477
+ }
478
+ });
479
+ conn.connect();
480
+ process.on("SIGINT", () => {
481
+ console.log("\n");
482
+ info("Disconnecting...");
483
+ streaming.disconnectAll();
484
+ process.exit(0);
485
+ });
486
+ await new Promise(() => {
487
+ });
488
+ });
414
489
 
415
490
  // src/commands/trade.ts
416
491
  var import_commander3 = require("commander");
417
492
  var import_chalk4 = __toESM(require("chalk"));
418
493
  var import_cli_table33 = __toESM(require("cli-table3"));
494
+ var import_sdk4 = require("@clawdvault/sdk");
419
495
  var tradeCommand = new import_commander3.Command("trade").description("Trading operations");
420
496
  tradeCommand.command("buy").description("Buy tokens").requiredOption("-m, --mint <address>", "Token mint address").requiredOption("-a, --sol <amount>", "Amount of SOL to spend").option("-s, --slippage <percent>", "Slippage tolerance (default: 1%)", "1").option("-w, --wallet <path>", "Wallet file path").option("--simulate", "Only simulate, don't execute").action(async (options) => {
421
497
  const { client, signer, walletAddress } = createClientWithWallet(options.wallet);
@@ -630,6 +706,78 @@ tradeCommand.command("history").description("Get trade history for a token").req
630
706
  handleError(err);
631
707
  }
632
708
  });
709
+ tradeCommand.command("stream").description("Stream trades in real-time").requiredOption("-m, --mint <address>", "Token mint address").option("--json", "Output as JSON (one object per line)").option("--append", "Append mode (simple log format)").action(async (options) => {
710
+ const baseUrl = process.env.CLAWDVAULT_API_URL || "https://clawdvault.com/api";
711
+ console.log(import_chalk4.default.bold(`
712
+ \u{1F4E1} Streaming trades for ${shortenAddress(options.mint)}
713
+ `));
714
+ info(`Connecting to ${baseUrl}...`);
715
+ console.log(import_chalk4.default.dim("Press Ctrl+C to stop\n"));
716
+ const streaming = (0, import_sdk4.createStreaming)(baseUrl);
717
+ const conn = streaming.streamTrades(options.mint);
718
+ const trades = [];
719
+ const MAX_DISPLAY = 20;
720
+ conn.onConnect(() => {
721
+ success("Connected to stream");
722
+ console.log();
723
+ });
724
+ conn.onDisconnect(() => warn("Disconnected - reconnecting..."));
725
+ conn.on("trade", (trade) => {
726
+ if (options.json) {
727
+ console.log(JSON.stringify(trade));
728
+ return;
729
+ }
730
+ if (options.append) {
731
+ const typeStr = trade.type === "buy" ? import_chalk4.default.green("BUY ") : import_chalk4.default.red("SELL");
732
+ const time = new Date(trade.created_at).toLocaleTimeString();
733
+ console.log(
734
+ `${import_chalk4.default.dim(time)} ${typeStr} ${formatSol(trade.sol_amount).padEnd(15)} ${formatTokens(trade.token_amount).padEnd(12)} @ ${formatSol(trade.price_sol).padEnd(18)} ${import_chalk4.default.dim(shortenAddress(trade.trader))}`
735
+ );
736
+ return;
737
+ }
738
+ trades.unshift(trade);
739
+ if (trades.length > MAX_DISPLAY) {
740
+ trades.pop();
741
+ }
742
+ console.clear();
743
+ console.log(import_chalk4.default.bold(`
744
+ \u{1F4E1} Live Trades - ${shortenAddress(options.mint)}
745
+ `));
746
+ const table = new import_cli_table33.default({
747
+ head: [
748
+ import_chalk4.default.cyan("Type"),
749
+ import_chalk4.default.cyan("SOL"),
750
+ import_chalk4.default.cyan("Tokens"),
751
+ import_chalk4.default.cyan("Price"),
752
+ import_chalk4.default.cyan("Trader"),
753
+ import_chalk4.default.cyan("Time")
754
+ ],
755
+ style: { head: [], border: [] }
756
+ });
757
+ for (const t of trades) {
758
+ const typeStr = t.type === "buy" ? import_chalk4.default.green("BUY") : import_chalk4.default.red("SELL");
759
+ table.push([
760
+ typeStr,
761
+ formatSol(t.sol_amount),
762
+ formatTokens(t.token_amount),
763
+ formatSol(t.price_sol),
764
+ shortenAddress(t.trader),
765
+ new Date(t.created_at).toLocaleTimeString()
766
+ ]);
767
+ }
768
+ console.log(table.toString());
769
+ console.log(import_chalk4.default.dim("\nPress Ctrl+C to stop"));
770
+ });
771
+ conn.connect();
772
+ process.on("SIGINT", () => {
773
+ console.log("\n");
774
+ info("Disconnecting...");
775
+ streaming.disconnectAll();
776
+ process.exit(0);
777
+ });
778
+ await new Promise(() => {
779
+ });
780
+ });
633
781
 
634
782
  // src/commands/wallet.ts
635
783
  var import_commander4 = require("commander");
@@ -1007,18 +1155,228 @@ walletCommand.command("airdrop").description("Request SOL from devnet faucet (de
1007
1155
  }
1008
1156
  });
1009
1157
 
1158
+ // src/commands/stream.ts
1159
+ var import_commander5 = require("commander");
1160
+ var import_chalk6 = __toESM(require("chalk"));
1161
+ var import_cli_table35 = __toESM(require("cli-table3"));
1162
+ var import_sdk5 = require("@clawdvault/sdk");
1163
+ function getBaseUrl2() {
1164
+ return process.env.CLAWDVAULT_API_URL || "https://clawdvault.com/api";
1165
+ }
1166
+ var streamCommand = new import_commander5.Command("stream").description("Real-time streaming commands");
1167
+ streamCommand.command("trades").description("Stream real-time trades for a token").requiredOption("-m, --mint <address>", "Token mint address").option("--json", "Output as JSON (one object per line)").option("--append", "Append mode instead of table (good for logging)").action(async (options) => {
1168
+ const baseUrl = getBaseUrl2();
1169
+ console.log(import_chalk6.default.bold(`
1170
+ \u{1F4E1} Streaming trades for ${shortenAddress(options.mint)}
1171
+ `));
1172
+ info(`Connecting to ${baseUrl}...`);
1173
+ console.log(import_chalk6.default.dim("Press Ctrl+C to stop\n"));
1174
+ const streaming = (0, import_sdk5.createStreaming)(baseUrl, {
1175
+ autoReconnect: true,
1176
+ reconnectDelay: 3e3
1177
+ });
1178
+ const conn = streaming.streamTrades(options.mint);
1179
+ const trades = [];
1180
+ const MAX_DISPLAY = 20;
1181
+ conn.onConnect(() => {
1182
+ success("Connected to stream");
1183
+ console.log();
1184
+ });
1185
+ conn.onDisconnect(() => {
1186
+ warn("Disconnected - reconnecting...");
1187
+ });
1188
+ conn.onError((err) => {
1189
+ if (!err.message.includes("Max reconnect")) {
1190
+ } else {
1191
+ console.error(import_chalk6.default.red(`Error: ${err.message}`));
1192
+ process.exit(1);
1193
+ }
1194
+ });
1195
+ conn.on("trade", (trade) => {
1196
+ if (options.json) {
1197
+ console.log(JSON.stringify(trade));
1198
+ return;
1199
+ }
1200
+ if (options.append) {
1201
+ const typeStr = trade.type === "buy" ? import_chalk6.default.green("BUY ") : import_chalk6.default.red("SELL");
1202
+ const time = new Date(trade.created_at).toLocaleTimeString();
1203
+ console.log(
1204
+ `${import_chalk6.default.dim(time)} ${typeStr} ${formatSol(trade.sol_amount).padEnd(15)} ${formatTokens(trade.token_amount).padEnd(12)} @ ${formatSol(trade.price_sol).padEnd(18)} ${import_chalk6.default.dim(shortenAddress(trade.trader))}`
1205
+ );
1206
+ return;
1207
+ }
1208
+ trades.unshift(trade);
1209
+ if (trades.length > MAX_DISPLAY) {
1210
+ trades.pop();
1211
+ }
1212
+ console.clear();
1213
+ console.log(import_chalk6.default.bold(`
1214
+ \u{1F4E1} Live Trades - ${shortenAddress(options.mint)}
1215
+ `));
1216
+ const table = new import_cli_table35.default({
1217
+ head: [
1218
+ import_chalk6.default.cyan("Type"),
1219
+ import_chalk6.default.cyan("SOL"),
1220
+ import_chalk6.default.cyan("Tokens"),
1221
+ import_chalk6.default.cyan("Price"),
1222
+ import_chalk6.default.cyan("Trader"),
1223
+ import_chalk6.default.cyan("Time")
1224
+ ],
1225
+ style: { head: [], border: [] }
1226
+ });
1227
+ for (const t of trades) {
1228
+ const typeStr = t.type === "buy" ? import_chalk6.default.green("BUY") : import_chalk6.default.red("SELL");
1229
+ table.push([
1230
+ typeStr,
1231
+ formatSol(t.sol_amount),
1232
+ formatTokens(t.token_amount),
1233
+ formatSol(t.price_sol),
1234
+ shortenAddress(t.trader),
1235
+ new Date(t.created_at).toLocaleTimeString()
1236
+ ]);
1237
+ }
1238
+ console.log(table.toString());
1239
+ console.log(import_chalk6.default.dim("\nPress Ctrl+C to stop"));
1240
+ });
1241
+ conn.connect();
1242
+ process.on("SIGINT", () => {
1243
+ console.log("\n");
1244
+ info("Disconnecting...");
1245
+ streaming.disconnectAll();
1246
+ process.exit(0);
1247
+ });
1248
+ await new Promise(() => {
1249
+ });
1250
+ });
1251
+ streamCommand.command("token").description("Stream real-time token updates (price, market cap)").requiredOption("-m, --mint <address>", "Token mint address").option("--json", "Output as JSON (one object per line)").action(async (options) => {
1252
+ const baseUrl = getBaseUrl2();
1253
+ console.log(import_chalk6.default.bold(`
1254
+ \u{1F4C8} Watching token ${shortenAddress(options.mint)}
1255
+ `));
1256
+ info(`Connecting to ${baseUrl}...`);
1257
+ console.log(import_chalk6.default.dim("Press Ctrl+C to stop\n"));
1258
+ const streaming = (0, import_sdk5.createStreaming)(baseUrl);
1259
+ const conn = streaming.streamToken(options.mint);
1260
+ const client = createReadOnlyClient();
1261
+ let solPrice = 0;
1262
+ try {
1263
+ const { price } = await client.getSolPrice();
1264
+ solPrice = price;
1265
+ } catch {
1266
+ }
1267
+ let tokenInfo = {};
1268
+ let lastUpdate = null;
1269
+ const displayUpdate = (update) => {
1270
+ if (options.json) {
1271
+ console.log(JSON.stringify({ ...update, ...tokenInfo }));
1272
+ return;
1273
+ }
1274
+ console.clear();
1275
+ console.log(import_chalk6.default.bold(`
1276
+ \u{1F4C8} ${tokenInfo.name || "Token"} (${tokenInfo.symbol || shortenAddress(options.mint)})
1277
+ `));
1278
+ const table = new import_cli_table35.default({
1279
+ style: { head: [], border: [] }
1280
+ });
1281
+ const priceUsd = solPrice > 0 ? formatUsd(update.price_sol * solPrice) : "-";
1282
+ const mcapUsd = solPrice > 0 ? formatUsd(update.market_cap_sol * solPrice) : "-";
1283
+ table.push(
1284
+ { [import_chalk6.default.cyan("Price (SOL)")]: formatSol(update.price_sol) },
1285
+ { [import_chalk6.default.cyan("Price (USD)")]: priceUsd },
1286
+ { [import_chalk6.default.cyan("Market Cap (SOL)")]: formatSol(update.market_cap_sol) },
1287
+ { [import_chalk6.default.cyan("Market Cap (USD)")]: mcapUsd },
1288
+ { [import_chalk6.default.cyan("Bonding Curve SOL")]: formatSol(update.real_sol_reserves) },
1289
+ { [import_chalk6.default.cyan("Status")]: update.graduated ? import_chalk6.default.green("\u2713 Graduated") : import_chalk6.default.yellow("Bonding Curve") }
1290
+ );
1291
+ console.log(table.toString());
1292
+ if (lastUpdate && lastUpdate.price_sol !== update.price_sol) {
1293
+ const change = (update.price_sol - lastUpdate.price_sol) / lastUpdate.price_sol * 100;
1294
+ const changeStr = change >= 0 ? import_chalk6.default.green(`+${change.toFixed(2)}%`) : import_chalk6.default.red(`${change.toFixed(2)}%`);
1295
+ console.log(`
1296
+ ${import_chalk6.default.dim("Last change:")} ${changeStr}`);
1297
+ }
1298
+ console.log(import_chalk6.default.dim("\nLast update: " + new Date(update.timestamp).toLocaleTimeString()));
1299
+ console.log(import_chalk6.default.dim("Press Ctrl+C to stop"));
1300
+ lastUpdate = update;
1301
+ };
1302
+ conn.onConnect(() => {
1303
+ success("Connected to stream");
1304
+ });
1305
+ conn.onDisconnect(() => {
1306
+ warn("Disconnected - reconnecting...");
1307
+ });
1308
+ conn.on("connected", (data) => {
1309
+ tokenInfo = { name: data.name, symbol: data.symbol };
1310
+ displayUpdate(data);
1311
+ });
1312
+ conn.on("update", displayUpdate);
1313
+ conn.on("trade", (trade) => {
1314
+ if (lastUpdate) {
1315
+ lastUpdate.price_sol = trade.price_sol;
1316
+ displayUpdate(lastUpdate);
1317
+ }
1318
+ });
1319
+ conn.connect();
1320
+ process.on("SIGINT", () => {
1321
+ console.log("\n");
1322
+ info("Disconnecting...");
1323
+ streaming.disconnectAll();
1324
+ process.exit(0);
1325
+ });
1326
+ await new Promise(() => {
1327
+ });
1328
+ });
1329
+ streamCommand.command("chat").description("Stream real-time chat messages for a token").requiredOption("-m, --mint <address>", "Token mint address").option("--json", "Output as JSON (one object per line)").action(async (options) => {
1330
+ const baseUrl = getBaseUrl2();
1331
+ console.log(import_chalk6.default.bold(`
1332
+ \u{1F4AC} Streaming chat for ${shortenAddress(options.mint)}
1333
+ `));
1334
+ info(`Connecting to ${baseUrl}...`);
1335
+ console.log(import_chalk6.default.dim("Press Ctrl+C to stop\n"));
1336
+ const streaming = (0, import_sdk5.createStreaming)(baseUrl);
1337
+ const conn = streaming.streamChat(options.mint);
1338
+ conn.onConnect(() => {
1339
+ success("Connected to stream");
1340
+ console.log();
1341
+ });
1342
+ conn.onDisconnect(() => {
1343
+ warn("Disconnected - reconnecting...");
1344
+ });
1345
+ conn.on("message", (msg) => {
1346
+ if (options.json) {
1347
+ console.log(JSON.stringify(msg));
1348
+ return;
1349
+ }
1350
+ const time = new Date(msg.created_at).toLocaleTimeString();
1351
+ const sender = msg.username || shortenAddress(msg.wallet);
1352
+ console.log(
1353
+ `${import_chalk6.default.dim(time)} ${import_chalk6.default.cyan(sender)}: ${msg.message}`
1354
+ );
1355
+ });
1356
+ conn.connect();
1357
+ process.on("SIGINT", () => {
1358
+ console.log("\n");
1359
+ info("Disconnecting...");
1360
+ streaming.disconnectAll();
1361
+ process.exit(0);
1362
+ });
1363
+ await new Promise(() => {
1364
+ });
1365
+ });
1366
+
1010
1367
  // src/index.ts
1011
- var program = new import_commander5.Command();
1368
+ var program = new import_commander6.Command();
1012
1369
  program.name("clawdvault").description("CLI for ClawdVault - Solana token launchpad").version("0.1.0");
1013
1370
  program.addCommand(tokensCommand);
1014
1371
  program.addCommand(tokenCommand);
1015
1372
  program.addCommand(tradeCommand);
1016
1373
  program.addCommand(walletCommand);
1374
+ program.addCommand(streamCommand);
1017
1375
  program.hook("preAction", () => {
1018
1376
  });
1019
1377
  program.configureOutput({
1020
1378
  outputError: (str, write) => {
1021
- write(import_chalk6.default.red(str));
1379
+ write(import_chalk7.default.red(str));
1022
1380
  }
1023
1381
  });
1024
1382
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawdvault/cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "CLI for ClawdVault - Solana token launchpad",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -15,7 +15,7 @@
15
15
  "clean": "rm -rf dist"
16
16
  },
17
17
  "dependencies": {
18
- "@clawdvault/sdk": "^0.1.1",
18
+ "@clawdvault/sdk": "^0.1.3",
19
19
  "@solana/spl-token": "^0.4.0",
20
20
  "@solana/web3.js": "^1.91.0",
21
21
  "bs58": "^5.0.0",