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.
@@ -25,19 +25,15 @@ const bs58 = require('bs58').default;
25
25
  const bip39 = require('bip39');
26
26
  const nacl = require('tweetnacl');
27
27
 
28
- // ANSI colours
29
- const C = {
30
- reset: '\x1b[0m',
31
- bright: '\x1b[1m',
32
- dim: '\x1b[2m',
33
- red: '\x1b[31m',
34
- green: '\x1b[32m',
35
- yellow: '\x1b[33m',
36
- cyan: '\x1b[36m',
37
- magenta: '\x1b[35m',
38
- };
39
-
40
- const CLI_VERSION = '1.2.5';
28
+ // Import theme
29
+ const theme = require('../theme');
30
+ const { C, BANNERS, ICONS } = theme;
31
+
32
+ // Import SDK
33
+ const sdkPath = path.join(__dirname, '..', 'sdk', 'index.js');
34
+ const { AetherClient } = require(sdkPath);
35
+
36
+ const CLI_VERSION = '1.3.0';
41
37
  const MULTISIG_VERSION = 1;
42
38
 
43
39
  // ---------------------------------------------------------------------------
@@ -109,53 +105,19 @@ function getDefaultRpc() {
109
105
  return process.env.AETHER_RPC || 'http://127.0.0.1:8899';
110
106
  }
111
107
 
