alpha-cli-toolkit 1.0.0 → 1.2.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/bin/alpha.js CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ require('dotenv').config();
2
3
  const { Command } = require('commander');
3
4
  const chalk = require('chalk');
4
5
  const gradient = require('gradient-string');
@@ -6,7 +7,7 @@ const Table = require('cli-table3');
6
7
  const { authenticateViaBrowser, getToken, clearToken } = require('../utils/auth');
7
8
 
8
9
  const program = new Command();
9
- const BACKEND_URL = process.env.ALPHA_BACKEND_URL || 'http://localhost:4000/api';
10
+ const BACKEND_URL = process.env.ALPHA_BACKEND_URL;
10
11
 
11
12
  program
12
13
  .name('alpha')
@@ -70,11 +71,12 @@ program
70
71
  }
71
72
 
72
73
  // Backend health
74
+ const healthUrl = BACKEND_URL ? `${BACKEND_URL.replace(/\/api$/, '')}/health` : 'http://localhost:4000/health';
73
75
  try {
74
- const { data } = await axios.get(`http://localhost:4000/health`, { timeout: 3000 });
76
+ const { data } = await axios.get(healthUrl, { timeout: 3000 });
75
77
  console.log(chalk.green(' ✅ Backend online') + chalk.grey(` (${data.timestamp})`));
76
78
  } catch {
77
- console.log(chalk.red(' ❌ Backend offline') + chalk.grey(' — start it with `npm run dev` in /backend'));
79
+ console.log(chalk.red(' ❌ Backend offline') + chalk.grey(`check your BACKEND_URL or start it with \`npm run dev\` in /backend`));
78
80
  }
79
81
 
80
82
  console.log('');
@@ -107,6 +109,8 @@ program
107
109
  .option('-c, --crypto', 'Trending crypto from Nansen (default)')
108
110
  .option('-s, --sp500', 'Trending S&P 500 assets via Yahoo Finance')
109
111
  .option('-n, --nsd', 'Trending NASDAQ assets via Yahoo Finance')
112
+ .option('-f, --nft', 'NFT Market Indexes (Nansen)')
113
+ .option('-m, --macro', 'Smart Money Holdings \u0026 Macro (Nansen)')
110
114
  .action(async (options) => {
111
115
  const token = checkAuth();
112
116
  const axios = require('axios');
@@ -116,6 +120,23 @@ program
116
120
 
117
121
  if (options.sp500) { url = `${BACKEND_URL}/market/tradfi/sp500`; cType = 'S&P 500'; }
118
122
  else if (options.nsd) { url = `${BACKEND_URL}/market/tradfi/nsd`; cType = 'NASDAQ'; }
123
+ else if (options.nft || options.macro) {
124
+ console.log(chalk.cyan(`\n🔍 Fetching Nansen Market Macro Insights...`));
125
+ try {
126
+ const { data } = await axios.get(`${BACKEND_URL}/market/macro`, { headers: authHeaders(token) });
127
+ if (options.nft) {
128
+ console.log(gradient.atlas(`\n─── Nansen NFT Indexes ──────────────────────────`));
129
+ console.log(JSON.stringify(data.nftIndexes, null, 2));
130
+ } else {
131
+ console.log(gradient.atlas(`\n─── Smart Money Holdings ─────────────────────────`));
132
+ console.log(JSON.stringify(data.smartMoneyHoldings, null, 2));
133
+ }
134
+ return;
135
+ } catch (err) {
136
+ console.error(chalk.red('Macro fetch failed:'), err.response?.data?.error || err.message);
137
+ return;
138
+ }
139
+ }
119
140
 
120
141
  console.log(chalk.cyan(`\n🔍 Fetching ${cType} market data...`));
121
142
 
@@ -169,6 +190,48 @@ program
169
190
  }
170
191
  });
171
192
 
193
+ // ─────────────────────────────────────────────────────────────────────────────
194
+ // WALLET COMMAND
195
+ // ─────────────────────────────────────────────────────────────────────────────
196
+ program
197
+ .command('wallet <address>')
198
+ .description('Deep dive into a wallet using Nansen Profiler \u0026 Balances')
199
+ .action(async (address) => {
200
+ const token = checkAuth();
201
+ const axios = require('axios');
202
+
203
+ console.log(chalk.cyan(`\n🔍 Profiling wallet: ${chalk.bold(address)}...`));
204
+
205
+ try {
206
+ const { data } = await axios.get(`${BACKEND_URL}/market/wallet/${address}`, { headers: authHeaders(token) });
207
+ console.log(gradient.atlas(`\n─── Nansen Wallet Insights ──────────────────────`));
208
+ console.log(JSON.stringify(data, null, 2));
209
+ } catch (err) {
210
+ console.error(chalk.red('Wallet profiling failed:'), err.response?.data?.error || err.message);
211
+ }
212
+ });
213
+
214
+ // ─────────────────────────────────────────────────────────────────────────────
215
+ // ENTITY COMMAND
216
+ // ─────────────────────────────────────────────────────────────────────────────
217
+ program
218
+ .command('entity <name>')
219
+ .description('Track token flows for a specific entity (e.g., Binance, Alameda)')
220
+ .action(async (name) => {
221
+ const token = checkAuth();
222
+ const axios = require('axios');
223
+
224
+ console.log(chalk.cyan(`\n🔍 Tracking entity flows: ${chalk.bold(name)}...`));
225
+
226
+ try {
227
+ const { data } = await axios.get(`${BACKEND_URL}/market/entities/${name}`, { headers: authHeaders(token) });
228
+ console.log(gradient.atlas(`\n─── Nansen Entity Flows: ${name.toUpperCase()} ───`));
229
+ console.log(JSON.stringify(data.flows, null, 2));
230
+ } catch (err) {
231
+ console.error(chalk.red('Entity tracking failed:'), err.response?.data?.error || err.message);
232
+ }
233
+ });
234
+
172
235
  program
173
236
  .command('positions')
174
237
  .description('View your simulated portfolio and open positions')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alpha-cli-toolkit",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Autonomous Agent Toolkit for Crypto & TradFi market data powered by Nansen.",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/utils/auth.js CHANGED
@@ -44,10 +44,6 @@ function setToken(token) {
44
44
 
45
45
  // ─── Browser-based Phantom auth flow ─────────────────────────────────────────
46
46
 
47
- /**
48
- * Spins up a local temporary server and opens the Next.js UI
49
- * to capture the Phantom wallet authentication token.
50
- */
51
47
  async function authenticateViaBrowser() {
52
48
  return new Promise(async (resolve, reject) => {
53
49
  const server = http.createServer((req, res) => {
@@ -82,9 +78,9 @@ async function authenticateViaBrowser() {
82
78
  });
83
79
 
84
80
  server.listen(0, async () => {
81
+ const FRONTEND_URL = process.env.FRONTEND_URL || 'https://alpha-cli-ui.vercel.app';
85
82
  const port = server.address().port;
86
- const callbackUrl = `http://localhost:${port}`;
87
- const loginUrl = `http://localhost:3000/?callback=${encodeURIComponent(callbackUrl)}`;
83
+ const loginUrl = `${FRONTEND_URL}/?callback=${encodeURIComponent(`http://localhost:${port}`)}`;
88
84
 
89
85
  // Dynamic import for `open` (ESM-only since v9)
90
86
  const open = (await import('open')).default;