@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.
- package/README.md +298 -33
- package/dist/index.js +362 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# @clawdvault/cli
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@clawdvault/cli)
|
|
4
|
+
[](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
|
-
|
|
61
|
-
|
|
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
|
-
###
|
|
86
|
+
### `clawdvault token`
|
|
87
|
+
|
|
88
|
+
Token details and creation.
|
|
65
89
|
|
|
66
90
|
```bash
|
|
67
|
-
#
|
|
68
|
-
clawdvault
|
|
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
|
-
|
|
71
|
-
|
|
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
|
|
227
|
+
clawdvault wallet balance -m, --mint <address> [-w, --wallet <path>]
|
|
75
228
|
|
|
76
|
-
#
|
|
77
|
-
clawdvault wallet
|
|
229
|
+
# Network status
|
|
230
|
+
clawdvault wallet network [--json]
|
|
231
|
+
|
|
232
|
+
# Current SOL/USD price
|
|
233
|
+
clawdvault wallet sol-price [--json]
|
|
78
234
|
|
|
79
|
-
|
|
80
|
-
clawdvault wallet
|
|
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>
|
|
104
|
-
--rpc <url>
|
|
105
|
-
--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.
|
|
120
|
-
clawdvault wallet
|
|
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
|
|
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.
|
|
135
|
-
clawdvault
|
|
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
|
-
|
|
141
|
-
|
|
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
|
-
|
|
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
|
|
28
|
-
var
|
|
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
|
|
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(
|
|
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.
|
|
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.
|
|
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",
|