@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.
Files changed (62) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +110 -0
  3. package/aether-cli-1.0.0.tgz +0 -0
  4. package/aether-cli-1.8.0.tgz +0 -0
  5. package/aether-hub-1.0.5.tgz +0 -0
  6. package/aether-hub-1.1.8.tgz +0 -0
  7. package/aether-hub-1.2.1.tgz +0 -0
  8. package/commands/account.js +280 -0
  9. package/commands/apy.js +499 -0
  10. package/commands/balance.js +241 -0
  11. package/commands/blockhash.js +181 -0
  12. package/commands/broadcast.js +387 -0
  13. package/commands/claim.js +490 -0
  14. package/commands/config.js +851 -0
  15. package/commands/delegations.js +582 -0
  16. package/commands/doctor.js +769 -0
  17. package/commands/emergency.js +667 -0
  18. package/commands/epoch.js +275 -0
  19. package/commands/fees.js +276 -0
  20. package/commands/index.js +78 -0
  21. package/commands/info.js +495 -0
  22. package/commands/init.js +816 -0
  23. package/commands/install.js +666 -0
  24. package/commands/kyc.js +272 -0
  25. package/commands/logs.js +315 -0
  26. package/commands/monitor.js +431 -0
  27. package/commands/multisig.js +701 -0
  28. package/commands/network.js +429 -0
  29. package/commands/nft.js +857 -0
  30. package/commands/ping.js +266 -0
  31. package/commands/price.js +253 -0
  32. package/commands/rewards.js +931 -0
  33. package/commands/sdk-test.js +477 -0
  34. package/commands/sdk.js +656 -0
  35. package/commands/slot.js +155 -0
  36. package/commands/snapshot.js +470 -0
  37. package/commands/stake-info.js +139 -0
  38. package/commands/stake-positions.js +205 -0
  39. package/commands/stake.js +516 -0
  40. package/commands/stats.js +396 -0
  41. package/commands/status.js +327 -0
  42. package/commands/supply.js +391 -0
  43. package/commands/tps.js +238 -0
  44. package/commands/transfer.js +495 -0
  45. package/commands/tx-history.js +346 -0
  46. package/commands/unstake.js +597 -0
  47. package/commands/validator-info.js +657 -0
  48. package/commands/validator-register.js +593 -0
  49. package/commands/validator-start.js +323 -0
  50. package/commands/validator-status.js +227 -0
  51. package/commands/validators.js +626 -0
  52. package/commands/wallet.js +1570 -0
  53. package/index.js +593 -0
  54. package/lib/errors.js +398 -0
  55. package/package.json +76 -0
  56. package/sdk/README.md +210 -0
  57. package/sdk/index.js +1639 -0
  58. package/sdk/package.json +34 -0
  59. package/sdk/rpc.js +254 -0
  60. package/sdk/test.js +85 -0
  61. package/test/doctor.test.js +76 -0
  62. package/validator-identity.json +4 -0
