aether-hub 1.2.8 → 1.3.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.
@@ -1,205 +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 };
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 };