aether-hub 1.2.6 → 1.2.7
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/commands/account.js +10 -34
- package/commands/balance.js +276 -0
- package/commands/blockhash.js +181 -0
- package/commands/broadcast.js +323 -323
- package/commands/claim.js +292 -0
- package/commands/emergency.js +657 -657
- package/commands/epoch.js +12 -94
- package/commands/fees.js +276 -0
- package/commands/info.js +38 -79
- package/commands/network.js +34 -108
- package/commands/ping.js +11 -65
- package/commands/price.js +253 -253
- package/commands/sdk-test.js +477 -0
- package/commands/stake-info.js +139 -0
- package/commands/status.js +113 -157
- package/commands/supply.js +34 -82
- package/commands/tps.js +238 -0
- package/commands/transfer.js +495 -0
- package/commands/tx-history.js +462 -508
- package/commands/validator-info.js +10 -4
- package/commands/validator-start.js +1 -1
- package/commands/validator-status.js +32 -73
- package/commands/validators.js +36 -75
- package/commands/wallet.js +5 -29
- package/index.js +54 -6
- package/package.json +1 -3
|
@@ -634,7 +634,13 @@ async function main() {
|
|
|
634
634
|
console.log();
|
|
635
635
|
}
|
|
636
636
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
637
|
+
// Export for module use
|
|
638
|
+
module.exports = { validatorInfo: main };
|
|
639
|
+
|
|
640
|
+
// Only run if called directly (not when required as module)
|
|
641
|
+
if (require.main === module) {
|
|
642
|
+
main().catch(err => {
|
|
643
|
+
console.error(`\n${C.red}✗ Validator info failed:${C.reset} ${err.message}\n`);
|
|
644
|
+
process.exit(1);
|
|
645
|
+
});
|
|
646
|
+
}
|
|
@@ -254,7 +254,7 @@ function startValidatorProcess({ type, path: binaryPath, inPath }, options) {
|
|
|
254
254
|
if (options.testnet) {
|
|
255
255
|
validatorArgs.push('--testnet');
|
|
256
256
|
}
|
|
257
|
-
validatorArgs.push('--tier', options.tier);
|
|
257
|
+
validatorArgs.push('--tier', options.tier.toLowerCase());
|
|
258
258
|
validatorArgs.push('--rpc-addr', options.rpcAddr);
|
|
259
259
|
validatorArgs.push('--p2p-addr', options.p2pAddr);
|
|
260
260
|
if (options.identity) {
|
|
@@ -3,9 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Queries the validator's RPC endpoint and displays status information.
|
|
5
5
|
* Shows slot height, peer count, block production, and epoch info.
|
|
6
|
+
*
|
|
7
|
+
* Uses @jellylegsai/aether-sdk for real blockchain RPC calls.
|
|
6
8
|
*/
|
|
7
9
|
|
|
8
|
-
const
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
// Import SDK for real blockchain RPC calls
|
|
13
|
+
const sdkPath = path.join(__dirname, '..', 'sdk', 'index.js');
|
|
14
|
+
const aether = require(sdkPath);
|
|
9
15
|
|
|
10
16
|
// ANSI colors
|
|
11
17
|
const colors = {
|
|
@@ -19,54 +25,10 @@ const colors = {
|
|
|
19
25
|
};
|
|
20
26
|
|
|
21
27
|
/**
|
|
22
|
-
*
|
|
28
|
+
* Create SDK client
|
|
23
29
|
*/
|
|
24
|
-
function
|
|
25
|
-
return new
|
|
26
|
-
const urlObj = new URL(url);
|
|
27
|
-
|
|
28
|
-
const postData = JSON.stringify({
|
|
29
|
-
jsonrpc: '2.0',
|
|
30
|
-
id: 1,
|
|
31
|
-
method,
|
|
32
|
-
params,
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
const options = {
|
|
36
|
-
hostname: urlObj.hostname,
|
|
37
|
-
port: urlObj.port || 8899,
|
|
38
|
-
path: '/',
|
|
39
|
-
method: 'POST',
|
|
40
|
-
headers: {
|
|
41
|
-
'Content-Type': 'application/json',
|
|
42
|
-
'Content-Length': Buffer.byteLength(postData),
|
|
43
|
-
},
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const req = http.request(options, (res) => {
|
|
47
|
-
let data = '';
|
|
48
|
-
res.on('data', (chunk) => data += chunk);
|
|
49
|
-
res.on('end', () => {
|
|
50
|
-
try {
|
|
51
|
-
const json = JSON.parse(data);
|
|
52
|
-
if (json.error) {
|
|
53
|
-
reject(new Error(json.error.message || JSON.stringify(json.error)));
|
|
54
|
-
} else {
|
|
55
|
-
resolve(json.result);
|
|
56
|
-
}
|
|
57
|
-
} catch (e) {
|
|
58
|
-
reject(new Error(`Invalid JSON response: ${data}`));
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
req.on('error', (e) => {
|
|
64
|
-
reject(new Error(`Connection failed: ${e.message}`));
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
req.write(postData);
|
|
68
|
-
req.end();
|
|
69
|
-
});
|
|
30
|
+
function createClient(rpcUrl) {
|
|
31
|
+
return new aether.AetherClient({ rpcUrl });
|
|
70
32
|
}
|
|
71
33
|
|
|
72
34
|
/**
|
|
@@ -181,24 +143,25 @@ async function validatorStatus() {
|
|
|
181
143
|
let epochInfo = {};
|
|
182
144
|
let blockProduction = {};
|
|
183
145
|
|
|
146
|
+
const client = createClient(options.rpcUrl);
|
|
147
|
+
|
|
184
148
|
try {
|
|
185
|
-
// Make parallel RPC calls
|
|
186
|
-
const [
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
options.details ? rpcCall(options.rpcUrl, 'getBlockProduction').catch(e => ({})) : Promise.resolve({}),
|
|
149
|
+
// Make parallel RPC calls using SDK
|
|
150
|
+
const [slotResult, blockHeightResult, epochInfoResult, peersResult] = await Promise.all([
|
|
151
|
+
client.getSlot().catch(e => ({ error: e.message })),
|
|
152
|
+
client.getBlockHeight().catch(e => ({ error: e.message })),
|
|
153
|
+
client.getEpochInfo().catch(e => ({})),
|
|
154
|
+
client.getClusterPeers().catch(e => ([])),
|
|
192
155
|
]);
|
|
193
156
|
|
|
194
|
-
if (typeof
|
|
157
|
+
if (typeof slotResult === 'object' && slotResult.error) {
|
|
195
158
|
if (options.json) {
|
|
196
|
-
console.log(JSON.stringify({ error:
|
|
159
|
+
console.log(JSON.stringify({ error: slotResult.error }, null, 2));
|
|
197
160
|
process.exit(1);
|
|
198
161
|
}
|
|
199
162
|
console.log();
|
|
200
163
|
console.log(` ${colors.red}❌ Cannot connect to validator${colors.reset}`);
|
|
201
|
-
console.log(` ${colors.yellow}${
|
|
164
|
+
console.log(` ${colors.yellow}${slotResult.error}${colors.reset}`);
|
|
202
165
|
console.log();
|
|
203
166
|
console.log(` ${colors.bright}Start the validator first:${colors.reset}`);
|
|
204
167
|
console.log(` ${colors.cyan}aether-cli validator start${colors.reset}`);
|
|
@@ -206,26 +169,22 @@ async function validatorStatus() {
|
|
|
206
169
|
process.exit(1);
|
|
207
170
|
}
|
|
208
171
|
|
|
209
|
-
status.slot = typeof
|
|
210
|
-
status.blockHeight = typeof
|
|
211
|
-
status.transactionCount =
|
|
172
|
+
status.slot = typeof slotResult === 'number' ? slotResult : (slotResult.slot || 0);
|
|
173
|
+
status.blockHeight = typeof blockHeightResult === 'number' ? blockHeightResult : status.slot;
|
|
174
|
+
status.transactionCount = 0; // Transaction count not available via SDK
|
|
175
|
+
status.peerCount = Array.isArray(peersResult) ? peersResult.length : 0;
|
|
212
176
|
|
|
213
177
|
if (epochInfoResult && typeof epochInfoResult === 'object') {
|
|
214
178
|
epochInfo = epochInfoResult;
|
|
215
179
|
status.epoch = epochInfo.epoch || 0;
|
|
216
|
-
epochInfo.slotIndex = epochInfo.slotIndex || 0;
|
|
217
|
-
epochInfo.slotsInEpoch = epochInfo.slotsInEpoch || 432000;
|
|
180
|
+
epochInfo.slotIndex = epochInfo.slotIndex || epochInfo.slot_index || 0;
|
|
181
|
+
epochInfo.slotsInEpoch = epochInfo.slotsInEpoch || epochInfo.slots_in_epoch || 432000;
|
|
218
182
|
}
|
|
219
183
|
|
|
220
|
-
if (
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
// Get peer count
|
|
225
|
-
try {
|
|
226
|
-
status.peerCount = await rpcCall(options.rpcUrl, 'getPeerCount') || 0;
|
|
227
|
-
} catch (e) {
|
|
228
|
-
status.peerCount = 0;
|
|
184
|
+
if (options.details) {
|
|
185
|
+
try {
|
|
186
|
+
blockProduction = await client.getSlotProduction();
|
|
187
|
+
} catch { /* Block production not available */ }
|
|
229
188
|
}
|
|
230
189
|
|
|
231
190
|
if (options.json) {
|
|
@@ -260,7 +219,7 @@ async function validatorStatus() {
|
|
|
260
219
|
}
|
|
261
220
|
|
|
262
221
|
// Export for use as module
|
|
263
|
-
module.exports = { validatorStatus
|
|
222
|
+
module.exports = { validatorStatus };
|
|
264
223
|
|
|
265
224
|
// Run if called directly
|
|
266
225
|
if (require.main === module) {
|
package/commands/validators.js
CHANGED
|
@@ -13,10 +13,15 @@
|
|
|
13
13
|
* aether validators list --sort stake Sort by stake (default: score)
|
|
14
14
|
*
|
|
15
15
|
* Requires AETHER_RPC env var (default: http://127.0.0.1:8899)
|
|
16
|
+
*
|
|
17
|
+
* SDK wired to: GET /v1/validators, GET /v1/epoch, GET /v1/supply
|
|
16
18
|
*/
|
|
17
19
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
+
const path = require('path');
|
|
21
|
+
|
|
22
|
+
// Import SDK for real blockchain RPC calls
|
|
23
|
+
const sdkPath = path.join(__dirname, '..', 'sdk', 'index.js');
|
|
24
|
+
const aether = require(sdkPath);
|
|
20
25
|
|
|
21
26
|
// ANSI colours
|
|
22
27
|
const C = {
|
|
@@ -31,56 +36,12 @@ const C = {
|
|
|
31
36
|
magenta: '\x1b[35m',
|
|
32
37
|
};
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
// ---------------------------------------------------------------------------
|
|
37
|
-
// HTTP helpers
|
|
38
|
-
// ---------------------------------------------------------------------------
|
|
39
|
-
|
|
40
|
-
function httpRequest(rpcUrl, path) {
|
|
41
|
-
return new Promise((resolve, reject) => {
|
|
42
|
-
const url = new URL(path, rpcUrl);
|
|
43
|
-
const lib = url.protocol === 'https:' ? https : http;
|
|
44
|
-
const req = lib.request({
|
|
45
|
-
hostname: url.hostname,
|
|
46
|
-
port: url.port || (url.protocol === 'https:' ? 443 : 80),
|
|
47
|
-
path: url.pathname + url.search,
|
|
48
|
-
method: 'GET',
|
|
49
|
-
timeout: 8000,
|
|
50
|
-
headers: { 'Content-Type': 'application/json' },
|
|
51
|
-
}, (res) => {
|
|
52
|
-
let data = '';
|
|
53
|
-
res.on('data', (chunk) => data += chunk);
|
|
54
|
-
res.on('end', () => { try { resolve(JSON.parse(data)); } catch { resolve({ raw: data }); } });
|
|
55
|
-
});
|
|
56
|
-
req.on('error', reject);
|
|
57
|
-
req.on('timeout', () => { req.destroy(); reject(new Error('Request timeout')); });
|
|
58
|
-
req.end();
|
|
59
|
-
});
|
|
39
|
+
function getDefaultRpc() {
|
|
40
|
+
return process.env.AETHER_RPC || aether.DEFAULT_RPC_URL || 'http://127.0.0.1:8899';
|
|
60
41
|
}
|
|
61
42
|
|
|
62
|
-
function
|
|
63
|
-
return new
|
|
64
|
-
const url = new URL(path, rpcUrl);
|
|
65
|
-
const lib = url.protocol === 'https:' ? https : http;
|
|
66
|
-
const bodyStr = JSON.stringify(body);
|
|
67
|
-
const req = lib.request({
|
|
68
|
-
hostname: url.hostname,
|
|
69
|
-
port: url.port || (url.protocol === 'https:' ? 443 : 80),
|
|
70
|
-
path: url.pathname + url.search,
|
|
71
|
-
method: 'POST',
|
|
72
|
-
timeout: 8000,
|
|
73
|
-
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(bodyStr) },
|
|
74
|
-
}, (res) => {
|
|
75
|
-
let data = '';
|
|
76
|
-
res.on('data', (chunk) => data += chunk);
|
|
77
|
-
res.on('end', () => { try { resolve(JSON.parse(data)); } catch { resolve(data); } });
|
|
78
|
-
});
|
|
79
|
-
req.on('error', reject);
|
|
80
|
-
req.on('timeout', () => { req.destroy(); reject(new Error('Request timeout')); });
|
|
81
|
-
req.write(bodyStr);
|
|
82
|
-
req.end();
|
|
83
|
-
});
|
|
43
|
+
function createClient(rpcUrl) {
|
|
44
|
+
return new aether.AetherClient({ rpcUrl });
|
|
84
45
|
}
|
|
85
46
|
|
|
86
47
|
// ---------------------------------------------------------------------------
|
|
@@ -90,7 +51,7 @@ function httpPost(rpcUrl, path, body) {
|
|
|
90
51
|
function parseArgs() {
|
|
91
52
|
const args = process.argv.slice(3); // [node, index.js, validators, list, ...]
|
|
92
53
|
const opts = {
|
|
93
|
-
rpc:
|
|
54
|
+
rpc: getDefaultRpc(),
|
|
94
55
|
subcmd: 'list',
|
|
95
56
|
tier: null,
|
|
96
57
|
asJson: false,
|
|
@@ -137,6 +98,7 @@ function parseArgs() {
|
|
|
137
98
|
}
|
|
138
99
|
|
|
139
100
|
function showHelp() {
|
|
101
|
+
const defaultRpc = getDefaultRpc();
|
|
140
102
|
console.log(`
|
|
141
103
|
${C.bright}${C.cyan}aether-cli validators${C.reset} - List and inspect Aether validators
|
|
142
104
|
|
|
@@ -148,17 +110,22 @@ ${C.bright}Options (list):${C.reset}
|
|
|
148
110
|
-t, --tier <type> Filter by tier: full, lite, observer
|
|
149
111
|
-s, --sort <field> Sort by: stake, score, apy, uptime, name (default: score)
|
|
150
112
|
-l, --limit <n> Max validators to show (default: 100, max: 500)
|
|
151
|
-
-r, --rpc <url> RPC endpoint (default: ${
|
|
113
|
+
-r, --rpc <url> RPC endpoint (default: ${defaultRpc} or $AETHER_RPC)
|
|
152
114
|
-j, --json Output raw JSON (for scripting)
|
|
153
115
|
-h, --help Show this help message
|
|
154
116
|
|
|
155
117
|
${C.bright}Options (rank):${C.reset}
|
|
156
118
|
-t, --tier <type> Filter by tier: full, lite, observer
|
|
157
119
|
-l, --limit <n> Max validators to show (default: 50, max: 200)
|
|
158
|
-
-r, --rpc <url> RPC endpoint (default: ${
|
|
120
|
+
-r, --rpc <url> RPC endpoint (default: ${defaultRpc} or $AETHER_RPC)
|
|
159
121
|
-j, --json Output raw JSON (for scripting)
|
|
160
122
|
-h, --help Show this help message
|
|
161
123
|
|
|
124
|
+
${C.bright}SDK Methods Used:${C.reset}
|
|
125
|
+
client.getValidators() → GET /v1/validators
|
|
126
|
+
client.getEpochInfo() → GET /v1/epoch
|
|
127
|
+
client.getSupply() → GET /v1/supply
|
|
128
|
+
|
|
162
129
|
${C.bright}Examples:${C.reset}
|
|
163
130
|
aether validators list # All validators, sorted by score
|
|
164
131
|
aether validators list --tier full # Full validators only
|
|
@@ -173,46 +140,40 @@ ${C.bright}Examples:${C.reset}
|
|
|
173
140
|
}
|
|
174
141
|
|
|
175
142
|
// ---------------------------------------------------------------------------
|
|
176
|
-
// Data fetchers
|
|
143
|
+
// Data fetchers using SDK - Real blockchain RPC calls
|
|
177
144
|
// ---------------------------------------------------------------------------
|
|
178
145
|
|
|
179
|
-
/** Fetch all validators from the network */
|
|
146
|
+
/** Fetch all validators from the network using SDK */
|
|
180
147
|
async function fetchValidators(rpc) {
|
|
181
148
|
try {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
if (res.validators && Array.isArray(res.validators)) return res.validators;
|
|
187
|
-
if (res.accounts && Array.isArray(res.accounts)) return res.accounts;
|
|
188
|
-
}
|
|
189
|
-
// Fallback: POST to a validators query endpoint
|
|
190
|
-
const res2 = await httpPost(rpc, '/v1/validators', {});
|
|
191
|
-
if (res2 && !res2.error) {
|
|
192
|
-
if (Array.isArray(res2)) return res2;
|
|
193
|
-
if (res2.validators && Array.isArray(res2.validators)) return res2.validators;
|
|
194
|
-
}
|
|
195
|
-
return [];
|
|
149
|
+
const client = createClient(rpc);
|
|
150
|
+
// SDK getValidators() → GET /v1/validators
|
|
151
|
+
const result = await client.getValidators();
|
|
152
|
+
return Array.isArray(result) ? result : [];
|
|
196
153
|
} catch {
|
|
197
154
|
return [];
|
|
198
155
|
}
|
|
199
156
|
}
|
|
200
157
|
|
|
201
|
-
/** Fetch epoch info for APY calculations */
|
|
158
|
+
/** Fetch epoch info for APY calculations using SDK */
|
|
202
159
|
async function fetchEpochInfo(rpc) {
|
|
203
160
|
try {
|
|
204
|
-
const
|
|
205
|
-
|
|
161
|
+
const client = createClient(rpc);
|
|
162
|
+
// SDK getEpochInfo() → GET /v1/epoch
|
|
163
|
+
const result = await client.getEpochInfo();
|
|
164
|
+
return result || null;
|
|
206
165
|
} catch {
|
|
207
166
|
return null;
|
|
208
167
|
}
|
|
209
168
|
}
|
|
210
169
|
|
|
211
|
-
/** Fetch network-wide stake totals for APY estimation */
|
|
170
|
+
/** Fetch network-wide stake totals for APY estimation using SDK */
|
|
212
171
|
async function fetchSupply(rpc) {
|
|
213
172
|
try {
|
|
214
|
-
const
|
|
215
|
-
|
|
173
|
+
const client = createClient(rpc);
|
|
174
|
+
// SDK getSupply() → GET /v1/supply
|
|
175
|
+
const result = await client.getSupply();
|
|
176
|
+
return result || null;
|
|
216
177
|
} catch {
|
|
217
178
|
return null;
|
|
218
179
|
}
|
package/commands/wallet.js
CHANGED
|
@@ -541,37 +541,11 @@ async function connectWallet(rl) {
|
|
|
541
541
|
|
|
542
542
|
// ---------------------------------------------------------------------------
|
|
543
543
|
// BALANCE
|
|
544
|
-
// Query chain RPC GET /v1/account/<addr> for real AETH balance
|
|
544
|
+
// Query chain RPC GET /v1/account/<addr> for real AETH balance using SDK
|
|
545
545
|
// ---------------------------------------------------------------------------
|
|
546
546
|
|
|
547
547
|
function getDefaultRpc() {
|
|
548
|
-
return process.env.AETHER_RPC || 'http://127.0.0.1:8899';
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
/**
|
|
552
|
-
* Make HTTP GET request to the RPC endpoint
|
|
553
|
-
*/
|
|
554
|
-
function httpRequest(rpcUrl, path) {
|
|
555
|
-
return new Promise((resolve, reject) => {
|
|
556
|
-
const url = new URL(path, rpcUrl);
|
|
557
|
-
const lib = url.protocol === 'https:' ? require('https') : require('http');
|
|
558
|
-
const req = lib.request({
|
|
559
|
-
hostname: url.hostname,
|
|
560
|
-
port: url.port || (url.protocol === 'https:' ? 443 : 80),
|
|
561
|
-
path: url.pathname + url.search,
|
|
562
|
-
method: 'GET',
|
|
563
|
-
headers: { 'Content-Type': 'application/json' },
|
|
564
|
-
}, (res) => {
|
|
565
|
-
let data = '';
|
|
566
|
-
res.on('data', (chunk) => data += chunk);
|
|
567
|
-
res.on('end', () => {
|
|
568
|
-
try { resolve(JSON.parse(data)); }
|
|
569
|
-
catch { resolve(data); }
|
|
570
|
-
});
|
|
571
|
-
});
|
|
572
|
-
req.on('error', reject);
|
|
573
|
-
req.end();
|
|
574
|
-
});
|
|
548
|
+
return process.env.AETHER_RPC || aether.DEFAULT_RPC_URL || 'http://127.0.0.1:8899';
|
|
575
549
|
}
|
|
576
550
|
|
|
577
551
|
/**
|
|
@@ -612,9 +586,11 @@ async function balanceWallet(rl) {
|
|
|
612
586
|
console.log();
|
|
613
587
|
|
|
614
588
|
try {
|
|
589
|
+
// Use SDK for real blockchain RPC call
|
|
590
|
+
const client = new aether.AetherClient({ rpcUrl });
|
|
615
591
|
// Strip ATH prefix if present for API call
|
|
616
592
|
const rawAddr = address.startsWith('ATH') ? address.slice(3) : address;
|
|
617
|
-
const account = await
|
|
593
|
+
const account = await client.getAccountInfo(rawAddr);
|
|
618
594
|
|
|
619
595
|
if (!account || account.error) {
|
|
620
596
|
console.log(` ${C.yellow}⚠ Account not found on chain or RPC error.${C.reset}`);
|
package/index.js
CHANGED
|
@@ -30,6 +30,12 @@ const { broadcastCommand } = require('./commands/broadcast');
|
|
|
30
30
|
const { apyCommand } = require('./commands/apy');
|
|
31
31
|
const { statsCommand } = require('./commands/stats');
|
|
32
32
|
const { txHistoryCommand } = require('./commands/tx-history');
|
|
33
|
+
const { feesCommand } = require('./commands/fees');
|
|
34
|
+
const { tpsCommand } = require('./commands/tps');
|
|
35
|
+
const { blockhashCommand } = require('./commands/blockhash');
|
|
36
|
+
const { sdkTestCommand } = require('./commands/sdk-test');
|
|
37
|
+
const { balanceCommand } = require('./commands/balance');
|
|
38
|
+
const { transferCommand } = require('./commands/transfer');
|
|
33
39
|
const readline = require('readline');
|
|
34
40
|
|
|
35
41
|
// CLI version
|
|
@@ -204,6 +210,13 @@ const COMMANDS = {
|
|
|
204
210
|
stakePositionsCommand();
|
|
205
211
|
},
|
|
206
212
|
},
|
|
213
|
+
'stake-info': {
|
|
214
|
+
description: 'Get staking info for an address via real chain RPC — aether stake-info <address>',
|
|
215
|
+
handler: () => {
|
|
216
|
+
const { stakeInfoCommand } = require('./commands/stake-info');
|
|
217
|
+
stakeInfoCommand();
|
|
218
|
+
},
|
|
219
|
+
},
|
|
207
220
|
unstake: {
|
|
208
221
|
description: 'Unstake AETH — deactivate a stake account — aether unstake --account <stakeAcct> [--amount <aeth>]',
|
|
209
222
|
handler: () => {
|
|
@@ -227,11 +240,7 @@ const COMMANDS = {
|
|
|
227
240
|
transfer: {
|
|
228
241
|
description: 'Transfer AETH to another address — aether transfer --to <addr> --amount <aeth>',
|
|
229
242
|
handler: () => {
|
|
230
|
-
|
|
231
|
-
const originalArgv = process.argv;
|
|
232
|
-
process.argv = [...originalArgv.slice(0, 2), 'wallet', 'transfer', ...originalArgv.slice(3)];
|
|
233
|
-
walletCommand();
|
|
234
|
-
process.argv = originalArgv;
|
|
243
|
+
transferCommand();
|
|
235
244
|
},
|
|
236
245
|
},
|
|
237
246
|
tx: {
|
|
@@ -246,6 +255,20 @@ const COMMANDS = {
|
|
|
246
255
|
txHistoryCommand();
|
|
247
256
|
},
|
|
248
257
|
},
|
|
258
|
+
blockhash: {
|
|
259
|
+
description: 'Get the latest blockhash from the chain (required for signing TXs) — aether blockhash [--json] [--watch]',
|
|
260
|
+
handler: () => {
|
|
261
|
+
const { blockhashCommand } = require('./commands/blockhash');
|
|
262
|
+
blockhashCommand();
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
balance: {
|
|
266
|
+
description: 'Query account balance — aether balance [address] [--json] [--lamports] [--rpc <url>]',
|
|
267
|
+
handler: () => {
|
|
268
|
+
const { balanceCommand } = require('./commands/balance');
|
|
269
|
+
balanceCommand();
|
|
270
|
+
},
|
|
271
|
+
},
|
|
249
272
|
network: {
|
|
250
273
|
description: 'Aether network status — slot, block height, peers, TPS, epoch info',
|
|
251
274
|
handler: () => {
|
|
@@ -394,6 +417,31 @@ const COMMANDS = {
|
|
|
394
417
|
emergencyCommand();
|
|
395
418
|
},
|
|
396
419
|
},
|
|
420
|
+
fees: {
|
|
421
|
+
description: 'Network fee estimates — aether fees [--json] [--verbose] [--rpc <url>]',
|
|
422
|
+
handler: () => {
|
|
423
|
+
feesCommand();
|
|
424
|
+
},
|
|
425
|
+
},
|
|
426
|
+
tps: {
|
|
427
|
+
description: 'Transactions per second monitor — aether tps [--monitor] [--interval 2] [--json]',
|
|
428
|
+
handler: () => {
|
|
429
|
+
tpsCommand();
|
|
430
|
+
},
|
|
431
|
+
},
|
|
432
|
+
claim: {
|
|
433
|
+
description: 'Claim accumulated staking rewards — aether claim --address <addr> [--json] [--dry-run]',
|
|
434
|
+
handler: () => {
|
|
435
|
+
const { claimCommand } = require('./commands/claim');
|
|
436
|
+
claimCommand();
|
|
437
|
+
},
|
|
438
|
+
},
|
|
439
|
+
'sdk-test': {
|
|
440
|
+
description: 'Test SDK with real RPC calls — aether sdk-test [--rpc <url>] [--quick] [--json]',
|
|
441
|
+
handler: () => {
|
|
442
|
+
sdkTestCommand();
|
|
443
|
+
},
|
|
444
|
+
},
|
|
397
445
|
help: {
|
|
398
446
|
description: 'Show this help message',
|
|
399
447
|
handler: showHelp,
|
|
@@ -448,7 +496,7 @@ function parseArgs() {
|
|
|
448
496
|
const args = process.argv.slice(2);
|
|
449
497
|
|
|
450
498
|
// Handle version flag
|
|
451
|
-
if (args.includes('--version') || args.includes('-v')) {
|
|
499
|
+
if (args.includes('--version') || args.includes('-v') || args.includes('-V')) {
|
|
452
500
|
return 'version';
|
|
453
501
|
}
|
|
454
502
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aether-hub",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.7",
|
|
4
4
|
"description": "AeTHer Validator CLI — tiered validators (Full/Lite/Observer), system checks, onboarding, and node management",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -18,8 +18,6 @@
|
|
|
18
18
|
"test": "node test/doctor.test.js",
|
|
19
19
|
"start": "node index.js",
|
|
20
20
|
"doctor": "node index.js doctor",
|
|
21
|
-
"price": "node index.js price",
|
|
22
|
-
"build": "node -e \"require('./commands/price'); require('./commands/account'); require('./commands/emergency')\" && echo \"Build OK\"",
|
|
23
21
|
"postinstall": "node -e \"console.log('\\n\\n [Aether] aether-hub installed!\\n\\n Run: aether start\\n Docs: https://github.com/jelly-legs-ai/Jelly-legs-unsteady-workshop\\n')\""
|
|
24
22
|
},
|
|
25
23
|
"keywords": [
|