aether-hub 1.2.7 → 1.2.8
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 +280 -280
- package/commands/apy.js +480 -480
- package/commands/balance.js +276 -276
- package/commands/claim.js +292 -292
- package/commands/delegations.js +45 -95
- package/commands/emergency.js +14 -4
- package/commands/epoch.js +275 -275
- package/commands/fees.js +276 -276
- package/commands/info.js +495 -495
- package/commands/monitor.js +431 -431
- package/commands/multisig.js +726 -726
- package/commands/network.js +429 -429
- package/commands/ping.js +266 -266
- package/commands/sdk-test.js +477 -477
- package/commands/sdk.js +537 -537
- package/commands/slot.js +155 -0
- package/commands/snapshot.js +509 -509
- package/commands/stake-positions.js +31 -46
- package/commands/stats.js +418 -418
- package/commands/status.js +326 -326
- package/commands/supply.js +3 -1
- package/commands/tps.js +238 -238
- package/commands/tx-history.js +346 -462
- package/commands/wallet.js +3 -0
- package/index.js +11 -2
- package/package.json +1 -1
package/commands/delegations.js
CHANGED
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
* aether delegations list --address <addr> List all stake delegations
|
|
10
10
|
* aether delegations list --address <addr> --json JSON output
|
|
11
11
|
* aether delegations claim --address <addr> --account <stakeAcct> [--json]
|
|
12
|
+
*
|
|
13
|
+
* SDK wired to: GET /v1/slot, GET /v1/account/<addr>, GET /v1/stake/<addr>
|
|
12
14
|
*/
|
|
13
15
|
|
|
14
|
-
const
|
|
15
|
-
const https = require('https');
|
|
16
|
+
const path = require('path');
|
|
16
17
|
const readline = require('readline');
|
|
17
18
|
const crypto = require('crypto');
|
|
18
19
|
const bs58 = require('bs58').default;
|
|
@@ -32,18 +33,25 @@ const C = {
|
|
|
32
33
|
};
|
|
33
34
|
|
|
34
35
|
const DERIVATION_PATH = "m/44'/7777777'/0'/0'";
|
|
35
|
-
const CLI_VERSION = '1.0.
|
|
36
|
+
const CLI_VERSION = '1.0.6';
|
|
37
|
+
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// SDK Import
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
const sdkPath = path.join(__dirname, '..', 'sdk', 'index.js');
|
|
43
|
+
const aether = require(sdkPath);
|
|
36
44
|
|
|
37
45
|
// ---------------------------------------------------------------------------
|
|
38
46
|
// Paths & config
|
|
39
47
|
// ---------------------------------------------------------------------------
|
|
40
48
|
|
|
41
49
|
function getAetherDir() {
|
|
42
|
-
return
|
|
50
|
+
return path.join(require('os').homedir(), '.aether');
|
|
43
51
|
}
|
|
44
52
|
|
|
45
53
|
function loadConfig() {
|
|
46
|
-
const p =
|
|
54
|
+
const p = path.join(getAetherDir(), 'config.json');
|
|
47
55
|
if (!require('fs').existsSync(p)) return { defaultWallet: null };
|
|
48
56
|
try {
|
|
49
57
|
return JSON.parse(require('fs').readFileSync(p, 'utf8'));
|
|
@@ -53,7 +61,7 @@ function loadConfig() {
|
|
|
53
61
|
}
|
|
54
62
|
|
|
55
63
|
function loadWallet(address) {
|
|
56
|
-
const fp =
|
|
64
|
+
const fp = path.join(getAetherDir(), 'wallets', `${address}.json`);
|
|
57
65
|
if (!require('fs').existsSync(fp)) return null;
|
|
58
66
|
return JSON.parse(require('fs').readFileSync(fp, 'utf8'));
|
|
59
67
|
}
|
|
@@ -75,57 +83,15 @@ function formatAddress(publicKey) {
|
|
|
75
83
|
}
|
|
76
84
|
|
|
77
85
|
// ---------------------------------------------------------------------------
|
|
78
|
-
//
|
|
86
|
+
// Config helpers
|
|
79
87
|
// ---------------------------------------------------------------------------
|
|
80
88
|
|
|
81
|
-
function
|
|
82
|
-
return
|
|
83
|
-
const url = new URL(path, rpcUrl);
|
|
84
|
-
const lib = url.protocol === 'https:' ? https : http;
|
|
85
|
-
const req = lib.request({
|
|
86
|
-
hostname: url.hostname,
|
|
87
|
-
port: url.port || (url.protocol === 'https:' ? 443 : 80),
|
|
88
|
-
path: url.pathname + url.search,
|
|
89
|
-
method: 'GET',
|
|
90
|
-
timeout: 8000,
|
|
91
|
-
headers: { 'Content-Type': 'application/json' },
|
|
92
|
-
}, (res) => {
|
|
93
|
-
let data = '';
|
|
94
|
-
res.on('data', (chunk) => data += chunk);
|
|
95
|
-
res.on('end', () => { try { resolve(JSON.parse(data)); } catch { resolve({ raw: data }); } });
|
|
96
|
-
});
|
|
97
|
-
req.on('error', reject);
|
|
98
|
-
req.on('timeout', () => { req.destroy(); reject(new Error('Request timeout')); });
|
|
99
|
-
req.end();
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function httpPost(rpcUrl, path, body) {
|
|
104
|
-
return new Promise((resolve, reject) => {
|
|
105
|
-
const url = new URL(path, rpcUrl);
|
|
106
|
-
const lib = url.protocol === 'https:' ? https : http;
|
|
107
|
-
const bodyStr = JSON.stringify(body);
|
|
108
|
-
const req = lib.request({
|
|
109
|
-
hostname: url.hostname,
|
|
110
|
-
port: url.port || (url.protocol === 'https:' ? 443 : 80),
|
|
111
|
-
path: url.pathname + url.search,
|
|
112
|
-
method: 'POST',
|
|
113
|
-
timeout: 8000,
|
|
114
|
-
headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(bodyStr) },
|
|
115
|
-
}, (res) => {
|
|
116
|
-
let data = '';
|
|
117
|
-
res.on('data', (chunk) => data += chunk);
|
|
118
|
-
res.on('end', () => { try { resolve(JSON.parse(data)); } catch { resolve({ raw: data }); } });
|
|
119
|
-
});
|
|
120
|
-
req.on('error', reject);
|
|
121
|
-
req.on('timeout', () => { req.destroy(); reject(new Error('Request timeout')); });
|
|
122
|
-
req.write(bodyStr);
|
|
123
|
-
req.end();
|
|
124
|
-
});
|
|
89
|
+
function getDefaultRpc() {
|
|
90
|
+
return process.env.AETHER_RPC || aether.DEFAULT_RPC_URL || 'http://127.0.0.1:8899';
|
|
125
91
|
}
|
|
126
92
|
|
|
127
|
-
function
|
|
128
|
-
return
|
|
93
|
+
function createClient(rpcUrl) {
|
|
94
|
+
return new aether.AetherClient({ rpcUrl });
|
|
129
95
|
}
|
|
130
96
|
|
|
131
97
|
function formatAether(lamports) {
|
|
@@ -159,7 +125,7 @@ async function askMnemonic(rl, prompt) {
|
|
|
159
125
|
}
|
|
160
126
|
|
|
161
127
|
// ---------------------------------------------------------------------------
|
|
162
|
-
// LIST DELEGATIONS
|
|
128
|
+
// LIST DELEGATIONS — uses SDK
|
|
163
129
|
// ---------------------------------------------------------------------------
|
|
164
130
|
|
|
165
131
|
async function listDelegations(args) {
|
|
@@ -169,9 +135,9 @@ async function listDelegations(args) {
|
|
|
169
135
|
let rpcUrl = getDefaultRpc();
|
|
170
136
|
|
|
171
137
|
for (let i = 0; i < args.length; i++) {
|
|
172
|
-
if ((args[i] === '--address' || args[i] === '-a') && args[i + 1]) address = args[i
|
|
138
|
+
if ((args[i] === '--address' || args[i] === '-a') && args[i + 1]) address = args[++i];
|
|
173
139
|
else if (args[i] === '--json' || args[i] === '-j') asJson = true;
|
|
174
|
-
else if ((args[i] === '--rpc' || args[i] === '-r') && args[i + 1]) rpcUrl = args[i
|
|
140
|
+
else if ((args[i] === '--rpc' || args[i] === '-r') && args[i + 1]) rpcUrl = args[++i];
|
|
175
141
|
}
|
|
176
142
|
|
|
177
143
|
if (!address) {
|
|
@@ -186,29 +152,15 @@ async function listDelegations(args) {
|
|
|
186
152
|
return;
|
|
187
153
|
}
|
|
188
154
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
// Fetch account info for context
|
|
193
|
-
const account = await httpRequest(rpcUrl, `/v1/account/${rawAddr}`);
|
|
155
|
+
const client = createClient(rpcUrl);
|
|
156
|
+
const rawAddr = address.startsWith('ATH') ? address.slice(3) : address;
|
|
194
157
|
|
|
195
|
-
|
|
196
|
-
//
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
stakeAccounts = Array.isArray(res) ? res : (res.accounts || []);
|
|
202
|
-
}
|
|
203
|
-
} catch {
|
|
204
|
-
// Fallback: try program account query
|
|
205
|
-
try {
|
|
206
|
-
const res2 = await httpRequest(rpcUrl, `/v1/program/STAKE/accounts?owner=${encodeURIComponent(rawAddr)}`);
|
|
207
|
-
if (res2 && !res2.error) {
|
|
208
|
-
stakeAccounts = Array.isArray(res2) ? res2 : (res2.accounts || []);
|
|
209
|
-
}
|
|
210
|
-
} catch { /* no stake accounts or RPC doesn't support this endpoint */ }
|
|
211
|
-
}
|
|
158
|
+
try {
|
|
159
|
+
// Real chain RPC calls via SDK
|
|
160
|
+
const [account, stakeAccounts] = await Promise.all([
|
|
161
|
+
client.getAccountInfo(rawAddr).catch(() => null),
|
|
162
|
+
client.getStakePositions(rawAddr).catch(() => []),
|
|
163
|
+
]);
|
|
212
164
|
|
|
213
165
|
if (asJson) {
|
|
214
166
|
console.log(JSON.stringify({
|
|
@@ -216,6 +168,7 @@ async function listDelegations(args) {
|
|
|
216
168
|
rpc: rpcUrl,
|
|
217
169
|
account: account && !account.error ? { lamports: account.lamports } : null,
|
|
218
170
|
delegations: stakeAccounts,
|
|
171
|
+
cli_version: CLI_VERSION,
|
|
219
172
|
fetched_at: new Date().toISOString(),
|
|
220
173
|
}, null, 2));
|
|
221
174
|
rl.close();
|
|
@@ -230,7 +183,7 @@ async function listDelegations(args) {
|
|
|
230
183
|
}
|
|
231
184
|
console.log();
|
|
232
185
|
|
|
233
|
-
if (stakeAccounts.length === 0) {
|
|
186
|
+
if (!stakeAccounts || stakeAccounts.length === 0) {
|
|
234
187
|
console.log(` ${C.dim}No stake delegations found for this wallet.${C.reset}`);
|
|
235
188
|
console.log(` ${C.dim}Delegate with:${C.reset} ${C.cyan}aether stake --address ${address} --validator <val> --amount <aeth>${C.reset}\n`);
|
|
236
189
|
rl.close();
|
|
@@ -282,7 +235,7 @@ async function listDelegations(args) {
|
|
|
282
235
|
}
|
|
283
236
|
|
|
284
237
|
// ---------------------------------------------------------------------------
|
|
285
|
-
// CLAIM REWARDS
|
|
238
|
+
// CLAIM REWARDS — uses SDK for fetch, wallet for signing
|
|
286
239
|
// ---------------------------------------------------------------------------
|
|
287
240
|
|
|
288
241
|
async function claimRewards(args) {
|
|
@@ -294,10 +247,10 @@ async function claimRewards(args) {
|
|
|
294
247
|
let rpcUrl = getDefaultRpc();
|
|
295
248
|
|
|
296
249
|
for (let i = 0; i < args.length; i++) {
|
|
297
|
-
if ((args[i] === '--address' || args[i] === '-a') && args[i + 1]) address = args[i
|
|
298
|
-
else if ((args[i] === '--account' || args[i] === '-s') && args[i + 1]) stakeAccount = args[i
|
|
250
|
+
if ((args[i] === '--address' || args[i] === '-a') && args[i + 1]) address = args[++i];
|
|
251
|
+
else if ((args[i] === '--account' || args[i] === '-s') && args[i + 1]) stakeAccount = args[++i];
|
|
299
252
|
else if (args[i] === '--json' || args[i] === '-j') asJson = true;
|
|
300
|
-
else if ((args[i] === '--rpc' || args[i] === '-r') && args[i + 1]) rpcUrl = args[i
|
|
253
|
+
else if ((args[i] === '--rpc' || args[i] === '-r') && args[i + 1]) rpcUrl = args[++i];
|
|
301
254
|
}
|
|
302
255
|
|
|
303
256
|
if (!address) {
|
|
@@ -312,17 +265,14 @@ async function claimRewards(args) {
|
|
|
312
265
|
return;
|
|
313
266
|
}
|
|
314
267
|
|
|
268
|
+
const client = createClient(rpcUrl);
|
|
269
|
+
|
|
270
|
+
// If no stake account specified, fetch list via SDK
|
|
315
271
|
if (!stakeAccount) {
|
|
316
|
-
|
|
317
|
-
let stakeAccounts = [];
|
|
318
|
-
try {
|
|
319
|
-
const res = await httpRequest(rpcUrl, `/v1/stake?address=${encodeURIComponent(address.startsWith('ATH') ? address.slice(3) : address)}`);
|
|
320
|
-
if (res && !res.error) {
|
|
321
|
-
stakeAccounts = Array.isArray(res) ? res : (res.accounts || []);
|
|
322
|
-
}
|
|
323
|
-
} catch { /* noop */ }
|
|
272
|
+
const rawAddr = address.startsWith('ATH') ? address.slice(3) : address;
|
|
273
|
+
let stakeAccounts = await client.getStakePositions(rawAddr).catch(() => []);
|
|
324
274
|
|
|
325
|
-
if (stakeAccounts.length === 0) {
|
|
275
|
+
if (!stakeAccounts || stakeAccounts.length === 0) {
|
|
326
276
|
console.log(` ${C.red}✗ No stake accounts found.${C.reset} Use ${C.cyan}--account <stakeAcct>${C.reset} to specify one.\n`);
|
|
327
277
|
rl.close();
|
|
328
278
|
return;
|
|
@@ -366,7 +316,7 @@ async function claimRewards(args) {
|
|
|
366
316
|
|
|
367
317
|
let keyPair;
|
|
368
318
|
try {
|
|
369
|
-
keyPair = deriveKeypair(mnemonic
|
|
319
|
+
keyPair = deriveKeypair(mnemonic);
|
|
370
320
|
} catch (e) {
|
|
371
321
|
console.log(` ${C.red}✗ Failed to derive keypair: ${e.message}${C.reset}\n`);
|
|
372
322
|
rl.close();
|
|
@@ -404,10 +354,10 @@ async function claimRewards(args) {
|
|
|
404
354
|
timestamp: Math.floor(Date.now() / 1000),
|
|
405
355
|
};
|
|
406
356
|
|
|
407
|
-
console.log(` ${C.dim}Submitting to ${rpcUrl}...${C.reset}`);
|
|
357
|
+
console.log(` ${C.dim}Submitting via SDK to ${rpcUrl}...${C.reset}`);
|
|
408
358
|
|
|
409
359
|
try {
|
|
410
|
-
const result = await
|
|
360
|
+
const result = await client.sendTransaction(tx);
|
|
411
361
|
|
|
412
362
|
if (result.error) {
|
|
413
363
|
console.log(`\n ${C.red}✗ Claim failed:${C.reset} ${result.error}\n`);
|
package/commands/emergency.js
CHANGED
|
@@ -651,7 +651,17 @@ async function main() {
|
|
|
651
651
|
}
|
|
652
652
|
}
|
|
653
653
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
}
|
|
654
|
+
// Exported emergency command handler for CLI integration
|
|
655
|
+
async function emergencyCommand() {
|
|
656
|
+
return main();
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// Run if called directly
|
|
660
|
+
if (require.main === module) {
|
|
661
|
+
main().catch(err => {
|
|
662
|
+
console.error(`\n${C.red}Error in emergency command:${C.reset}`, err.message, '\n');
|
|
663
|
+
process.exit(1);
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
module.exports = { emergencyCommand };
|