112
- function httpRequest(rpcUrl, pathStr, timeoutMs = 10000) {
113
- return new Promise((resolve, reject) => {
114
- const url = new URL(pathStr, rpcUrl);
115
- const lib = url.protocol === 'https:' ? require('https') : require('http');
116
- const req = lib.request({
117
- hostname: url.hostname,
118
- port: url.port || (url.protocol === 'https:' ? 443 : 80),
119
- path: url.pathname + url.search,
120
- method: 'GET',
121
- timeout: timeoutMs,
122
- headers: { 'Content-Type': 'application/json' },
123
- }, (res) => {
124
- let data = '';
125
- res.on('data', (chunk) => data += chunk);
126
- res.on('end', () => { try { resolve(JSON.parse(data)); } catch { resolve({ _raw: data }); } });
127
- });
128
- req.on('error', reject);
129
- req.on('timeout', () => { req.destroy(); reject(new Error('Request timeout')); });
130
- req.end();
131
- });
108
+ function createClient(rpcUrl) {
109
+ return new AetherClient({ rpcUrl });
132
110
  }
133
111
 
134
- function httpPost(rpcUrl, pathStr, body, timeoutMs = 15000) {
135
- return new Promise((resolve, reject) => {
136
- const url = new URL(pathStr, rpcUrl);
137
- const lib = url.protocol === 'https:' ? require('https') : require('http');
138
- const bodyStr = JSON.stringify(body);
139
- const req = lib.request({
140
- hostname: url.hostname,
141
- port: url.port || (url.protocol === 'https:' ? 443 : 80),
142
- path: url.pathname + url.search,
143
- method: 'POST',
144
- timeout: timeoutMs,
145
- headers: {
146
- 'Content-Type': 'application/json',
147
- 'Content-Length': Buffer.byteLength(bodyStr),
148
- },
149
- }, (res) => {
150
- let data = '';
151
- res.on('data', (chunk) => data += chunk);
152
- res.on('end', () => { try { resolve(JSON.parse(data)); } catch { resolve({ _raw: data }); } });
153
- });
154
- req.on('error', reject);
155
- req.on('timeout', () => { req.destroy(); reject(new Error('Request timeout')); });
156
- req.write(bodyStr);
157
- req.end();
158
- });
112
+ /** Fetch balance using SDK */
113
+ async function fetchBalance(rpc, address) {
114
+ const client = createClient(rpc);
115
+ try {
116
+ const account = await client.getAccountInfo(address);
117
+ return account.lamports || 0;
118
+ } catch {
119
+ return null;
120
+ }
159
121
  }
160
122
 
161
123
  function formatAether(lamports) {
@@ -243,7 +205,7 @@ function askMnemonic(rl, label = 'wallet passphrase') {
243
205
  // ---------------------------------------------------------------------------
244
206
 
245
207
  async function createMultisig(rl, args) {
246
- console.log(`\n${C.bright}${C.cyan}── Create Multi-Signature Wallet ─────────────────────────${C.reset}\n`);
208
+ console.log(`\n${BANNERS.multisig}\n`);
247
209
 
248
210
  // Parse --threshold and --signers from args
249
211
  let threshold = null;
@@ -337,7 +299,7 @@ async function createMultisig(rl, args) {
337
299
  // ---------------------------------------------------------------------------
338
300
 
339
301
  async function listMultisig(rl, args) {
340
- console.log(`\n${C.bright}${C.cyan}── Multi-Signature Wallets ────────────────────────────${C.reset}\n`);
302
+ console.log(`\n${BANNERS.multisig} (List)\n`);
341
303
 
342
304
  const all = listAllMultisig();
343
305
 
@@ -356,12 +318,12 @@ async function listMultisig(rl, args) {
356
318
  console.log(` ${C.dim} Threshold: ${ms.threshold}/${ms.signers.length} Signers: ${ms.signers.length}${C.reset}`);
357
319
  console.log(` ${C.dim} Created: ${new Date(ms.created_at).toLocaleString()}${C.reset}`);
358
320
 
359
- // Fetch on-chain balance
321
+ // Fetch on-chain balance using SDK
360
322
  try {
361
323
  const rawAddr = ms.address.startsWith('ATH') ? ms.address.slice(3) : ms.address;
362
- const account = await httpRequest(rpcUrl, `/v1/account/${rawAddr}`);
363
- if (!account.error && account.lamports !== undefined) {
364
- console.log(` ${C.green} Balance:${C.reset} ${C.bright}${formatAether(account.lamports)}${C.reset}`);
324
+ const balance = await fetchBalance(rpcUrl, rawAddr);
325
+ if (balance !== null) {
326
+ console.log(` ${C.green}${ICONS.success} Balance:${C.reset} ${C.bright}${formatAether(balance)}${C.reset}`);
365
327
  }
366
328
  } catch {}
367
329
 
@@ -374,7 +336,7 @@ async function listMultisig(rl, args) {
374
336
  // ---------------------------------------------------------------------------
375
337
 
376
338
  async function infoMultisig(rl, args) {
377
- console.log(`\n${C.bright}${C.cyan}── Multi-Signature Wallet Info ─────────────────────────${C.reset}\n`);
339
+ console.log(`\n${BANNERS.multisig} (Info)\n`);
378
340
 
379
341
  let address = null;
380
342
  for (let i = 0; i < args.length; i++) {
@@ -390,21 +352,21 @@ async function infoMultisig(rl, args) {
390
352
  }
391
353
 
392
354
  if (!address) {
393
- console.log(` ${C.red}No address specified.${C.reset}`);
355
+ console.log(` ${ICONS.error} ${C.red}No address specified.${C.reset}`);
394
356
  console.log(` ${C.dim}Usage: aether multisig info --address <addr>${C.reset}\n`);
395
357
  return;
396
358
  }
397
359
 
398
360
  const ms = loadMultisig(address);
399
361
  if (!ms) {
400
- console.log(` ${C.red}Multisig wallet not found:${C.reset} ${address}`);
362
+ console.log(` ${ICONS.error} ${C.red}Multisig wallet not found:${C.reset} ${address}`);
401
363
  console.log(` ${C.dim}Check your wallets: aether multisig list${C.reset}\n`);
402
364
  return;
403
365
  }
404
366
 
405
367
  const rpcUrl = getDefaultRpc();
406
- console.log(` ${C.green}★${C.reset} Address: ${C.bright}${ms.address}${C.reset}`);
407
- console.log(` ${C.green}★${C.reset} Threshold: ${C.bright}${ms.threshold} of ${ms.signers.length}${C.reset}`);
368
+ console.log(` ${ICONS.success} ${C.green}Address:${C.reset} ${C.bright}${ms.address}${C.reset}`);
369
+ console.log(` ${ICONS.success} ${C.green}Threshold:${C.reset} ${C.bright}${ms.threshold} of ${ms.signers.length}${C.reset}`);
408
370
  console.log(` ${C.dim} Public key: ${ms.public_key}${C.reset}`);
409
371
  console.log(` ${C.dim} Created: ${new Date(ms.created_at).toLocaleString()}${C.reset}`);
410
372
  console.log(` ${C.dim} Version: ${ms.version}${C.reset}`);
@@ -414,25 +376,22 @@ async function infoMultisig(rl, args) {
414
376
  for (let i = 0; i < ms.signers.length; i++) {
415
377
  const s = ms.signers[i];
416
378
  const isYou = s === loadConfig().defaultWallet;
417
- const marker = isYou ? ` ${C.green} you${C.reset}` : '';
379
+ const marker = isYou ? ` ${C.green}${ICONS.success} you${C.reset}` : '';
418
380
  console.log(` ${i + 1}. ${C.cyan}${s}${C.reset}${marker}`);
419
381
  }
420
382
  console.log();
421
383
 
422
- // On-chain balance
384
+ // On-chain balance using SDK
423
385
  try {
424
386
  const rawAddr = ms.address.startsWith('ATH') ? ms.address.slice(3) : ms.address;
425
- const account = await httpRequest(rpcUrl, `/v1/account/${rawAddr}`);
426
- if (!account.error && account.lamports !== undefined) {
427
- console.log(` ${C.green}Balance:${C.reset} ${C.bright}${formatAether(account.lamports)}${C.reset}`);
428
- if (account.owner) {
429
- console.log(` ${C.dim} Owner: ${account.owner}${C.reset}`);
430
- }
387
+ const balance = await fetchBalance(rpcUrl, rawAddr);
388
+ if (balance !== null) {
389
+ console.log(` ${ICONS.success} ${C.green}Balance:${C.reset} ${C.bright}${formatAether(balance)}${C.reset}`);
431
390
  } else {
432
- console.log(` ${C.yellow}Account not found on chain (may have 0 balance).${C.reset}`);
391
+ console.log(` ${ICONS.warning} ${C.yellow}Account not found on chain (may have 0 balance).${C.reset}`);
433
392
  }
434
393
  } catch (err) {
435
- console.log(` ${C.yellow}Could not fetch balance: ${err.message}${C.reset}`);
394
+ console.log(` ${ICONS.warning} ${C.yellow}Could not fetch balance: ${err.message}${C.reset}`);
436
395
  }
437
396
 
438
397
  console.log();
@@ -443,7 +402,7 @@ async function infoMultisig(rl, args) {
443
402
  // ---------------------------------------------------------------------------
444
403
 
445
404
  async function addSignerMultisig(rl, args) {
446
- console.log(`\n${C.bright}${C.cyan}── Add Signer to Multi-Signature Wallet ─────────────────${C.reset}\n`);
405
+ console.log(`\n${BANNERS.multisig} (Add Signer)\n`);
447
406
 
448
407
  let address = null;
449
408
  let newSigner = null;
@@ -454,29 +413,29 @@ async function addSignerMultisig(rl, args) {
454
413
  }
455
414
 
456
415
  if (!address || !newSigner) {
457
- console.log(` ${C.red}Missing required arguments.${C.reset}`);
416
+ console.log(` ${ICONS.error} ${C.red}Missing required arguments.${C.reset}`);
458
417
  console.log(` ${C.dim}Usage: aether multisig add-signer --address <msAddr> --signer <newAddr>${C.reset}\n`);
459
418
  return;
460
419
  }
461
420
 
462
421
  const ms = loadMultisig(address);
463
422
  if (!ms) {
464
- console.log(` ${C.red}Multisig wallet not found:${C.reset} ${address}\n`);
423
+ console.log(` ${ICONS.error} ${C.red}Multisig wallet not found:${C.reset} ${address}\n`);
465
424
  return;
466
425
  }
467
426
 
468
427
  if (!isValidAddress(newSigner)) {
469
- console.log(` ${C.red}Invalid signer address:${C.reset} ${newSigner}\n`);
428
+ console.log(` ${ICONS.error} ${C.red}Invalid signer address:${C.reset} ${newSigner}\n`);
470
429
  return;
471
430
  }
472
431
 
473
432
  if (ms.signers.includes(newSigner)) {
474
- console.log(` ${C.yellow}Signer already in wallet:${C.reset} ${newSigner}\n`);
433
+ console.log(` ${ICONS.warning} ${C.yellow}Signer already in wallet:${C.reset} ${newSigner}\n`);
475
434
  return;
476
435
  }
477
436
 
478
- console.log(` ${C.green}★${C.reset} Multisig: ${C.bright}${shortAddress(address)}${C.reset}`);
479
- console.log(` ${C.green}★${C.reset} Adding: ${C.bright}${shortAddress(newSigner)}${C.reset}`);
437
+ console.log(` ${ICONS.success} ${C.green}Multisig:${C.reset} ${C.bright}${shortAddress(address)}${C.reset}`);
438
+ console.log(` ${ICONS.success} ${C.green}Adding:${C.reset} ${C.bright}${shortAddress(newSigner)}${C.reset}`);
480
439
  console.log(` ${C.dim} Current threshold: ${ms.threshold}/${ms.signers.length}${C.reset}`);
481
440
  console.log();
482
441
 
@@ -494,8 +453,8 @@ async function addSignerMultisig(rl, args) {
494
453
 
495
454
  saveMultisig(newMs);
496
455
 
497
- console.log(`${C.green} Signer added.${C.reset}`);
498
- console.log(` ${C.yellow}Important: Changing signers creates a NEW wallet address.${C.reset}`);
456
+ console.log(`${C.green}${ICONS.success} Signer added.${C.reset}`);
457
+ console.log(` ${ICONS.warning} ${C.yellow}Important: Changing signers creates a NEW wallet address.${C.reset}`);
499
458
  console.log(` ${C.dim} Old address: ${ms.address}${C.reset}`);
500
459
  console.log(` ${C.dim} New address: ${newAddress}${C.reset}`);
501
460
  console.log(` ${C.dim} Transfer all funds to the new address.${C.reset}`);