@darksol/terminal 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,198 @@
1
+ <p align="center">
2
+ <img src="assets/darksol-banner.png" alt="DARKSOL" width="600" />
3
+ </p>
4
+ <h3 align="center">Built by DARKSOL 🌑</h3>
5
+
6
+ ---
7
+
8
+ # @darksol/terminal
9
+
10
+ **All DARKSOL services. One terminal. Zero trust required.**
11
+
12
+ A unified CLI for market intel, trading, on-chain oracle, casino, prepaid cards, builder indexing, and more. Encrypted wallet management. Agent-native. OpenClaw-controllable.
13
+
14
+ ## Install
15
+
16
+ ```bash
17
+ npm install -g @darksol/terminal
18
+ ```
19
+
20
+ ## Quick Start
21
+
22
+ ```bash
23
+ # Show dashboard
24
+ darksol
25
+
26
+ # Create a wallet (AES-256-GCM encrypted)
27
+ darksol wallet create main
28
+
29
+ # Check balance
30
+ darksol wallet balance
31
+
32
+ # Set chain
33
+ darksol config set chain base
34
+
35
+ # Add custom RPC
36
+ darksol config rpc base https://your-rpc-endpoint.com
37
+
38
+ # Swap tokens
39
+ darksol trade swap -i ETH -o USDC -a 0.1
40
+
41
+ # Snipe a token
42
+ darksol trade snipe 0xTOKEN_ADDRESS -a 0.05
43
+
44
+ # Create DCA order
45
+ darksol dca create
46
+
47
+ # Market data
48
+ darksol market top
49
+ darksol market token VIRTUAL
50
+ darksol market compare ETH AERO VIRTUAL
51
+
52
+ # Oracle
53
+ darksol oracle flip
54
+ darksol oracle dice 20
55
+
56
+ # Casino
57
+ darksol casino bet coin-flip heads
58
+ darksol casino tables
59
+
60
+ # Execution scripts (automated trading)
61
+ darksol script templates # See available templates
62
+ darksol script create # Create from template (interactive)
63
+ darksol script list # List your scripts
64
+ darksol script run my-buy-script # Execute (requires wallet password)
65
+ darksol script show my-script # View details + code
66
+ darksol script edit my-script # Edit params/wallet/chain
67
+ darksol script clone my-script new-script
68
+ darksol script delete old-script
69
+
70
+ # Prepaid cards
71
+ darksol cards catalog
72
+
73
+ # Builder index
74
+ darksol builders leaderboard
75
+
76
+ # Facilitator
77
+ darksol facilitator health
78
+ ```
79
+
80
+ ## Wallet Security
81
+
82
+ - Private keys are **never stored in plaintext**
83
+ - AES-256-GCM encryption with scrypt key derivation
84
+ - Password required for every transaction
85
+ - Keys stored in `~/.darksol/wallets/` (encrypted JSON)
86
+ - No recovery without password — back it up
87
+
88
+ ## Modules
89
+
90
+ | Module | Description | Pricing |
91
+ |--------|-------------|---------|
92
+ | `wallet` | Create, import, manage wallets | Free |
93
+ | `trade` | Swap, snipe, token trading | Gas only |
94
+ | `dca` | Dollar-cost averaging engine | Gas only |
95
+ | `script` | Execution scripts & strategies | Free |
96
+ | `market` | Market intel, top movers, analysis | x402 micropayments |
97
+ | `oracle` | On-chain random number oracle | $0.05–$0.25 |
98
+ | `casino` | The Clawsino — on-chain betting | $1 flat bets |
99
+ | `cards` | Crypto → prepaid Visa/MC | 3% markup |
100
+ | `builders` | ERC-8021 builder leaderboard | Free |
101
+ | `facilitator` | x402 payment verification | Free |
102
+ | `config` | Terminal configuration | Free |
103
+
104
+ ## Execution Scripts
105
+
106
+ Automated trading strategies with full PK access. Scripts unlock your wallet at runtime and execute on-chain transactions.
107
+
108
+ ### Templates
109
+
110
+ | Template | Description |
111
+ |----------|-------------|
112
+ | `buy-token` | Buy a token with ETH at current price |
113
+ | `sell-token` | Sell a % of token balance for ETH |
114
+ | `limit-buy` | Watch price and buy at target (polling) |
115
+ | `stop-loss` | Auto-sell if value drops below threshold |
116
+ | `multi-buy` | Buy multiple tokens in one execution |
117
+ | `transfer` | Transfer ETH or tokens to an address |
118
+ | `empty` | Custom script — full ethers.js context |
119
+
120
+ ### Script Context
121
+
122
+ Every script gets:
123
+ ```javascript
124
+ module.exports = async function({ signer, provider, ethers, config, params }) {
125
+ // signer — ethers.Wallet (unlocked, connected to provider)
126
+ // provider — ethers.JsonRpcProvider for active chain
127
+ // ethers — the ethers library
128
+ // config — { chain, slippage, gasMultiplier, rpcs }
129
+ // params — your custom parameters
130
+ };
131
+ ```
132
+
133
+ ### Automation (OpenClaw / cron)
134
+
135
+ ```bash
136
+ # Run without prompts (password via flag)
137
+ darksol script run my-dca --password "mypass" --yes
138
+
139
+ # JSON output for programmatic use
140
+ darksol config set output json
141
+ ```
142
+
143
+ ## Configuration
144
+
145
+ Config stored at `~/.config/darksol-terminal/config.json`
146
+
147
+ ```bash
148
+ # View all settings
149
+ darksol config show
150
+
151
+ # Set active chain
152
+ darksol config set chain base
153
+
154
+ # Set slippage tolerance
155
+ darksol config set slippage 1.0
156
+
157
+ # Custom RPC
158
+ darksol config rpc base https://mainnet.base.org
159
+ darksol config rpc ethereum https://eth.llamarpc.com
160
+ darksol config rpc arbitrum https://arb1.arbitrum.io/rpc
161
+ ```
162
+
163
+ ## Supported Chains
164
+
165
+ - **Base** (default)
166
+ - Ethereum
167
+ - Polygon
168
+ - Arbitrum
169
+ - Optimism
170
+
171
+ ## OpenClaw Integration
172
+
173
+ DARKSOL Terminal is designed to be controlled by AI agents via OpenClaw:
174
+
175
+ ```bash
176
+ # Agents can run any command non-interactively
177
+ darksol market top --output json
178
+ darksol wallet balance main
179
+ darksol oracle flip
180
+ ```
181
+
182
+ JSON output mode for programmatic use:
183
+ ```bash
184
+ darksol config set output json
185
+ ```
186
+
187
+ ## Development
188
+
189
+ ```bash
190
+ git clone https://gitlab.com/darks0l/darksol-terminal
191
+ cd darksol-terminal
192
+ npm install
193
+ node bin/darksol.js
194
+ ```
195
+
196
+ ---
197
+
198
+ Built with teeth. 🌑
Binary file
package/bin/darksol.js ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { cli } from '../src/cli.js';
4
+
5
+ cli(process.argv);
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@darksol/terminal",
3
+ "version": "0.1.0",
4
+ "description": "DARKSOL Terminal — unified CLI for all DARKSOL services. Market intel, trading, oracle, casino, and more.",
5
+ "type": "module",
6
+ "bin": {
7
+ "darksol": "./bin/darksol.js"
8
+ },
9
+ "main": "./src/cli.js",
10
+ "scripts": {
11
+ "start": "node bin/darksol.js",
12
+ "dev": "node bin/darksol.js dashboard",
13
+ "test": "node --test tests/*.test.js"
14
+ },
15
+ "keywords": ["darksol", "crypto", "trading", "cli", "x402", "base", "ethereum", "defi"],
16
+ "author": "DARKSOL <chris00claw@gmail.com>",
17
+ "license": "MIT",
18
+ "dependencies": {
19
+ "chalk": "^5.3.0",
20
+ "commander": "^12.1.0",
21
+ "ethers": "^6.13.0",
22
+ "boxen": "^8.0.1",
23
+ "ora": "^8.1.0",
24
+ "cli-table3": "^0.6.5",
25
+ "inquirer": "^12.0.0",
26
+ "figlet": "^1.8.0",
27
+ "gradient-string": "^3.0.0",
28
+ "conf": "^13.0.1",
29
+ "nanospinner": "^1.1.0",
30
+ "node-fetch": "^3.3.2",
31
+ "blessed": "^0.1.81",
32
+ "blessed-contrib": "^4.11.0",
33
+ "terminal-link": "^3.0.0",
34
+ "update-notifier": "^7.3.1"
35
+ },
36
+ "engines": {
37
+ "node": ">=18.0.0"
38
+ }
39
+ }
package/src/cli.js ADDED
@@ -0,0 +1,434 @@
1
+ import { Command } from 'commander';
2
+ import { showBanner, showMiniBanner, showSection } from './ui/banner.js';
3
+ import { theme } from './ui/theme.js';
4
+ import { kvDisplay, success, error, warn, info } from './ui/components.js';
5
+ import { getConfig, setConfig, getAllConfig, getRPC, setRPC, configPath } from './config/store.js';
6
+ import { createWallet, importWallet, showWallets, getBalance, useWallet, exportWallet } from './wallet/manager.js';
7
+ import { executeSwap } from './trading/swap.js';
8
+ import { snipeToken, watchSnipe } from './trading/snipe.js';
9
+ import { createDCA, listDCA, cancelDCA, runDCA } from './trading/dca.js';
10
+ import { topMovers, tokenDetail, compareTokens } from './services/market.js';
11
+ import { oracleFlip, oracleDice, oracleNumber, oracleShuffle, oracleHealth } from './services/oracle.js';
12
+ import { casinoBet, casinoTables, casinoStats, casinoReceipt } from './services/casino.js';
13
+ import { cardsCatalog, cardsOrder, cardsStatus } from './services/cards.js';
14
+ import { facilitatorHealth, facilitatorVerify, facilitatorSettle } from './services/facilitator.js';
15
+ import { buildersLeaderboard, buildersLookup, buildersFeed } from './services/builders.js';
16
+ import { createScript, listScripts, runScript, showScript, editScript, deleteScript, cloneScript, listTemplates } from './scripts/engine.js';
17
+
18
+ export function cli(argv) {
19
+ const program = new Command();
20
+
21
+ program
22
+ .name('darksol')
23
+ .description(theme.gold('DARKSOL Terminal') + theme.dim(' — Ghost in the machine with teeth 🌑'))
24
+ .version('0.1.0')
25
+ ;
26
+
27
+ // ═══════════════════════════════════════
28
+ // WALLET COMMANDS
29
+ // ═══════════════════════════════════════
30
+ const wallet = program
31
+ .command('wallet')
32
+ .description('Wallet management — create, import, list, balance');
33
+
34
+ wallet
35
+ .command('create [name]')
36
+ .description('Create a new wallet')
37
+ .option('-c, --chain <chain>', 'Target chain', 'base')
38
+ .action((name, opts) => createWallet(name, opts));
39
+
40
+ wallet
41
+ .command('import [name]')
42
+ .description('Import wallet from private key')
43
+ .option('-c, --chain <chain>', 'Target chain', 'base')
44
+ .action((name, opts) => importWallet(name, opts));
45
+
46
+ wallet
47
+ .command('list')
48
+ .description('List all wallets')
49
+ .action(() => showWallets());
50
+
51
+ wallet
52
+ .command('balance [name]')
53
+ .description('Check wallet balance')
54
+ .action((name) => getBalance(name));
55
+
56
+ wallet
57
+ .command('use <name>')
58
+ .description('Set active wallet')
59
+ .action((name) => useWallet(name));
60
+
61
+ wallet
62
+ .command('export [name]')
63
+ .description('Export wallet details')
64
+ .action((name) => exportWallet(name));
65
+
66
+ // ═══════════════════════════════════════
67
+ // TRADING COMMANDS
68
+ // ═══════════════════════════════════════
69
+ const trade = program
70
+ .command('trade')
71
+ .description('Trading — swap, snipe, DCA');
72
+
73
+ trade
74
+ .command('swap')
75
+ .description('Swap tokens via DEX')
76
+ .requiredOption('-i, --in <token>', 'Token to sell (symbol or address)')
77
+ .requiredOption('-o, --out <token>', 'Token to buy (symbol or address)')
78
+ .requiredOption('-a, --amount <amount>', 'Amount to swap')
79
+ .option('-s, --slippage <percent>', 'Max slippage %', '0.5')
80
+ .option('-w, --wallet <name>', 'Wallet to use')
81
+ .action((opts) => executeSwap({
82
+ tokenIn: opts.in,
83
+ tokenOut: opts.out,
84
+ amount: opts.amount,
85
+ slippage: parseFloat(opts.slippage),
86
+ wallet: opts.wallet,
87
+ }));
88
+
89
+ trade
90
+ .command('snipe <token>')
91
+ .description('Snipe a token — fast buy with ETH')
92
+ .requiredOption('-a, --amount <eth>', 'ETH amount to spend')
93
+ .option('-s, --slippage <percent>', 'Max slippage %', '1')
94
+ .option('-g, --gas <multiplier>', 'Gas priority multiplier', '1.5')
95
+ .option('-w, --wallet <name>', 'Wallet to use')
96
+ .action((token, opts) => snipeToken(token, opts.amount, {
97
+ slippage: parseFloat(opts.slippage),
98
+ gas: parseFloat(opts.gas),
99
+ wallet: opts.wallet,
100
+ }));
101
+
102
+ trade
103
+ .command('watch')
104
+ .description('Watch for new pairs (snipe monitor)')
105
+ .option('--auto', 'Auto-snipe mode (dangerous)')
106
+ .option('-a, --amount <eth>', 'Auto-snipe amount')
107
+ .action((opts) => watchSnipe(opts));
108
+
109
+ // ═══════════════════════════════════════
110
+ // DCA COMMANDS
111
+ // ═══════════════════════════════════════
112
+ const dca = program
113
+ .command('dca')
114
+ .description('Dollar-cost averaging');
115
+
116
+ dca
117
+ .command('create')
118
+ .description('Create a new DCA order')
119
+ .action(() => createDCA());
120
+
121
+ dca
122
+ .command('list')
123
+ .description('List DCA orders')
124
+ .action(() => listDCA());
125
+
126
+ dca
127
+ .command('cancel <id>')
128
+ .description('Cancel a DCA order')
129
+ .action((id) => cancelDCA(id));
130
+
131
+ dca
132
+ .command('run')
133
+ .description('Execute pending DCA orders')
134
+ .action(() => runDCA());
135
+
136
+ // ═══════════════════════════════════════
137
+ // MARKET COMMANDS
138
+ // ═══════════════════════════════════════
139
+ const market = program
140
+ .command('market')
141
+ .description('Market intel — prices, movers, analysis');
142
+
143
+ market
144
+ .command('top')
145
+ .description('Top movers on chain')
146
+ .option('-c, --chain <chain>', 'Chain to scan')
147
+ .option('-l, --limit <n>', 'Number of results', '15')
148
+ .action((opts) => topMovers(opts.chain, { limit: parseInt(opts.limit) }));
149
+
150
+ market
151
+ .command('token <query>')
152
+ .description('Token detail — price, volume, liquidity')
153
+ .action((query) => tokenDetail(query));
154
+
155
+ market
156
+ .command('compare <tokens...>')
157
+ .description('Compare multiple tokens side by side')
158
+ .action((tokens) => compareTokens(tokens));
159
+
160
+ // ═══════════════════════════════════════
161
+ // ORACLE COMMANDS
162
+ // ═══════════════════════════════════════
163
+ const oracle = program
164
+ .command('oracle')
165
+ .description('On-chain random oracle');
166
+
167
+ oracle
168
+ .command('flip')
169
+ .description('Coin flip')
170
+ .action(() => oracleFlip());
171
+
172
+ oracle
173
+ .command('dice [sides]')
174
+ .description('Roll dice')
175
+ .action((sides) => oracleDice(parseInt(sides) || 6));
176
+
177
+ oracle
178
+ .command('number [min] [max]')
179
+ .description('Random number in range')
180
+ .action((min, max) => oracleNumber(parseInt(min) || 1, parseInt(max) || 100));
181
+
182
+ oracle
183
+ .command('shuffle <items...>')
184
+ .description('Shuffle a list')
185
+ .action((items) => oracleShuffle(items));
186
+
187
+ oracle
188
+ .command('health')
189
+ .description('Oracle status')
190
+ .action(() => oracleHealth());
191
+
192
+ // ═══════════════════════════════════════
193
+ // CASINO COMMANDS
194
+ // ═══════════════════════════════════════
195
+ const casino = program
196
+ .command('casino')
197
+ .description('The Clawsino — on-chain betting');
198
+
199
+ casino
200
+ .command('bet <game> [choice]')
201
+ .description('Place a bet (coin-flip, dice, hilo, slots)')
202
+ .option('-n, --number <n>', 'Number for dice over/under')
203
+ .option('-w, --wallet <addr>', 'Wallet address')
204
+ .action((game, choice, opts) => casinoBet(game, { choice, ...opts }));
205
+
206
+ casino
207
+ .command('tables')
208
+ .description('View game tables')
209
+ .action(() => casinoTables());
210
+
211
+ casino
212
+ .command('stats')
213
+ .description('House stats')
214
+ .action(() => casinoStats());
215
+
216
+ casino
217
+ .command('receipt <id>')
218
+ .description('Verify bet receipt')
219
+ .action((id) => casinoReceipt(id));
220
+
221
+ // ═══════════════════════════════════════
222
+ // CARDS COMMANDS
223
+ // ═══════════════════════════════════════
224
+ const cards = program
225
+ .command('cards')
226
+ .description('Prepaid cards — crypto to Visa/MC');
227
+
228
+ cards
229
+ .command('catalog')
230
+ .description('Available card providers')
231
+ .action(() => cardsCatalog());
232
+
233
+ cards
234
+ .command('order')
235
+ .description('Order a prepaid card')
236
+ .requiredOption('-p, --provider <name>', 'Card provider')
237
+ .requiredOption('-a, --amount <usd>', 'Card amount in USD')
238
+ .action((opts) => cardsOrder(opts.provider, parseFloat(opts.amount)));
239
+
240
+ cards
241
+ .command('status <orderId>')
242
+ .description('Check order status')
243
+ .action((id) => cardsStatus(id));
244
+
245
+ // ═══════════════════════════════════════
246
+ // BUILDERS COMMANDS
247
+ // ═══════════════════════════════════════
248
+ const builders = program
249
+ .command('builders')
250
+ .description('ERC-8021 builder index');
251
+
252
+ builders
253
+ .command('leaderboard')
254
+ .description('Builder leaderboard')
255
+ .option('-l, --limit <n>', 'Number of results', '20')
256
+ .action((opts) => buildersLeaderboard({ limit: parseInt(opts.limit) }));
257
+
258
+ builders
259
+ .command('lookup <code>')
260
+ .description('Builder profile')
261
+ .action((code) => buildersLookup(code));
262
+
263
+ builders
264
+ .command('feed')
265
+ .description('Recent builder transactions')
266
+ .option('-l, --limit <n>', 'Number of results', '20')
267
+ .action((opts) => buildersFeed({ limit: parseInt(opts.limit) }));
268
+
269
+ // ═══════════════════════════════════════
270
+ // FACILITATOR COMMANDS
271
+ // ═══════════════════════════════════════
272
+ const facilitator = program
273
+ .command('facilitator')
274
+ .description('x402 payment facilitator');
275
+
276
+ facilitator
277
+ .command('health')
278
+ .description('Facilitator status')
279
+ .action(() => facilitatorHealth());
280
+
281
+ facilitator
282
+ .command('verify <payment>')
283
+ .description('Verify a payment off-chain')
284
+ .action((payment) => facilitatorVerify(payment));
285
+
286
+ facilitator
287
+ .command('settle <payment>')
288
+ .description('Settle payment on-chain')
289
+ .action((payment) => facilitatorSettle(payment));
290
+
291
+ // ═══════════════════════════════════════
292
+ // SCRIPT COMMANDS
293
+ // ═══════════════════════════════════════
294
+ const script = program
295
+ .command('script')
296
+ .description('Execution scripts — automated trading strategies');
297
+
298
+ script
299
+ .command('create')
300
+ .description('Create a new execution script')
301
+ .action(() => createScript());
302
+
303
+ script
304
+ .command('list')
305
+ .description('List all scripts')
306
+ .action(() => listScripts());
307
+
308
+ script
309
+ .command('run <name>')
310
+ .description('Execute a script')
311
+ .option('-p, --password <pw>', 'Wallet password (for automation)')
312
+ .option('-y, --yes', 'Skip confirmation')
313
+ .option('-v, --verbose', 'Show full error traces')
314
+ .action((name, opts) => runScript(name, opts));
315
+
316
+ script
317
+ .command('show <name>')
318
+ .description('Show script details and code')
319
+ .action((name) => showScript(name));
320
+
321
+ script
322
+ .command('edit <name>')
323
+ .description('Edit script parameters')
324
+ .action((name) => editScript(name));
325
+
326
+ script
327
+ .command('delete <name>')
328
+ .description('Delete a script')
329
+ .action((name) => deleteScript(name));
330
+
331
+ script
332
+ .command('clone <name> [newName]')
333
+ .description('Clone a script')
334
+ .action((name, newName) => cloneScript(name, newName));
335
+
336
+ script
337
+ .command('templates')
338
+ .description('List available script templates')
339
+ .action(() => listTemplates());
340
+
341
+ // ═══════════════════════════════════════
342
+ // CONFIG COMMANDS
343
+ // ═══════════════════════════════════════
344
+ const config = program
345
+ .command('config')
346
+ .description('Terminal configuration');
347
+
348
+ config
349
+ .command('show')
350
+ .description('Show current config')
351
+ .action(() => {
352
+ showMiniBanner();
353
+ showSection('CONFIGURATION');
354
+ const cfg = getAllConfig();
355
+ kvDisplay([
356
+ ['Active Wallet', cfg.activeWallet || theme.dim('(none)')],
357
+ ['Chain', cfg.chain],
358
+ ['Output', cfg.output],
359
+ ['Slippage', `${cfg.slippage}%`],
360
+ ['Gas Multiplier', `${cfg.gasMultiplier}x`],
361
+ ['Config File', configPath()],
362
+ ]);
363
+ console.log('');
364
+ showSection('RPC ENDPOINTS');
365
+ kvDisplay(Object.entries(cfg.rpcs).map(([k, v]) => [k, v]));
366
+ console.log('');
367
+ showSection('SERVICE URLS');
368
+ kvDisplay(Object.entries(cfg.services).map(([k, v]) => [k, v]));
369
+ console.log('');
370
+ });
371
+
372
+ config
373
+ .command('set <key> <value>')
374
+ .description('Set config value')
375
+ .action((key, value) => {
376
+ setConfig(key, value);
377
+ success(`${key} = ${value}`);
378
+ });
379
+
380
+ config
381
+ .command('rpc <chain> <url>')
382
+ .description('Set custom RPC endpoint')
383
+ .action((chain, url) => {
384
+ setRPC(chain, url);
385
+ success(`RPC for ${chain}: ${url}`);
386
+ });
387
+
388
+ // ═══════════════════════════════════════
389
+ // DASHBOARD (default)
390
+ // ═══════════════════════════════════════
391
+ program
392
+ .command('dashboard', { isDefault: true })
393
+ .description('Show DARKSOL Terminal dashboard')
394
+ .action(async () => {
395
+ showBanner();
396
+
397
+ const cfg = getAllConfig();
398
+ const wallet = cfg.activeWallet;
399
+
400
+ showSection('STATUS');
401
+ kvDisplay([
402
+ ['Wallet', wallet || theme.dim('Not set — run: darksol wallet create')],
403
+ ['Chain', cfg.chain],
404
+ ['Slippage', `${cfg.slippage}%`],
405
+ ]);
406
+
407
+ console.log('');
408
+ showSection('COMMANDS');
409
+ const commands = [
410
+ ['wallet', 'Create, import, manage wallets'],
411
+ ['trade', 'Swap tokens, snipe, trading'],
412
+ ['dca', 'Dollar-cost averaging orders'],
413
+ ['script', 'Execution scripts & strategies'],
414
+ ['market', 'Market intel & token data'],
415
+ ['oracle', 'On-chain random oracle'],
416
+ ['casino', 'The Clawsino — betting'],
417
+ ['cards', 'Prepaid Visa/MC cards'],
418
+ ['builders', 'ERC-8021 builder index'],
419
+ ['facilitator', 'x402 payment facilitator'],
420
+ ['config', 'Terminal configuration'],
421
+ ];
422
+
423
+ commands.forEach(([cmd, desc]) => {
424
+ console.log(` ${theme.gold(cmd.padEnd(16))} ${theme.dim(desc)}`);
425
+ });
426
+
427
+ console.log('');
428
+ console.log(theme.dim(' Run any command with --help for details'));
429
+ console.log(theme.dim(' Example: darksol trade swap --help'));
430
+ console.log('');
431
+ });
432
+
433
+ program.parse(argv);
434
+ }