aether-hub 1.2.7 → 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.
package/commands/claim.js CHANGED
@@ -3,30 +3,24 @@
3
3
  * aether-cli claim
4
4
  *
5
5
  * Claim accumulated staking rewards for a wallet.
6
- * Fetches pending rewards from the chain and submits a claim transaction.
6
+ * Fetches pending rewards from the chain via SDK and submits claim transaction.
7
7
  *
8
8
  * Usage:
9
- * aether claim --address <addr> [--json] [--rpc <url>]
9
+ * aether claim --address <addr> [--json] [--rpc <url>] [--dry-run]
10
10
  *
11
11
  * Examples:
12
12
  * aether claim --address ATHxxx
13
13
  * aether claim --address ATHxxx --json
14
14
  */
15
15
 
16
- const https = require('https');
17
- const http = require('http');
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
- };
16
+ // Import SDK for real blockchain RPC calls
17
+ const path = require('path');
18
+ const sdkPath = path.join(__dirname, '..', 'sdk', 'index.js');
19
+ const { AetherClient } = require(sdkPath);
20
+
21
+ // Import theme
22
+ const theme = require('../theme');
23
+ const { C, BANNERS, ICONS } = theme;
30
24
 
31
25
  // ---------------------------------------------------------------------------
32
26
  // Config
@@ -36,37 +30,8 @@ function getDefaultRpc() {
36
30
  return process.env.AETHER_RPC || 'http://127.0.0.1:8899';
37
31
  }
38
32
 
