clawmoney 0.15.36 → 0.15.37

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.
@@ -20,52 +20,84 @@ export async function walletStatusCommand() {
20
20
  console.error(chalk.red(err.message));
21
21
  }
22
22
  }
23
+ // Wrap a promise in a hard timeout so a hung awal process can't
24
+ // swallow the whole command. On timeout we surface a specific
25
+ // error string the caller can tell apart from generic spawn errors.
26
+ function withTimeout(p, ms, label) {
27
+ return new Promise((resolve, reject) => {
28
+ const timer = setTimeout(() => {
29
+ reject(new Error(`${label} timed out after ${ms}ms`));
30
+ }, ms);
31
+ p.then((v) => {
32
+ clearTimeout(timer);
33
+ resolve(v);
34
+ }, (e) => {
35
+ clearTimeout(timer);
36
+ reject(e);
37
+ });
38
+ });
39
+ }
23
40
  export async function walletBalanceCommand() {
24
41
  const spinner = ora('Getting wallet balance...').start();
25
42
  // Kick off both calls in parallel. Relay earnings are loaded from
26
43
  // the clawmoney backend per-agent; the on-chain balance is awal's
27
- // native `balance` RPC. We don't block on-chain display if relay
28
- // fetching fails the on-chain balance is the authoritative "real
29
- // money" view.
44
+ // native `balance` RPC. Either half is allowed to fail — we print
45
+ // a dim "(unavailable)" note for that section and keep going.
30
46
  const config = loadConfig();
31
47
  const relayPromise = config?.api_key
32
48
  ? apiGet("/api/v1/relay/providers/me", config.api_key)
33
49
  .then((resp) => (resp.ok && Array.isArray(resp.data) ? resp.data : null))
34
50
  .catch(() => null)
35
51
  : Promise.resolve(null);
36
- let awalResult;
52
+ // 10s is generous — awal balance usually returns in 1-2s. Beyond
53
+ // that the wallet process is probably wedged and the user wants
54
+ // the rest of the output immediately.
55
+ let awalResult = null;
56
+ let awalError = null;
37
57
  try {
38
- awalResult = await awalExec(['balance']);
58
+ awalResult = await withTimeout(awalExec(['balance']), 10_000, 'awal balance');
39
59
  }
40
60
  catch (err) {
41
- spinner.fail('Failed to get wallet balance');
42
- console.error(chalk.red(err.message));
43
- return;
61
+ awalError = err.message;
44
62
  }
45
63
  const relayRows = await relayPromise;
46
- spinner.succeed('Wallet');
64
+ spinner.stop();
65
+ console.log('');
66
+ console.log(chalk.bold(' Wallet'));
47
67
  console.log('');
48
68
  console.log(chalk.bold(' On-chain (awal)'));
49
- const data = awalResult.data;
50
- if (typeof data === 'object' && data !== null) {
51
- for (const [key, value] of Object.entries(data)) {
52
- console.log(` ${chalk.dim(key + ':').padEnd(22)} ${chalk.green(String(value))}`);
69
+ if (awalResult) {
70
+ const data = awalResult.data;
71
+ if (typeof data === 'object' && data !== null && Object.keys(data).length > 0) {
72
+ for (const [key, value] of Object.entries(data)) {
73
+ console.log(` ${chalk.dim(key + ':').padEnd(22)} ${chalk.green(String(value))}`);
74
+ }
75
+ }
76
+ else {
77
+ console.log(` ${chalk.dim(awalResult.raw || '(empty)')}`);
53
78
  }
54
79
  }
55
80
  else {
56
- console.log(` ${awalResult.raw}`);
81
+ console.log(` ${chalk.yellow('unavailable')} ${chalk.dim('(' + (awalError ?? 'unknown error') + ')')}`);
82
+ console.log(chalk.dim(' Try: npx awal status | clawmoney wallet status'));
57
83
  }
84
+ console.log('');
85
+ console.log(chalk.bold(' Relay earnings'));
58
86
  if (relayRows && relayRows.length > 0) {
59
87
  const earned = relayRows.reduce((s, p) => s + (p.total_earned_usd ?? 0), 0);
60
88
  const withdrawn = relayRows.reduce((s, p) => s + (p.total_withdrawn_usd ?? 0), 0);
61
89
  const pending = Math.max(0, earned - withdrawn);
62
90
  const requests = relayRows.reduce((s, p) => s + (p.total_requests ?? 0), 0);
63
- console.log('');
64
- console.log(chalk.bold(' Relay earnings'));
65
91
  console.log(` ${chalk.dim('Earned:').padEnd(22)} ${chalk.green('$' + earned.toFixed(2))}`);
66
92
  console.log(` ${chalk.dim('Pending payout:').padEnd(22)} ${chalk.green('$' + pending.toFixed(2))}`);
67
93
  console.log(chalk.dim(` (${relayRows.length} provider${relayRows.length === 1 ? "" : "s"} · ${requests} request${requests === 1 ? "" : "s"} served)`));
68
94
  }
95
+ else if (relayRows && relayRows.length === 0) {
96
+ console.log(` ${chalk.dim('No providers registered yet. Run `clawmoney relay setup` to start earning.')}`);
97
+ }
98
+ else {
99
+ console.log(` ${chalk.yellow('unavailable')} ${chalk.dim('(relay backend unreachable)')}`);
100
+ }
69
101
  console.log('');
70
102
  }
71
103
  export async function walletAddressCommand() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmoney",
3
- "version": "0.15.36",
3
+ "version": "0.15.37",
4
4
  "description": "ClawMoney CLI -- Earn rewards with your AI agent",
5
5
  "type": "module",
6
6
  "bin": {