@@ -0,0 +1,139 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * aether-cli - Stake Info Command
4
+ * Get staking information for an address using real chain RPC calls.
5
+ * All calls go through @jellylegsai/aether-sdk → AetherClient → real HTTP RPC.
6
+ *
7
+ * Usage:
8
+ * aether stake-info <address> Show stake info for address
9
+ * aether stake-info <address> --json JSON output
10
+ * aether stake-info <address> --rpc <url> Custom RPC endpoint
11
+ *
12
+ * SDK wired to: GET /v1/slot, GET /v1/account/<addr>, GET /v1/blockheight
13
+ */
14
+
15
+ const path = require('path');
16
+ const sdkPath = path.join(__dirname, '..', 'sdk', 'index.js');
17
+ const { AetherClient } = require(sdkPath);
18
+
19
+ // ANSI colours
20
+ const C = {
21
+ reset: '\x1b[0m',
22
+ bright: '\x1b[1m',
23
+ dim: '\x1b[2m',
24
+ red: '\x1b[31m',
25
+ green: '\x1b[32m',
26
+ yellow: '\x1b[33m',
27
+ cyan: '\x1b[36m',
28
+ magenta: '\x1b[35m',
29
+ };
30
+
31
+ // ---------------------------------------------------------------------------
32
+ // Argument parsing
33
+ // ---------------------------------------------------------------------------
34
+
35
+ function parseArgs() {
36
+ const args = process.argv.slice(2);
37
+ const result = { address: null, json: false, rpc: null };
38
+
39
+ for (let i = 0; i < args.length; i++) {
40
+ if (!args[i].startsWith('-') && !result.address) {
41
+ result.address = args[i];
42
+ } else if (args[i] === '--json' || args[i] === '-j') {
43
+ result.json = true;
44
+ } else if ((args[i] === '--rpc' || args[i] === '-r') && args[i + 1]) {
45
+ result.rpc = args[++i];
46
+ } else if (args[i] === '--help' || args[i] === '-h') {
47
+ result.help = true;
48
+ }
49
+ }
50
+ return result;
51
+ }
52
+
53
+ function getDefaultRpc() {
54
+ return process.env.AETHER_RPC || 'http://127.0.0.1:8899';
55
+ }
56
+
57
+ // ---------------------------------------------------------------------------
58
+ // Main
59
+ // ---------------------------------------------------------------------------
60
+
61
+ async function stakeInfoCommand() {
62
+ const opts = parseArgs();
63
+
64
+ if (opts.help || !opts.address) {
65
+ console.log(`
66
+ ${C.bright}${C.cyan}aether-cli stake-info${C.reset} — Get stake/account info for an address
67
+
68
+ ${C.bright}USAGE${C.reset}
69
+ aether stake-info <address> [--json] [--rpc <url>]
70
+
71
+ ${C.bright}OPTIONS${C.reset}
72
+ --json, -j Output raw JSON
73
+ --rpc <url> RPC endpoint (default: AETHER_RPC or localhost:8899)
74
+ --help, -h Show this help
75
+
76
+ ${C.bright}SDK METHODS USED${C.reset}
77
+ client.getSlot() → GET /v1/slot
78
+ client.getAccountInfo(addr) → GET /v1/account/<addr>
79
+ client.getBlockHeight() → GET /v1/blockheight
80
+
81
+ ${C.bright}EXAMPLE${C.reset}
82
+ aether stake-info ATH3abc...def
83
+ `);
84
+ return;
85
+ }
86
+
87
+ const rpcUrl = opts.rpc || getDefaultRpc();
88
+ const client = new AetherClient({ rpcUrl });
89
+
90
+ try {
91
+ // Real chain RPC calls — all parallel for speed
92
+ const [slot, accountInfo, blockHeight] = await Promise.all([
93
+ client.getSlot().catch(() => null),
94
+ client.getAccountInfo(opts.address).catch(() => null),
95
+ client.getBlockHeight().catch(() => null),
96
+ ]);
97
+
98
+ const balance = accountInfo?.lamports != null
99
+ ? (accountInfo.lamports / 1e9).toFixed(4) + ' AETH'
100
+ : 'unavailable';
101
+ const owner = accountInfo?.owner || 'unknown';
102
+ const executable = accountInfo?.executable ? 'yes' : 'no';
103
+
104
+ if (opts.json) {
105
+ console.log(JSON.stringify({
106
+ address: opts.address,
107
+ slot: slot ?? null,
108
+ block_height: blockHeight ?? null,
109
+ account: {
110
+ lamports: accountInfo?.lamports ?? null,
111
+ balance_aeth: accountInfo?.lamports != null ? (accountInfo.lamports / 1e9).toFixed(4) : null,
112
+ owner: accountInfo?.owner ?? null,
113
+ executable: accountInfo?.executable ?? false,
114
+ rent_epoch: accountInfo?.rent_epoch ?? null,
115
+ },
116
+ rpc: rpcUrl,
117
+ timestamp: new Date().toISOString(),
118
+ }, null, 2));
119
+ return;
120
+ }
121
+
122
+ console.log(`\n${C.bright}${C.cyan}── Aether Stake Info ─────────────────────────────────${C.reset}\n`);
123
+ console.log(` ${C.dim}Address:${C.reset} ${opts.address}`);
124
+ console.log(` ${C.dim}Balance:${C.reset} ${C.green}${balance}${C.reset}`);
125
+ console.log(` ${C.dim}Owner:${C.reset} ${owner}`);
126
+ console.log(` ${C.dim}Executable:${C.reset} ${executable}`);
127
+ console.log(` ${C.dim}Slot:${C.reset} ${slot ?? 'unavailable'}`);
128
+ console.log(` ${C.dim}Block Height:${C.reset} ${blockHeight ?? 'unavailable'}`);
129
+ console.log(` ${C.dim}RPC:${C.reset} ${rpcUrl}\n`);
130
+ console.log(` ${C.green}? Real chain RPC calls completed${C.reset}\n`);
131
+ } catch (error) {
132
+ console.log(` ${C.red}? Error: ${error.message}${C.reset}\n`);
133
+ process.exit(1);
134
+ }
135
+ }
136
+
137
+ stakeInfoCommand();
138
+
139
+ module.exports = { stakeInfoCommand };
@@ -0,0 +1,205 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * aether-cli stake-positions
4
+ *
5
+ * Query and display current stake positions/delegations for a wallet.
6
+ * Shows validator, amount, status, and accumulated rewards.
7
+ *
8
+ * Usage:
9
+ * aether stake-positions --address <addr> [--json]
10
+ * aether wallet stake-positions --address <addr> [--json]
11
+ *
12
+ * Examples:
13
+ * aether stake-positions --address ATHxxx
14
+ * aether wallet stake-positions --address ATHxxx --json
15
+ *
16
+ * SDK wired to: GET /v1/slot, GET /v1/stake/<address>, GET /v1/account/<addr>
17
+ */
18
+
19
+ const path = require('path');
20
+
21
+ // Import SDK — all network calls go through @jellylegsai/aether-sdk
22
+ const sdkPath = path.join(__dirname, '..', 'sdk', 'index.js');
23
+ const aether = require(sdkPath);
24
+
25
+ // ANSI colours
26
+ const C = {
27
+ reset: '\x1b[0m',
28
+ bright: '\x1b[1m',
29
+ dim: '\x1b[2m',
30
+ red: '\x1b[31m',
31
+ green: '\x1b[32m',
32
+ yellow: '\x1b[33m',
33
+ cyan: '\x1b[36m',
34
+ magenta: '\x1b[35m',
35
+ };
36
+
37
+ const CLI_VERSION = '1.0.1';
38
+
39
+ // ---------------------------------------------------------------------------
40
+ // Config
41
+ // ---------------------------------------------------------------------------
42
+
43
+ function getDefaultRpc() {
44
+ return process.env.AETHER_RPC || aether.DEFAULT_RPC_URL || 'http://127.0.0.1:8899';
45
+ }
46
+
47
+ function createClient(rpcUrl) {
48
+ return new aether.AetherClient({ rpcUrl });
49
+ }
50
+
51
+ // ---------------------------------------------------------------------------
52
+ // Argument parsing
53
+ // ---------------------------------------------------------------------------
54
+
55
+ function parseArgs() {
56
+ const args = process.argv.slice(2);
57
+ const result = { address: null, json: false };
58
+
59
+ for (let i = 0; i < args.length; i++) {
60
+ if ((args[i] === '--address' || args[i] === '-a') && args[i + 1]) {
61
+ result.address = args[++i];
62
+ } else if (args[i] === '--json' || args[i] === '--json-output') {
63
+ result.json = true;
64
+ } else if (args[i] === '--rpc' && args[i + 1]) {
65
+ result.rpc = args[++i];
66
+ } else if (args[i] === '--help' || args[i] === '-h') {
67
+ result.help = true;
68
+ }
69
+ }
70
+
71
+ return result;
72
+ }
73
+
74
+ // ---------------------------------------------------------------------------
75
+ // Balance formatting
76
+ // ---------------------------------------------------------------------------
77
+
78
+ function formatAether(lamports) {
79
+ const aeth = (lamports || 0) / 1e9;
80
+ return aeth.toLocaleString(undefined, { minimumFractionDigits: 4, maximumFractionDigits: 4 }) + ' AETH';
81
+ }
82
+
83
+ // ---------------------------------------------------------------------------
84
+ // Main
85
+ // ---------------------------------------------------------------------------
86
+
87
+ async function stakePositionsCommand() {
88
+ const opts = parseArgs();
89
+
90
+ if (opts.help) {
91
+ console.log(`
92
+ ${C.bright}${C.cyan}stake-positions${C.reset} — Query active stake delegations for a wallet
93
+
94
+ ${C.bright}USAGE${C.reset}
95
+ aether stake-positions --address <addr> [--json] [--rpc <url>]
96
+
97
+ ${C.bright}OPTIONS${C.reset}
98
+ --address <addr> Wallet address (ATH...)
99
+ --json Output raw JSON
100
+ --rpc <url> RPC endpoint (default: AETHER_RPC or localhost:8899)
101
+ --help Show this help
102
+
103
+ ${C.bright}SDK METHODS USED${C.reset}
104
+ client.getSlot() → GET /v1/slot
105
+ client.getStakePositions() → GET /v1/stake/<address>
106
+ client.getAccountInfo() → GET /v1/account/<addr>
107
+
108
+ ${C.bright}EXAMPLES${C.reset}
109
+ aether stake-positions --address ATH3abc...
110
+ aether stake-positions --address ATH3abc... --json
111
+ `);
112
+ return;
113
+ }
114
+
115
+ if (!opts.address) {
116
+ console.log(` ${C.red}✗ Missing --address${C.reset}\n`);
117
+ console.log(` Usage: aether stake-positions --address <addr> [--json]\n`);
118
+ return;
119
+ }
120
+
121
+ const rpcUrl = opts.rpc || getDefaultRpc();
122
+ const client = createClient(rpcUrl);
123
+ const address = opts.address;
124
+ const rawAddr = address.startsWith('ATH') ? address.slice(3) : address;
125
+
126
+ if (!opts.json) {
127
+ console.log(`\n${C.bright}${C.cyan}── Stake Positions ──────────────────────────────────────${C.reset}\n`);
128
+ console.log(` ${C.dim}Wallet:${C.reset} ${address}`);
129
+ console.log(` ${C.dim}RPC: ${C.reset} ${rpcUrl}\n`);
130
+ }
131
+
132
+ try {
133
+ // Verify chain connectivity via SDK (real RPC call)
134
+ const slot = await client.getSlot().catch(() => null);
135
+
136
+ // Fetch stake positions via SDK (real RPC call to GET /v1/stake/<address>)
137
+ const stakeAccounts = await client.getStakePositions(rawAddr);
138
+
139
+ if (opts.json) {
140
+ const totalLamports = stakeAccounts.reduce((sum, acc) => sum + (acc.stake_lamports || acc.lamports || 0), 0);
141
+ console.log(JSON.stringify({
142
+ wallet_address: address,
143
+ slot,
144
+ stake_accounts: stakeAccounts.map(acc => ({
145
+ stake_account: acc.pubkey || acc.publicKey || acc.account || 'unknown',
146
+ validator: acc.validator || acc.delegate || acc.validator_address || 'unknown',
147
+ stake_lamports: acc.stake_lamports || acc.lamports || 0,
148
+ stake_aeth: ((acc.stake_lamports || acc.lamports || 0) / 1e9).toFixed(4),
149
+ status: acc.status || acc.state || 'active',
150
+ updated_epoch: acc.epoch || acc.last_update_epoch || null,
151
+ })),
152
+ total_staked_lamports: totalLamports,
153
+ total_staked_aeth: (totalLamports / 1e9).toFixed(4),
154
+ count: stakeAccounts.length,
155
+ rpc: rpcUrl,
156
+ cli_version: CLI_VERSION,
157
+ fetched_at: new Date().toISOString(),
158
+ }, null, 2));
159
+ return;
160
+ }
161
+
162
+ if (!stakeAccounts || stakeAccounts.length === 0) {
163
+ console.log(` ${C.yellow}? No active stake positions found.${C.reset}`);
164
+ console.log(` ${C.dim} Stake AETH with: ${C.cyan}aether stake --validator <addr> --amount <aeth>${C.reset}\n`);
165
+ return;
166
+ }
167
+
168
+ let totalStaked = 0;
169
+ console.log(` ${C.bright}Stake Positions (${stakeAccounts.length})${C.reset}\n`);
170
+
171
+ for (const acc of stakeAccounts) {
172
+ const stakeAcct = acc.pubkey || acc.publicKey || acc.account || 'unknown';
173
+ const validator = acc.validator || acc.delegate || acc.validator_address || 'unknown';
174
+ const lamports = acc.stake_lamports || acc.lamports || 0;
175
+ const status = (acc.status || acc.state || 'active').toLowerCase();
176
+ const epoch = acc.epoch || acc.last_update_epoch || null;
177
+
178
+ totalStaked += lamports;
179
+
180
+ const statusColor = status === 'active' ? C.green : status === 'deactivating' ? C.yellow : C.dim;
181
+ const shortAcct = stakeAcct.length > 20 ? stakeAcct.slice(0, 8) + '.' + stakeAcct.slice(-8) : stakeAcct;
182
+ const shortVal = validator.length > 20 ? validator.slice(0, 8) + '.' + validator.slice(-8) : validator;
183
+ const aeth = (lamports / 1e9).toFixed(4);
184
+
185
+ console.log(` ${C.dim}┌─${C.bright}${statusColor} ${status.toUpperCase()}${C.reset}`);
186
+ console.log(` │ ${C.dim}Stake acct:${C.reset} ${shortAcct}`);
187
+ console.log(` │ ${C.dim}Validator:${C.reset} ${shortVal}`);
188
+ console.log(` │ ${C.dim}Staked:${C.reset} ${C.bright}${aeth} AETH${C.reset} (${lamports.toLocaleString()} lamports)`);
189
+ if (epoch) console.log(` │ ${C.dim}Epoch:${C.reset} ${C.bright}#${epoch}${C.reset}`);
190
+ console.log(` ${C.dim}└${C.reset}\n`);
191
+ }
192
+
193
+ console.log(` ${C.dim}────────────────────────────────────────${C.reset}`);
194
+ console.log(` ${C.bright}Total Staked:${C.reset} ${C.green}${formatAether(totalStaked)}${C.reset}\n`);
195
+
196
+ } catch (err) {
197
+ console.log(` ${C.red}? Failed to fetch stake positions:${C.reset} ${err.message}\n`);
198
+ console.log(` ${C.dim} Set custom RPC: AETHER_RPC=https://your-rpc-url${C.reset}\n`);
199
+ process.exit(1);
200
+ }
201
+ }
202
+
203
+ stakePositionsCommand();
204
+
205
+ module.exports = { stakePositionsCommand };