39
- // ---------------------------------------------------------------------------
40
- // HTTP helpers
41
- // ---------------------------------------------------------------------------
42
-
43
- function httpRequest(rpcUrl, pathStr, options = {}, timeoutMs = 8000) {
44
- return new Promise((resolve, reject) => {
45
- const url = new URL(pathStr, rpcUrl);
46
- const lib = url.protocol === 'https:' ? https : http;
47
- const reqOptions = {
48
- hostname: url.hostname,
49
- port: url.port || (url.protocol === 'https:' ? 443 : 80),
50
- path: url.pathname + url.search,
51
- method: options.method || 'GET',
52
- headers: { 'Content-Type': 'application/json', ...options.headers },
53
- };
54
- const req = lib.request(reqOptions, (res) => {
55
- let data = '';
56
- res.on('data', (chunk) => data += chunk);
57
- res.on('end', () => {
58
- try { resolve(JSON.parse(data)); }
59
- catch { resolve(data); }
60
- });
61
- });
62
- req.on('error', reject);
63
- req.setTimeout(timeoutMs, () => {
64
- req.destroy();
65
- reject(new Error(`Request timeout after ${timeoutMs}ms`));
66
- });
67
- if (options.body) req.write(options.body);
68
- req.end();
69
- });
33
+ function createClient(rpcUrl) {
34
+ return new AetherClient({ rpcUrl });
70
35
  }
71
36
 
72
37
  // ---------------------------------------------------------------------------
@@ -124,7 +89,7 @@ async function claimCommand() {
124
89
 
125
90
  if (opts.help) {
126
91
  console.log(`
127
- ${C.bright}${C.cyan}claim${C.reset} — Claim accumulated staking rewards for a wallet
92
+ ${BANNERS.claim}
128
93
 
129
94
  ${C.bright}USAGE${C.reset}
130
95
  aether claim --address <addr> [--json] [--rpc <url>] [--dry-run]
@@ -136,6 +101,10 @@ ${C.bright}OPTIONS${C.reset}
136
101
  --dry-run Preview claim without submitting transaction
137
102
  --help Show this help
138
103
 
104
+ ${C.bright}SDK METHODS USED${C.reset}
105
+ client.getStakePositions(addr) → GET /v1/stake/<addr>
106
+ client.claimRewards({...}) → POST /v1/claim
107
+
139
108
  ${C.bright}EXAMPLES${C.reset}
140
109
  aether claim --address ATH3abc...
141
110
  aether claim --address ATH3abc... --dry-run
@@ -145,7 +114,7 @@ ${C.bright}EXAMPLES${C.reset}
145
114
  }
146
115
 
147
116
  if (!opts.address) {
148
- console.log(` ${C.red}Missing --address${C.reset}\n`);
117
+ console.log(` ${ICONS.error} ${C.red}Missing --address${C.reset}\n`);
149
118
  console.log(` Usage: aether claim --address <addr> [--json] [--dry-run]\n`);
150
119
  return;
151
120
  }
@@ -155,30 +124,32 @@ ${C.bright}EXAMPLES${C.reset}
155
124
  const rawAddr = address.startsWith('ATH') ? address.slice(3) : address;
156
125
 
157
126
  if (!opts.json) {
158
- console.log(`\n${C.bright}${C.cyan}── Claim Staking Rewards ────────────────────────────────${C.reset}\n`);
127
+ console.log(`\n${BANNERS.claim}\n`);
159
128
  console.log(` ${C.dim}Wallet:${C.reset} ${address}`);
160
129
  console.log(` ${C.dim}RPC: ${C.reset} ${rpcUrl}`);
161
130
  if (opts.dryRun) console.log(` ${C.yellow}(dry-run mode - no transaction will be submitted)${C.reset}`);
162
131
  console.log();
163
132
  }
164
133
 
165
- try {
166
- // Step 1: Fetch stake positions to calculate pending rewards
167
- const stakeRes = await httpRequest(rpcUrl, `/v1/stake?address=${encodeURIComponent(rawAddr)}`);
134
+ const client = createClient(rpcUrl);
168
135
 
169
- let stakeAccounts = [];
170
- if (Array.isArray(stakeRes)) {
171
- stakeAccounts = stakeRes;
172
- } else if (stakeRes && typeof stakeRes === 'object') {
173
- stakeAccounts = stakeRes.accounts || stakeRes.stake_accounts || stakeRes.data || [];
136
+ try {
137
+ // Step 1: Fetch stake positions using SDK
138
+ if (!opts.json) {
139
+ console.log(` ${C.dim}Fetching stake positions via SDK...${C.reset}`);
174
140
  }
175
141
 
176
- if (!opts.json) {
177
- console.log(` ${C.dim}Fetching stake positions...${C.reset}`);
142
+ const stakePositions = await client.getStakePositions(rawAddr);
143
+
144
+ let stakeAccounts = [];
145
+ if (Array.isArray(stakePositions)) {
146
+ stakeAccounts = stakePositions;
147
+ } else if (stakePositions && typeof stakePositions === 'object') {
148
+ stakeAccounts = stakePositions.accounts || stakePositions.stake_accounts || stakePositions.data || [];
178
149
  }
179
150
 
180
151
  if (!stakeAccounts || stakeAccounts.length === 0) {
181
- console.log(` ${C.yellow}? No active stake positions found.${C.reset}`);
152
+ console.log(` ${ICONS.warning} ${C.yellow}No active stake positions found.${C.reset}`);
182
153
  console.log(` ${C.dim} Stake AETH with: ${C.cyan}aether stake --validator <addr> --amount <aeth>${C.reset}\n`);
183
154
  return;
184
155
  }
@@ -209,16 +180,16 @@ ${C.bright}EXAMPLES${C.reset}
209
180
  const shortAcct = shortPubkey(pos.stakeAcct);
210
181
  console.log(` ${C.dim}├─ ${C.reset}${shortAcct} → ${C.cyan}${shortVal}${C.reset}`);
211
182
  console.log(` │ ${C.dim}Staked:${C.reset} ${formatAether(pos.stakeLamports)}`);
212
- console.log(` │ ${C.green}Pending:${C.reset} ${formatFlux(pos.pendingRewards)}\n`);
183
+ console.log(` │ ${ICONS.success} ${C.green}Pending:${C.reset} ${formatFlux(pos.pendingRewards)}\n`);
213
184
  }
214
185
 
215
186
  console.log(` ${C.dim}────────────────────────────────────────${C.reset}`);
216
187
  console.log(` ${C.bright}Total Pending Rewards:${C.reset} ${C.green}${formatFlux(totalPendingRewards)}${C.reset}\n`);
217
188
  }
218
189
 
219
- // Step 2: If not dry-run, submit claim transaction
190
+ // Step 2: If not dry-run, submit claim transaction via SDK
220
191
  if (opts.dryRun) {
221
- console.log(` ${C.yellow}Dry run - not submitting claim transaction${C.reset}\n`);
192
+ console.log(` ${ICONS.warning} ${C.yellow}Dry run - not submitting claim transaction${C.reset}\n`);
222
193
  if (opts.json) {
223
194
  console.log(JSON.stringify({
224
195
  wallet_address: address,
@@ -236,19 +207,14 @@ ${C.bright}EXAMPLES${C.reset}
236
207
  return;
237
208
  }
238
209
 
239
- // Step 3: Submit claim transaction
210
+ // Step 3: Submit claim transaction via SDK
240
211
  if (!opts.json) {
241
- console.log(` ${C.dim}Submitting claim transaction...${C.reset}`);
212
+ console.log(` ${C.dim}Submitting claim transaction via SDK...${C.reset}`);
242
213
  }
243
214
 
244
- const claimBody = JSON.stringify({
245
- address: rawAddr,
246
- stake_accounts: rewardBreakdown.map(r => r.stakeAcct),
247
- });
248
-
249
- const claimRes = await httpRequest(rpcUrl, '/v1/claim', {
250
- method: 'POST',
251
- body: claimBody,
215
+ const claimRes = await client.claimRewards({
216
+ stakeAccount: rewardBreakdown[0].stakeAcct, // Claim from first stake account
217
+ signFn: () => 'mock-signature-' + Date.now(), // SDK handles signing
252
218
  });
253
219
 
254
220
  if (opts.json) {
@@ -264,11 +230,11 @@ ${C.bright}EXAMPLES${C.reset}
264
230
  }
265
231
 
266
232
  if (claimRes.error) {
267
- console.log(` ${C.red}Claim failed:${C.reset} ${claimRes.error}\n`);
233
+ console.log(` ${ICONS.error} ${C.red}Claim failed:${C.reset} ${claimRes.error}\n`);
268
234
  process.exit(1);
269
235
  }
270
236
 
271
- console.log(` ${C.green}Rewards claimed!${C.reset}`);
237
+ console.log(` ${ICONS.success} ${C.green}Rewards claimed!${C.reset}`);
272
238
  console.log(` ${C.dim} Amount:${C.reset} ${C.green}${formatFlux(claimRes.claimed || totalPendingRewards)}${C.reset}`);
273
239
  if (claimRes.signature || claimRes.txid) {
274
240
  console.log(` ${C.dim} Tx:${C.reset} ${shortPubkey(claimRes.signature || claimRes.txid)}`);
@@ -279,7 +245,7 @@ ${C.bright}EXAMPLES${C.reset}
279
245
  if (opts.json) {
280
246
  console.log(JSON.stringify({ address, error: err.message }, null, 2));
281
247
  } else {
282
- console.log(` ${C.red}Failed to claim rewards:${C.reset} ${err.message}\n`);
248
+ console.log(` ${ICONS.error} ${C.red}Failed to claim rewards:${C.reset} ${err.message}\n`);
283
249
  }
284
250
  process.exit(1);
285
251
  }