@jellylegsai/aether-cli 1.8.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 +21 -0
- package/README.md +110 -0
- package/aether-cli-1.0.0.tgz +0 -0
- package/aether-cli-1.8.0.tgz +0 -0
- package/aether-hub-1.0.5.tgz +0 -0
- package/aether-hub-1.1.8.tgz +0 -0
- package/aether-hub-1.2.1.tgz +0 -0
- package/commands/account.js +280 -0
- package/commands/apy.js +499 -0
- package/commands/balance.js +241 -0
- package/commands/blockhash.js +181 -0
- package/commands/broadcast.js +387 -0
- package/commands/claim.js +490 -0
- package/commands/config.js +851 -0
- package/commands/delegations.js +582 -0
- package/commands/doctor.js +769 -0
- package/commands/emergency.js +667 -0
- package/commands/epoch.js +275 -0
- package/commands/fees.js +276 -0
- package/commands/index.js +78 -0
- package/commands/info.js +495 -0
- package/commands/init.js +816 -0
- package/commands/install.js +666 -0
- package/commands/kyc.js +272 -0
- package/commands/logs.js +315 -0
- package/commands/monitor.js +431 -0
- package/commands/multisig.js +701 -0
- package/commands/network.js +429 -0
- package/commands/nft.js +857 -0
- package/commands/ping.js +266 -0
- package/commands/price.js +253 -0
- package/commands/rewards.js +931 -0
- package/commands/sdk-test.js +477 -0
- package/commands/sdk.js +656 -0
- package/commands/slot.js +155 -0
- package/commands/snapshot.js +470 -0
- package/commands/stake-info.js +139 -0
- package/commands/stake-positions.js +205 -0
- package/commands/stake.js +516 -0
- package/commands/stats.js +396 -0
- package/commands/status.js +327 -0
- package/commands/supply.js +391 -0
- package/commands/tps.js +238 -0
- package/commands/transfer.js +495 -0
- package/commands/tx-history.js +346 -0
- package/commands/unstake.js +597 -0
- package/commands/validator-info.js +657 -0
- package/commands/validator-register.js +593 -0
- package/commands/validator-start.js +323 -0
- package/commands/validator-status.js +227 -0
- package/commands/validators.js +626 -0
- package/commands/wallet.js +1570 -0
- package/index.js +593 -0
- package/lib/errors.js +398 -0
- package/package.json +76 -0
- package/sdk/README.md +210 -0
- package/sdk/index.js +1639 -0
- package/sdk/package.json +34 -0
- package/sdk/rpc.js +254 -0
- package/sdk/test.js +85 -0
- package/test/doctor.test.js +76 -0
- package/validator-identity.json +4 -0
package/index.js
ADDED
|
@@ -0,0 +1,593 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* aether-cli - AeTHer Validator Command Line Interface
|
|
4
|
+
*
|
|
5
|
+
* Main entry point for the validator CLI tool.
|
|
6
|
+
* Provides onboarding, system checks, validator management, and KYC integration.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const { doctorCommand } = require('./commands/doctor');
|
|
10
|
+
const { validatorStart } = require('./commands/validator-start');
|
|
11
|
+
const { validatorStatus } = require('./commands/validator-status');
|
|
12
|
+
const { validatorInfo } = require('./commands/validator-info');
|
|
13
|
+
const { init } = require('./commands/init');
|
|
14
|
+
const { monitorLoop } = require('./commands/monitor');
|
|
15
|
+
const { logsCommand } = require('./commands/logs');
|
|
16
|
+
const { sdkCommand } = require('./commands/sdk');
|
|
17
|
+
const { snapshotCommand } = require('./commands/snapshot');
|
|
18
|
+
const { walletCommand } = require('./commands/wallet');
|
|
19
|
+
const { networkCommand } = require('./commands/network');
|
|
20
|
+
const { validatorsListCommand } = require('./commands/validators');
|
|
21
|
+
const { delegationsCommand } = require('./commands/delegations');
|
|
22
|
+
const { rewardsCommand } = require('./commands/rewards');
|
|
23
|
+
const { validatorRegisterCommand } = require('./commands/validator-register');
|
|
24
|
+
const { accountCommand } = require('./commands/account');
|
|
25
|
+
const { emergencyCommand } = require('./commands/emergency');
|
|
26
|
+
const { priceCommand } = require('./commands/price');
|
|
27
|
+
const { epochCommand } = require('./commands/epoch');
|
|
28
|
+
const { supplyCommand } = require('./commands/supply');
|
|
29
|
+
const { statusCommand } = require('./commands/status');
|
|
30
|
+
const { broadcastCommand } = require('./commands/broadcast');
|
|
31
|
+
const { apyCommand } = require('./commands/apy');
|
|
32
|
+
const { statsCommand } = require('./commands/stats');
|
|
33
|
+
const { txHistoryCommand } = require('./commands/tx-history');
|
|
34
|
+
const { feesCommand } = require('./commands/fees');
|
|
35
|
+
const { tpsCommand } = require('./commands/tps');
|
|
36
|
+
const { blockhashCommand } = require('./commands/blockhash');
|
|
37
|
+
const { sdkTestCommand } = require('./commands/sdk-test');
|
|
38
|
+
const { balanceCommand } = require('./commands/balance');
|
|
39
|
+
const { transferCommand } = require('./commands/transfer');
|
|
40
|
+
const { slotCommand } = require('./commands/slot');
|
|
41
|
+
const { configCommand } = require('./commands/config');
|
|
42
|
+
const { stakeCommand } = require('./commands/stake');
|
|
43
|
+
const { nftCommand } = require('./commands/nft');
|
|
44
|
+
const { installCommand } = require('./commands/install');
|
|
45
|
+
const readline = require('readline');
|
|
46
|
+
|
|
47
|
+
// CLI version
|
|
48
|
+
const VERSION = '1.8.0';
|
|
49
|
+
|
|
50
|
+
// Parse args early to support flags on commands
|
|
51
|
+
function getCommandArgs() {
|
|
52
|
+
return process.argv.slice(2);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Tier colours
|
|
56
|
+
const TIER_COLORS = {
|
|
57
|
+
FULL: '\x1b[36m', // cyan
|
|
58
|
+
LITE: '\x1b[33m', // yellow
|
|
59
|
+
OBSERVER: '\x1b[32m', // green
|
|
60
|
+
reset: '\x1b[0m',
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Display the interactive main menu
|
|
65
|
+
*/
|
|
66
|
+
async function showMenu() {
|
|
67
|
+
const rl = readline.createInterface({
|
|
68
|
+
input: process.stdin,
|
|
69
|
+
output: process.stdout,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const prompt = (q) => new Promise((res) => rl.question(q, res));
|
|
73
|
+
|
|
74
|
+
console.log(
|
|
75
|
+
TIER_COLORS.FULL + '\n ╔═══════════════════════════════════════════════╗\n' +
|
|
76
|
+
' ║ AETHER CHAIN — Validator Setup Wizard ║\n' +
|
|
77
|
+
' ╚═══════════════════════════════════════════════╝' + TIER_COLORS.reset + '\n'
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
console.log(' Welcome to AeTHer Chain. What would you like to do?\n');
|
|
81
|
+
console.log(' ' + TIER_COLORS.FULL + '1)' + TIER_COLORS.reset + ' 🩺 Doctor — Check if your system meets requirements');
|
|
82
|
+
console.log(' ' + TIER_COLORS.FULL + '2)' + TIER_COLORS.reset + ' 🚀 Start — Begin validator onboarding (recommended)');
|
|
83
|
+
console.log(' ' + TIER_COLORS.FULL + '3)' + TIER_COLORS.reset + ' 📊 Monitor — Watch live validator stats');
|
|
84
|
+
console.log(' ' + TIER_COLORS.FULL + '4)' + TIER_COLORS.reset + ' 📋 Logs — Tail and colourise validator logs');
|
|
85
|
+
console.log(' ' + TIER_COLORS.FULL + '5)' + TIER_COLORS.reset + ' 📦 SDK — Get SDK links and install tools');
|
|
86
|
+
console.log(' ' + TIER_COLORS.FULL + '6)' + TIER_COLORS.reset + ' 🌐 Network — Aether network status (slot, peers, TPS)');
|
|
87
|
+
console.log(' ' + TIER_COLORS.FULL + '7)' + TIER_COLORS.reset + ' ❓ Help — Show all commands\n');
|
|
88
|
+
console.log(' ' + TIER_COLORS.reset + ' Type a number or command name. Press Ctrl+C to exit.\n');
|
|
89
|
+
|
|
90
|
+
const VALID_CHOICES = ['1', '2', '3', '4', '5', '6', '7', 'doctor', 'init', 'monitor', 'logs', 'sdk', 'network', 'help'];
|
|
91
|
+
|
|
92
|
+
while (true) {
|
|
93
|
+
const answer = (await prompt(` > `)).trim().toLowerCase();
|
|
94
|
+
|
|
95
|
+
if (answer === '' || answer === '1' || answer === 'doctor') {
|
|
96
|
+
rl.close();
|
|
97
|
+
const { doctorCommand } = require('./commands/doctor');
|
|
98
|
+
doctorCommand({ autoFix: false, tier: 'full' });
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (answer === '2' || answer === 'init' || answer === 'start') {
|
|
103
|
+
rl.close();
|
|
104
|
+
const { init } = require('./commands/init');
|
|
105
|
+
init();
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (answer === '3' || answer === 'monitor') {
|
|
110
|
+
rl.close();
|
|
111
|
+
const { main } = require('./commands/monitor');
|
|
112
|
+
main();
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (answer === '4' || answer === 'logs') {
|
|
117
|
+
rl.close();
|
|
118
|
+
const { logsCommand } = require('./commands/logs');
|
|
119
|
+
logsCommand();
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (answer === '5' || answer === 'sdk') {
|
|
124
|
+
rl.close();
|
|
125
|
+
const { sdkCommand } = require('./commands/sdk');
|
|
126
|
+
const { snapshotCommand } = require('./commands/snapshot');
|
|
127
|
+
sdkCommand();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if (answer === '6' || answer === 'network') {
|
|
132
|
+
rl.close();
|
|
133
|
+
const { networkCommand } = require('./commands/network');
|
|
134
|
+
networkCommand();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (answer === '7' || answer === 'help') {
|
|
139
|
+
showHelp();
|
|
140
|
+
console.log(" Press Ctrl+C to exit or select an option above.\n");
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
console.log(`\n ⚠️ Unknown option: "${answer}". Type 1-6 or a command name.\n`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Available commands
|
|
149
|
+
const COMMANDS = {
|
|
150
|
+
start: {
|
|
151
|
+
description: 'Launch interactive menu (default if no args) — same as running aether-cli with no arguments',
|
|
152
|
+
handler: () => showMenu(),
|
|
153
|
+
},
|
|
154
|
+
doctor: {
|
|
155
|
+
description: 'Run system requirements checks (CPU/RAM/Disk/Network/Firewall)',
|
|
156
|
+
handler: () => {
|
|
157
|
+
const args = getCommandArgs();
|
|
158
|
+
const autoFix = args.includes('--fix') || args.includes('-f');
|
|
159
|
+
|
|
160
|
+
// Parse --tier flag
|
|
161
|
+
let tier = 'full';
|
|
162
|
+
const tierIndex = args.findIndex(arg => arg === '--tier');
|
|
163
|
+
if (tierIndex !== -1 && args[tierIndex + 1]) {
|
|
164
|
+
tier = args[tierIndex + 1].toLowerCase();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
doctorCommand({ autoFix, tier });
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
init: {
|
|
171
|
+
description: 'Start onboarding wizard (generate identity, create stake account, connect to testnet)',
|
|
172
|
+
handler: init,
|
|
173
|
+
},
|
|
174
|
+
'kyc generate': {
|
|
175
|
+
description: 'Generate pre-filled KYC link with pubkey, node ID, signature',
|
|
176
|
+
handler: () => {
|
|
177
|
+
const { kycGenerate } = require('./commands/kyc');
|
|
178
|
+
kycGenerate();
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
monitor: {
|
|
182
|
+
description: 'Real-time validator dashboard (slot, block height, peers, TPS)',
|
|
183
|
+
handler: () => {
|
|
184
|
+
// monitor command runs its own loop
|
|
185
|
+
const { main } = require('./commands/monitor');
|
|
186
|
+
main();
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
logs: {
|
|
190
|
+
description: 'Tail validator logs with colour-coded output (ERROR=red, WARN=yellow, INFO=green)',
|
|
191
|
+
handler: logsCommand,
|
|
192
|
+
},
|
|
193
|
+
sdk: {
|
|
194
|
+
description: 'Aether SDK download links and install instructions (JS, Rust, FLUX/ATH tokens)',
|
|
195
|
+
handler: sdkCommand,
|
|
196
|
+
},
|
|
197
|
+
wallet: {
|
|
198
|
+
description: 'Wallet management — create, import, list, default, connect, balance, stake, transfer',
|
|
199
|
+
handler: () => {
|
|
200
|
+
const { walletCommand } = require('./commands/wallet');
|
|
201
|
+
walletCommand();
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
stake: {
|
|
205
|
+
description: 'Stake AETH to a validator — aether stake --validator <addr> --amount <aeth> [--list-validators]',
|
|
206
|
+
handler: () => {
|
|
207
|
+
const { stakeCommand } = require('./commands/stake');
|
|
208
|
+
stakeCommand();
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
'stake-positions': {
|
|
212
|
+
description: 'Show current stake positions/delegations — aether stake-positions --address <addr> [--json]',
|
|
213
|
+
handler: () => {
|
|
214
|
+
const { stakePositionsCommand } = require('./commands/stake-positions');
|
|
215
|
+
stakePositionsCommand();
|
|
216
|
+
},
|
|
217
|
+
},
|
|
218
|
+
'stake-info': {
|
|
219
|
+
description: 'Get staking info for an address via real chain RPC — aether stake-info <address>',
|
|
220
|
+
handler: () => {
|
|
221
|
+
const { stakeInfoCommand } = require('./commands/stake-info');
|
|
222
|
+
stakeInfoCommand();
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
unstake: {
|
|
226
|
+
description: 'Unstake AETH — deactivate a stake account — aether unstake --account <stakeAcct> [--amount <aeth>]',
|
|
227
|
+
handler: () => {
|
|
228
|
+
const { unstakeCommand } = require('./commands/unstake');
|
|
229
|
+
unstakeCommand();
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
export: {
|
|
233
|
+
description: 'Export wallet data — aether export --address <addr> [--mnemonic] [--json]',
|
|
234
|
+
handler: () => {
|
|
235
|
+
const { walletCommand } = require('./commands/wallet');
|
|
236
|
+
const originalArgv = process.argv;
|
|
237
|
+
process.argv = [...originalArgv.slice(0, 2), 'wallet', 'export', ...originalArgv.slice(3)];
|
|
238
|
+
walletCommand();
|
|
239
|
+
process.argv = originalArgv;
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
transfer: {
|
|
243
|
+
description: 'Transfer AETH to another address — aether transfer --to <addr> --amount <aeth>',
|
|
244
|
+
handler: () => {
|
|
245
|
+
transferCommand();
|
|
246
|
+
},
|
|
247
|
+
},
|
|
248
|
+
tx: {
|
|
249
|
+
description: 'Transaction history — aether tx history --address <addr> [--limit 20] [--json]',
|
|
250
|
+
handler: () => {
|
|
251
|
+
txHistoryCommand();
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
'tx-history': {
|
|
255
|
+
description: 'Transaction history for an address — aether tx-history --address <addr> [--limit 20] [--json]',
|
|
256
|
+
handler: () => {
|
|
257
|
+
txHistoryCommand();
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
blockhash: {
|
|
261
|
+
description: 'Get the latest blockhash from the chain (required for signing TXs) — aether blockhash [--json] [--watch]',
|
|
262
|
+
handler: () => {
|
|
263
|
+
const { blockhashCommand } = require('./commands/blockhash');
|
|
264
|
+
blockhashCommand();
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
balance: {
|
|
268
|
+
description: 'Query account balance — aether balance [address] [--json] [--lamports] [--rpc <url>]',
|
|
269
|
+
handler: () => {
|
|
270
|
+
const { balanceCommand } = require('./commands/balance');
|
|
271
|
+
balanceCommand();
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
network: {
|
|
275
|
+
description: 'Aether network status — slot, block height, peers, TPS, epoch info',
|
|
276
|
+
handler: () => {
|
|
277
|
+
const { networkCommand } = require('./commands/network');
|
|
278
|
+
networkCommand();
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
history: {
|
|
282
|
+
description: 'Transaction history for an address — alias for tx history',
|
|
283
|
+
handler: () => {
|
|
284
|
+
txHistoryCommand();
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
validator: {
|
|
288
|
+
description: 'Validator node management',
|
|
289
|
+
handler: () => {
|
|
290
|
+
// Handle validator subcommands
|
|
291
|
+
const subcmd = process.argv[3];
|
|
292
|
+
|
|
293
|
+
if (!subcmd) {
|
|
294
|
+
console.log('Usage: aether-cli validator <command>');
|
|
295
|
+
console.log('');
|
|
296
|
+
console.log('Commands:');
|
|
297
|
+
console.log(' start Start the validator node');
|
|
298
|
+
console.log(' status Check validator status');
|
|
299
|
+
console.log(' info Get validator info');
|
|
300
|
+
console.log(' register Register validator with the network');
|
|
301
|
+
console.log('');
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
switch (subcmd) {
|
|
306
|
+
case 'start':
|
|
307
|
+
validatorStart();
|
|
308
|
+
break;
|
|
309
|
+
case 'status':
|
|
310
|
+
validatorStatus();
|
|
311
|
+
break;
|
|
312
|
+
case 'info':
|
|
313
|
+
validatorInfo();
|
|
314
|
+
break;
|
|
315
|
+
case 'register':
|
|
316
|
+
validatorRegisterCommand();
|
|
317
|
+
break;
|
|
318
|
+
default:
|
|
319
|
+
console.error(`Unknown validator command: ${subcmd}`);
|
|
320
|
+
console.error('Valid commands: start, status, info, register');
|
|
321
|
+
process.exit(1);
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
delegations: {
|
|
326
|
+
description: 'List/claim stake delegations — aether delegations list --address <addr>',
|
|
327
|
+
handler: () => {
|
|
328
|
+
delegationsCommand();
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
rewards: {
|
|
332
|
+
description: 'View staking rewards — aether rewards list | summary | pending | claim | compound',
|
|
333
|
+
handler: () => {
|
|
334
|
+
rewardsCommand();
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
snapshot: {
|
|
338
|
+
description: 'Node sync status, snapshot slot info, and network slot comparison',
|
|
339
|
+
handler: () => {
|
|
340
|
+
const { snapshotCommand } = require('./commands/snapshot');
|
|
341
|
+
snapshotCommand();
|
|
342
|
+
},
|
|
343
|
+
},
|
|
344
|
+
info: {
|
|
345
|
+
description: 'Validator info snapshot — identity, sync state, peers, stake positions',
|
|
346
|
+
handler: () => {
|
|
347
|
+
const { infoCommand } = require('./commands/info');
|
|
348
|
+
infoCommand();
|
|
349
|
+
},
|
|
350
|
+
},
|
|
351
|
+
account: {
|
|
352
|
+
description: 'Query on-chain account data — aether account --address <addr> [--json] [--data] [--rpc <url>]',
|
|
353
|
+
handler: () => {
|
|
354
|
+
const { accountCommand } = require('./commands/account');
|
|
355
|
+
accountCommand();
|
|
356
|
+
},
|
|
357
|
+
},
|
|
358
|
+
epoch: {
|
|
359
|
+
description: 'Aether epoch info — current epoch, slot, time remaining, APY estimate — aether epoch [--json] [--schedule]',
|
|
360
|
+
handler: () => {
|
|
361
|
+
const { epochCommand } = require('./commands/epoch');
|
|
362
|
+
epochCommand();
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
supply: {
|
|
366
|
+
description: 'Aether token supply — total, circulating, staked, burned — aether supply [--json] [--verbose]',
|
|
367
|
+
handler: () => {
|
|
368
|
+
const { supplyCommand } = require('./commands/supply');
|
|
369
|
+
// Pass full argv so supply.js can parse its own --help etc.
|
|
370
|
+
supplyCommand();
|
|
371
|
+
},
|
|
372
|
+
},
|
|
373
|
+
status: {
|
|
374
|
+
description: 'Full dashboard — epoch, network, supply, validator info — aether status [--json] [--compact] [--validator]',
|
|
375
|
+
handler: () => {
|
|
376
|
+
const { statusCommand } = require('./commands/status');
|
|
377
|
+
statusCommand();
|
|
378
|
+
},
|
|
379
|
+
},
|
|
380
|
+
validators: {
|
|
381
|
+
description: 'List active validators — aether validators list [--tier full|lite|observer] [--json]',
|
|
382
|
+
handler: () => {
|
|
383
|
+
validatorsListCommand();
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
'validator-info': {
|
|
387
|
+
description: 'Get detailed info for a specific validator — aether validator-info <address> [--json]',
|
|
388
|
+
handler: () => {
|
|
389
|
+
const { validatorInfoCommand } = require('./commands/validator-info');
|
|
390
|
+
validatorInfoCommand();
|
|
391
|
+
},
|
|
392
|
+
},
|
|
393
|
+
stats: {
|
|
394
|
+
description: 'Wallet stats dashboard — balance, stake positions, recent txs — aether stats --address <addr> [--compact] [--json]',
|
|
395
|
+
handler: () => {
|
|
396
|
+
statsCommand();
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
price: {
|
|
400
|
+
description: 'AETH/USD price — aether price [--pair AETH/USD] [--json] [--source coingecko]',
|
|
401
|
+
handler: () => {
|
|
402
|
+
const { priceCommand } = require('./commands/price');
|
|
403
|
+
priceCommand();
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
broadcast: {
|
|
407
|
+
description: 'Broadcast a signed transaction — aether broadcast --tx <sig> [--json] [--file <path>]',
|
|
408
|
+
handler: () => {
|
|
409
|
+
const { broadcastCommand } = require('./commands/broadcast');
|
|
410
|
+
broadcastCommand();
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
apy: {
|
|
414
|
+
description: 'Validator APY estimator — aether apy [--validator <addr>] [--address <addr>] [--json] [--epochs <n>]',
|
|
415
|
+
handler: () => {
|
|
416
|
+
const { apyCommand } = require('./commands/apy');
|
|
417
|
+
apyCommand();
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
ping: {
|
|
421
|
+
description: 'Ping RPC endpoint — measure latency, check node health — aether ping [--rpc <url>] [--count <n>] [--json]',
|
|
422
|
+
handler: () => {
|
|
423
|
+
const { pingCommand } = require('./commands/ping');
|
|
424
|
+
pingCommand();
|
|
425
|
+
},
|
|
426
|
+
},
|
|
427
|
+
emergency: {
|
|
428
|
+
description: 'Emergency response & network alerts — status, monitor, check, alert, failover, history',
|
|
429
|
+
handler: () => {
|
|
430
|
+
const { emergencyCommand } = require('./commands/emergency');
|
|
431
|
+
emergencyCommand();
|
|
432
|
+
},
|
|
433
|
+
},
|
|
434
|
+
fees: {
|
|
435
|
+
description: 'Network fee estimates — aether fees [--json] [--verbose] [--rpc <url>]',
|
|
436
|
+
handler: () => {
|
|
437
|
+
feesCommand();
|
|
438
|
+
},
|
|
439
|
+
},
|
|
440
|
+
tps: {
|
|
441
|
+
description: 'Transactions per second monitor — aether tps [--monitor] [--interval 2] [--json]',
|
|
442
|
+
handler: () => {
|
|
443
|
+
tpsCommand();
|
|
444
|
+
},
|
|
445
|
+
},
|
|
446
|
+
slot: {
|
|
447
|
+
description: 'Get current slot number — aether slot [--json] [--rpc <url>]',
|
|
448
|
+
handler: () => {
|
|
449
|
+
slotCommand();
|
|
450
|
+
},
|
|
451
|
+
},
|
|
452
|
+
claim: {
|
|
453
|
+
description: 'Claim accumulated staking rewards — aether claim --address <addr> [--json] [--dry-run]',
|
|
454
|
+
handler: () => {
|
|
455
|
+
const { claimCommand } = require('./commands/claim');
|
|
456
|
+
claimCommand();
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
register: {
|
|
460
|
+
description: 'Register validator with network — aether register --wallet <addr> --amount <aeth> [--tier full]',
|
|
461
|
+
handler: () => {
|
|
462
|
+
validatorRegisterCommand();
|
|
463
|
+
},
|
|
464
|
+
},
|
|
465
|
+
'sdk-test': {
|
|
466
|
+
description: 'Test SDK with real RPC calls — aether sdk-test [--rpc <url>] [--quick] [--json]',
|
|
467
|
+
handler: () => {
|
|
468
|
+
sdkTestCommand();
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
config: {
|
|
472
|
+
description: 'Configuration management — aether config set/get/list/validate/init',
|
|
473
|
+
handler: () => {
|
|
474
|
+
configCommand();
|
|
475
|
+
},
|
|
476
|
+
},
|
|
477
|
+
nft: {
|
|
478
|
+
description: 'NFT management — aether nft create|list|transfer|info|update — full SDK-wired suite',
|
|
479
|
+
handler: () => {
|
|
480
|
+
nftCommand();
|
|
481
|
+
},
|
|
482
|
+
},
|
|
483
|
+
install: {
|
|
484
|
+
description: 'Install or upgrade aether-cli — npm install, config init, PATH setup — aether install [--force] [--rpc <url>] [--skip-rpc-check]',
|
|
485
|
+
handler: () => {
|
|
486
|
+
installCommand();
|
|
487
|
+
},
|
|
488
|
+
},
|
|
489
|
+
'install-help': {
|
|
490
|
+
description: 'Show install command help',
|
|
491
|
+
hidden: true,
|
|
492
|
+
handler: () => {
|
|
493
|
+
process.argv = [process.argv[0], process.argv[1], 'install', '--help'];
|
|
494
|
+
installCommand();
|
|
495
|
+
},
|
|
496
|
+
},
|
|
497
|
+
help: {
|
|
498
|
+
description: 'Show this help message',
|
|
499
|
+
handler: showHelp,
|
|
500
|
+
},
|
|
501
|
+
version: {
|
|
502
|
+
description: 'Show version number',
|
|
503
|
+
handler: () => console.log(`aether-cli v${VERSION}`),
|
|
504
|
+
},
|
|
505
|
+
};
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Display help message with ASCII art
|
|
509
|
+
*/
|
|
510
|
+
function showHelp() {
|
|
511
|
+
const header = `
|
|
512
|
+
███╗ ███╗██╗███████╗███████╗██╗ ██████╗ ███╗ ██╗
|
|
513
|
+
████╗ ████║██║██╔════╝██╔════╝██║██╔═══██╗████╗ ██║
|
|
514
|
+
██╔████╔██║██║███████╗███████╗██║██║ ██║██╔██╗ ██║
|
|
515
|
+
██║╚██╔╝██║██║╚════██║╚════██║██║██║ ██║██║╚██╗██║
|
|
516
|
+
██║ ╚═╝ ██║██║███████║███████║██║╚██████╔╝██║ ╚████║
|
|
517
|
+
╚═╝ ╚═╝╚═╝╚══════╝╚══════╝╚═╝ ╚═════╝ ╚═╝ ╚═══╝
|
|
518
|
+
|
|
519
|
+
Validator CLI v${VERSION}
|
|
520
|
+
`.trim();
|
|
521
|
+
|
|
522
|
+
console.log(header);
|
|
523
|
+
console.log('\nUsage: aether-cli <command> [options]\n');
|
|
524
|
+
console.log('Commands:');
|
|
525
|
+
Object.entries(COMMANDS).forEach(([cmd, info]) => {
|
|
526
|
+
if (info.hidden) return;
|
|
527
|
+
console.log(` ${cmd.padEnd(18)} ${info.description}`);
|
|
528
|
+
});
|
|
529
|
+
console.log('\nExamples:');
|
|
530
|
+
console.log(' aether-cli doctor # Check system requirements');
|
|
531
|
+
console.log(' aether-cli init # Start onboarding wizard');
|
|
532
|
+
console.log(' aether-cli monitor # Real-time validator dashboard');
|
|
533
|
+
console.log(' aether-cli validator start # Start validator node');
|
|
534
|
+
console.log(' aether-cli validator status # Check validator status');
|
|
535
|
+
console.log(' aether-cli wallet balance # Query AETH balance');
|
|
536
|
+
console.log(' aether-cli network # Network status, peers, slot info');
|
|
537
|
+
console.log(' aether-cli network --peers # Detailed peer list');
|
|
538
|
+
console.log(' aether-cli tx history # Show transaction history');
|
|
539
|
+
console.log(' aether-cli price # AETH/USD price check');
|
|
540
|
+
console.log(' aether-cli nft create # Create NFT with metadata');
|
|
541
|
+
console.log(' aether-cli nft list # List NFTs owned by wallet');
|
|
542
|
+
console.log(' aether-cli --version # Show version');
|
|
543
|
+
console.log('\nDocumentation: https://github.com/jelly-legs-ai/Jelly-legs-unsteady-workshop');
|
|
544
|
+
console.log('Spec: docs/MINING_VALIDATOR_TOOLS.md\n');
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* Parse command line arguments
|
|
549
|
+
*/
|
|
550
|
+
function parseArgs() {
|
|
551
|
+
const args = process.argv.slice(2);
|
|
552
|
+
|
|
553
|
+
// Handle version flag
|
|
554
|
+
if (args.includes('--version') || args.includes('-v') || args.includes('-V')) {
|
|
555
|
+
return 'version';
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// No args → interactive menu
|
|
559
|
+
if (args.length === 0) {
|
|
560
|
+
return 'start';
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// Handle multi-word commands (e.g., "validator start", "kyc generate")
|
|
564
|
+
if (args.length >= 2) {
|
|
565
|
+
const multiCmd = `${args[0]} ${args[1]}`;
|
|
566
|
+
if (COMMANDS[multiCmd]) {
|
|
567
|
+
return multiCmd;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Handle single word commands
|
|
572
|
+
return args[0] || 'help';
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Main CLI entry point
|
|
577
|
+
*/
|
|
578
|
+
function main() {
|
|
579
|
+
const command = parseArgs();
|
|
580
|
+
|
|
581
|
+
if (COMMANDS[command]) {
|
|
582
|
+
COMMANDS[command].handler();
|
|
583
|
+
} else {
|
|
584
|
+
console.error(`❌ Unknown command: ${command}`);
|
|
585
|
+
console.error('Run "aether-cli help" for usage.\n');
|
|
586
|
+
process.exit(1);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// Run CLI only if executed directly
|
|
591
|
+
if (require.main === module) {
|
|
592
|
+
main();
|
|
593
|
+
}
|