nansen-cli 1.8.0 → 1.9.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/SKILL.md CHANGED
@@ -1,136 +1,230 @@
1
1
  ---
2
2
  name: nansen-cli
3
- description: Query the Nansen API for onchain analytics - Smart Money flows, wallet profiling, token analysis, and DeFi portfolio data. Use when analyzing crypto wallets, tracking smart money activity, or researching tokens.
3
+ description: Nansen CLI for onchain analytics, smart money tracking, DEX trading, and perp markets.
4
4
  license: MIT
5
5
  metadata:
6
6
  author: nansen-ai
7
- version: "1.3.0"
8
- compatibility: Requires Node.js 18+. Needs NANSEN_API_KEY environment variable or run `nansen login`.
7
+ version: "1.8.0"
8
+ repository: https://github.com/nansen-ai/nansen-cli
9
+ compatibility: Node.js 18+. Works with Claude Code, Codex, Cursor, Windsurf, and any terminal-native agent.
9
10
  ---
10
11
 
11
12
  # Nansen CLI
12
13
 
13
- Command-line interface for the [Nansen API](https://docs.nansen.ai) - onchain analytics for crypto investors and AI agents.
14
+ Onchain analytics and DEX trading for AI agents.
14
15
 
15
- ## CLI vs Direct API
16
+ ## Quick Reference
16
17
 
17
- If your agent has HTTP access (curl, fetch), you can skip the CLI and hit the [Nansen REST API](https://docs.nansen.ai) directly with `apiKey` header auth. The CLI is most useful for terminal-native agents (Claude Code, Codex, Cursor) that benefit from `--pretty`, `--table`, `--fields`, built-in retries, and schema introspection.
18
+ ```bash
19
+ # Search for any token, wallet, or entity
20
+ nansen research search "jupiter" --type token
21
+
22
+ # Token price (OHLCV)
23
+ nansen research token ohlcv --token <addr> --chain solana --timeframe 1h --limit 24
24
+
25
+ # Smart Money — what are the pros buying?
26
+ nansen research smart-money netflow --chain solana --limit 10
27
+
28
+ # Token screener — trending tokens
29
+ nansen research token screener --chain solana --timeframe 24h --smart-money --limit 20
30
+
31
+ # Trade — quote then execute
32
+ nansen trade quote --chain solana --from <from_token_address> --to <to_token_address> --amount <base_units>
33
+ nansen trade execute --quote <quote-id>
34
+
35
+ # Create a wallet
36
+ nansen wallet create # interactive
37
+ NANSEN_WALLET_PASSWORD="pass" nansen wallet create # non-interactive
38
+
39
+ # Discover all commands, options, and return fields
40
+ nansen schema
41
+ ```
18
42
 
19
43
  ## Setup
20
44
 
21
45
  ```bash
22
- # Install globally
23
46
  npm install -g nansen-cli
47
+ ```
24
48
 
25
- # Authenticate pick the method that works for your context:
49
+ ### Auth (pick one)
26
50
 
27
- # Option A: Non-interactive (best for agents — no prompts, no wasted credits)
28
- mkdir -p ~/.nansen && echo '{"apiKey":"YOUR_KEY","baseUrl":"https://api.nansen.ai"}' > ~/.nansen/config.json && chmod 600 ~/.nansen/config.json
51
+ **x402 Pay-Per-Call (no API key needed):**
29
52
 
30
- # Option B: Environment variable (good for CI/scripts)
31
- export NANSEN_API_KEY=your-api-key
53
+ ```bash
54
+ nansen wallet create # Generates EVM + Solana keypair
55
+ # Fund the EVM address with USDC on Base (~$0.50 minimum)
56
+ export NANSEN_WALLET_PASSWORD="your-password" # Skip interactive prompt
57
+ # Done — CLI auto-pays $0.01-$0.05 per call
58
+ ```
59
+
60
+ **API Key:**
32
61
 
33
- # Option C: Interactive login (burns 1 credit to validate)
34
- nansen login
62
+ ```bash
63
+ export NANSEN_API_KEY=your-api-key
64
+ # Or: nansen login --api-key YOUR_KEY
35
65
  ```
36
66
 
37
- Get your API key at [app.nansen.ai/api](https://app.nansen.ai/api).
67
+ Get a key at [app.nansen.ai/api](https://app.nansen.ai/api).
38
68
 
39
- ### Verify Installation
69
+ ## Smart Money
40
70
 
41
71
  ```bash
42
- # Free check (no API key needed):
43
- nansen schema | head -1
72
+ nansen research smart-money netflow --chain solana --limit 10
73
+ nansen research smart-money dex-trades --chain solana --labels "Smart Trader" --limit 20
74
+ nansen research smart-money holdings --chain solana --limit 10
75
+ nansen research smart-money perp-trades --limit 10 # no --chain (Hyperliquid only)
76
+ nansen research smart-money dcas --limit 10 # no --chain (Jupiter/Solana only)
77
+ nansen research smart-money historical-holdings --chain solana --token-address <addr>
78
+ ```
44
79
 
45
- # Full check (uses 1 credit):
46
- nansen token screener --chain solana --limit 1
80
+ Labels: `Fund`, `Smart Trader`, `30D Smart Trader`, `90D Smart Trader`, `180D Smart Trader`, `Smart HL Perps Trader`
81
+
82
+ ## Token Analytics
83
+
84
+ `--chain` required. Use `--token` for the token address.
85
+
86
+ ```bash
87
+ nansen research token screener --chain solana --timeframe 24h --smart-money --limit 20
88
+ nansen research token info --token <addr> --chain solana
89
+ nansen research token indicators --token <addr> --chain solana
90
+ nansen research token ohlcv --token <addr> --chain solana --timeframe 1h --limit 24
91
+ nansen research token holders --token <addr> --chain solana --smart-money
92
+ nansen research token flows --token <addr> --chain solana --days 7
93
+ nansen research token flow-intelligence --token <addr> --chain solana
94
+ nansen research token who-bought-sold --token <addr> --chain solana
95
+ nansen research token dex-trades --token <addr> --chain solana --limit 20
96
+ nansen research token pnl --token <addr> --chain solana --sort total_pnl_usd:desc
97
+ nansen research token transfers --token <addr> --chain solana --enrich
98
+ nansen research token jup-dca --token <addr> # no --chain
99
+ nansen research token perp-trades --symbol ETH --days 7 # no --chain, uses --symbol
100
+ nansen research token perp-positions --symbol BTC # no --chain
101
+ nansen research token perp-pnl-leaderboard --symbol SOL # no --chain
47
102
  ```
48
103
 
49
- ## Commands
104
+ Native tokens (SOL, ETH) are not supported on most token endpoints — use specific token addresses.
105
+
106
+ ## Wallet Profiler
107
+
108
+ `--chain` and `--address` required for most commands.
50
109
 
51
- ### Smart Money
52
- Track sophisticated market participants:
53
110
  ```bash
54
- nansen smart-money netflow --chain solana --pretty
55
- nansen smart-money dex-trades --chain solana --labels "Smart Trader"
56
- nansen smart-money holdings --chain solana
111
+ nansen research profiler balance --address <addr> --chain solana
112
+ nansen research profiler labels --address <addr> --chain ethereum
113
+ nansen research profiler pnl --address <addr> --chain ethereum --days 30
114
+ nansen research profiler pnl-summary --address <addr> --chain ethereum
115
+ nansen research profiler transactions --address <addr> --chain ethereum --limit 20
116
+ nansen research profiler historical-balances --address <addr> --chain solana --days 30
117
+ nansen research profiler related-wallets --address <addr> --chain ethereum
118
+ nansen research profiler counterparties --address <addr> --chain ethereum
119
+ nansen research profiler perp-positions --address <addr> # no --chain
120
+ nansen research profiler perp-trades --address <addr> # no --chain
121
+ nansen research profiler search --query "Vitalik" # no --chain
122
+ nansen research profiler batch --addresses "0xabc,0xdef" --chain ethereum --include labels,balance,pnl
123
+ nansen research profiler trace --address <addr> --chain ethereum --depth 2 --width 10 # ⚠️ makes N×width API calls
124
+ nansen research profiler compare --addresses "0xabc,0xdef" --chain ethereum
57
125
  ```
58
126
 
59
- ### Wallet Profiler
60
- Analyze any wallet:
127
+ ## Search
128
+
61
129
  ```bash
62
- nansen profiler balance --address 0x123... --chain ethereum
63
- nansen profiler labels --address 0x123... --chain ethereum
64
- nansen profiler pnl --address 0x123... --chain ethereum
65
- nansen profiler search --query "Vitalik"
130
+ nansen research search "jupiter" --type token
131
+ nansen research search "Vitalik" --type entity --limit 5
132
+ nansen research search "0xd8dA..." # by address
66
133
  ```
67
134
 
68
- ### Token God Mode
69
- Deep token analytics:
135
+ ## Perps (Hyperliquid)
136
+
70
137
  ```bash
71
- nansen token screener --chain solana --timeframe 24h
72
- nansen token holders --token <address> --chain solana --smart-money
73
- nansen token flows --token <address> --chain solana
74
- nansen token pnl --token <address> --chain solana
138
+ nansen research perp screener --sort volume_usd:desc --limit 20
139
+ nansen research perp leaderboard --days 7 --limit 20
75
140
  ```
76
141
 
77
- ### Portfolio
78
- DeFi holdings analysis:
142
+ ## Portfolio
143
+
79
144
  ```bash
80
- nansen portfolio defi --wallet 0x123...
145
+ nansen research portfolio defi --wallet <addr>
146
+ nansen research points leaderboard --tier green --limit 20
81
147
  ```
82
148
 
83
- ## Output Formats
149
+ ## Trading
84
150
 
85
- - **Default**: JSON (for AI agents)
86
- - `--pretty`: Formatted JSON
87
- - `--table`: Human-readable table
88
- - `--stream`: NDJSON (one record per line)
89
- - `--fields`: Filter specific fields
151
+ Two-step: quote then execute.
90
152
 
91
- ## Key Options
153
+ ```bash
154
+ # Get quotes from multiple aggregators (Jupiter, OKX, LiFi)
155
+ nansen trade quote --chain solana \
156
+ --from <from_token_address> \
157
+ --to <to_token_address> \
158
+ --amount <base_units>
159
+
160
+ # Execute the best quote
161
+ nansen trade execute --quote <quote-id>
162
+ ```
92
163
 
93
- | Option | Description |
94
- |--------|-------------|
95
- | `--chain` | Blockchain (solana, ethereum, base, etc.) |
96
- | `--chains` | Multiple chains as JSON array |
97
- | `--limit` | Number of results |
98
- | `--days` | Date range in days |
99
- | `--sort` | Sort field (e.g., `value_usd:desc`) |
100
- | `--smart-money` | Filter for Smart Money only |
164
+ > ⚠️ Always inspect the quote response (price, slippage, expiry) before executing.
165
+ > Quotes expire — if you wait too long, execute will fail. Get a fresh quote and retry.
166
+ > Trades are irreversible once executed on-chain.
101
167
 
102
- ## Supported Chains
168
+ **⚠️ Amounts are in base units (not human-readable):**
103
169
 
104
- ethereum, solana, base, bnb, arbitrum, polygon, optimism, avalanche, linea, scroll, mantle, ronin, sei, plasma, sonic, monad, hyperevm, iotaevm
170
+ | Token | Decimals | 1 unit = |
171
+ |-------|----------|----------|
172
+ | SOL | 9 | 1000000000 lamports |
173
+ | ETH | 18 | 1000000000000000000 wei |
174
+ | USDC | 6 | 1000000 |
105
175
 
106
- ## Smart Money Labels
176
+ Symbol shortcuts (SOL, ETH) don't work yet — use full addresses.
107
177
 
108
- Fund, Smart Trader, 30D Smart Trader, 90D Smart Trader, 180D Smart Trader, Smart HL Perps Trader
178
+ ### Common Addresses
109
179
 
110
- ## Schema Introspection
180
+ **Solana:** SOL `So11111111111111111111111111111111111111112` · USDC `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` · JUP `JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN`
181
+
182
+ **Base:** ETH `0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee` · USDC `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` · DEGEN `0x4ed4e862860bed51a9570b96d89af5e1b0efefed`
183
+
184
+ ## Wallet Management
111
185
 
112
- Get the full API schema for programmatic use:
113
186
  ```bash
114
- nansen schema --pretty
115
- nansen schema smart-money --pretty
187
+ nansen wallet create # Create EVM + Solana keypair
188
+ nansen wallet list # List wallets
189
+ nansen wallet send --to <addr> --amount 1.5 --chain evm # Send native
190
+ nansen wallet send --to <addr> --chain evm --max # Send entire balance
116
191
  ```
117
192
 
118
- ## Troubleshooting
193
+ ## Common Options
119
194
 
120
- See [AGENTS.md Troubleshooting](AGENTS.md#troubleshooting) for the full troubleshooting guide, including error codes, known endpoint quirks, and pagination gotchas.
195
+ | Option | Description |
196
+ |--------|-------------|
197
+ | `--chain` | Required for most commands. See [Supported Chains](#supported-chains) |
198
+ | `--token` | Token address (aliases: `--mint`, `--token-address`) |
199
+ | `--address` | Wallet address |
200
+ | `--limit` | Results per page (default 10) |
201
+ | `--days` | Lookback period in days (default 30) |
202
+ | `--sort` | Sort field:direction (e.g. `value_usd:desc`) |
203
+ | `--smart-money` | Filter to smart money wallets only |
204
+ | `--pretty` | Formatted JSON output |
205
+ | `--table` | ASCII table output |
206
+ | `--stream` | NDJSON (one record per line) |
207
+ | `--fields a,b` | Return only specific fields |
208
+ | `--cache` | Cache responses (300s TTL). **Do not use with `trade` commands** — stale prices/quotes can cause bad trades |
209
+
210
+ ## Schema Introspection
121
211
 
122
- ## Examples
212
+ > **Stuck?** Run `nansen schema` or `nansen schema <command>` to discover all available commands, options, and return fields.
123
213
 
124
214
  ```bash
125
- # Find trending Solana tokens with Smart Money activity
126
- nansen token screener --chain solana --timeframe 24h --smart-money --pretty
215
+ nansen schema # Full JSON schema all commands, options, return fields
216
+ ```
127
217
 
128
- # Check who's accumulating a specific token
129
- nansen token holders --token So11111111111111111111111111111111111111112 --chain solana --smart-money --limit 20 --pretty
218
+ ## Supported Chains
130
219
 
131
- # Profile a whale wallet
132
- nansen profiler balance --address Gu29tjXrVr9v5n42sX1DNrMiF3BwbrTm379szgB9qXjc --chain solana --pretty
220
+ **Research:** `solana`, `ethereum`, `base`, `bnb`, `arbitrum`, `polygon`, `optimism`, `avalanche`, `linea`, `scroll`, `mantle`, `ronin`, `sei`, `plasma`, `sonic`, `monad`, `hyperevm`, `iotaevm`
133
221
 
134
- # Track Smart Money flows into memecoins
135
- nansen smart-money netflow --chain solana --labels "Smart Trader" --pretty
136
- ```
222
+ **Trading & x402:** `solana`, `base`
223
+
224
+ ## Gotchas
225
+
226
+ - Native tokens (SOL, ETH) don't work on most token endpoints — use wrapped addresses
227
+ - Perp commands don't take `--chain` (Hyperliquid only)
228
+ - `--amount` is always in base units, not human-readable
229
+ - Profiler `trace` makes N×width API calls — can burn credits fast
230
+ - x402 auth needs USDC on Base, not Solana
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nansen-cli",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "Command-line interface for Nansen API - designed for AI agents",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/api.js CHANGED
@@ -505,8 +505,11 @@ export class NansenAPI {
505
505
  } else if (code === ErrorCode.CREDITS_EXHAUSTED) {
506
506
  message = message.replace(/\.+$/, '') + '. No retry will help. Check your Nansen dashboard for credit balance.';
507
507
  } else if (code === ErrorCode.PAYMENT_REQUIRED) {
508
- // Try x402 auto-payment with fallback across payment networks
509
- if (!this.defaultHeaders['Payment-Signature']) {
508
+ // Try x402 auto-payment: local wallet (with network fallback), then WalletConnect
509
+ const hasManualSignature = !!(this.defaultHeaders['Payment-Signature'] || options.headers?.['Payment-Signature']);
510
+
511
+ if (!hasManualSignature) {
512
+ // 1. Try local wallet with fallback across payment networks
510
513
  try {
511
514
  const { createPaymentSignatures } = await import('./x402.js');
512
515
  for await (const { signature, network } of createPaymentSignatures(response, url)) {
@@ -537,17 +540,54 @@ export class NansenAPI {
537
540
  }
538
541
  // This payment option was rejected, try next
539
542
  }
540
- } catch { /* x402 auto-pay unavailable, fall through */ }
541
- }
542
- message = 'Payment required. To access this endpoint:\n • Set an API key: nansen login --api-key <key> (get one at https://app.nansen.ai/api)\n • Or pay per call: nansen wallet create, fund with USDC on Base or Solana (from $0.01/call, min $0.05 balance)\n • Docs: https://docs.x402.org';
543
- const paymentHeader = response.headers.get('payment-required');
544
- if (paymentHeader) {
545
- try {
546
- data.paymentRequirements = JSON.parse(atob(paymentHeader));
547
- } catch {
548
- data.paymentRequiredRaw = paymentHeader;
543
+ } catch { /* local wallet unavailable, try WalletConnect */ }
544
+
545
+ // 2. Fall back to WalletConnect (walletconnect-x402.js)
546
+ // (local wallet returns early on success above, so we always reach here if it failed)
547
+ {
548
+ let paymentRequirements;
549
+ const paymentHeader = response.headers.get('payment-required');
550
+ if (paymentHeader) {
551
+ try {
552
+ paymentRequirements = JSON.parse(atob(paymentHeader));
553
+ } catch {
554
+ data.paymentRequiredRaw = paymentHeader;
555
+ }
556
+ }
557
+ if (!paymentRequirements && data.paymentRequirements) {
558
+ paymentRequirements = data.paymentRequirements;
559
+ }
560
+
561
+ if (paymentRequirements) {
562
+ try {
563
+ const { handleX402Payment } = await import('./walletconnect-x402.js');
564
+ const paymentSignature = await handleX402Payment(paymentRequirements);
565
+ const paidResponse = await fetch(url, {
566
+ method: 'POST',
567
+ headers: {
568
+ 'Content-Type': 'application/json',
569
+ 'X-Client-Type': 'nansen-cli',
570
+ 'X-Client-Version': packageVersion,
571
+ 'Payment-Signature': paymentSignature,
572
+ ...this.defaultHeaders,
573
+ ...options.headers,
574
+ },
575
+ body: JSON.stringify(NansenAPI.cleanBody(body)),
576
+ });
577
+ if (paidResponse.ok) {
578
+ return await paidResponse.json();
579
+ }
580
+ } catch (x402Err) {
581
+ message = `x402 auto-payment failed: ${x402Err.message}`;
582
+ }
583
+ data.paymentRequirements = paymentRequirements;
584
+ }
549
585
  }
550
586
  }
587
+
588
+ if (!message || message === data.message) {
589
+ message = 'Payment required (x402). Sign the paymentRequirements below per https://docs.x402.org and pass the result with --x402-payment-signature <value>.';
590
+ }
551
591
  }
552
592
 
553
593
  lastError = new NansenError(message, code, response.status, {
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Canonical EVM chain name → numeric chain ID mapping.
3
+ *
4
+ * Single source of truth — import from here instead of defining inline.
5
+ */
6
+
7
+ export const EVM_CHAIN_IDS = {
8
+ ethereum: 1,
9
+ base: 8453,
10
+ optimism: 10,
11
+ arbitrum: 42161,
12
+ polygon: 137,
13
+ avalanche: 43114,
14
+ bnb: 56,
15
+ linea: 59144,
16
+ scroll: 534352,
17
+ zksync: 324,
18
+ mantle: 5000,
19
+ };
package/src/cli.js CHANGED
@@ -144,14 +144,15 @@ export const SCHEMA = {
144
144
  chain: { type: 'string', default: 'ethereum', description: 'Blockchain' },
145
145
  from: { type: 'string', required: true, description: 'Token to sell (address or symbol)' },
146
146
  to: { type: 'string', required: true, description: 'Token to buy (address or symbol)' },
147
- amount: { type: 'string', required: true, description: 'Amount to swap' }
147
+ amount: { type: 'string', required: true, description: 'Amount to swap' },
148
+ wallet: { type: 'string', description: 'Wallet name, or "walletconnect"/"wc" for WalletConnect (EVM only)' }
148
149
  }
149
150
  },
150
151
  'execute': {
151
152
  description: 'Sign and broadcast a quoted trade',
152
153
  options: {
153
154
  chain: { type: 'string', default: 'ethereum', description: 'Blockchain' },
154
- wallet: { type: 'string', description: 'Wallet name or address' }
155
+ wallet: { type: 'string', description: 'Wallet name, or "walletconnect"/"wc" for WalletConnect (EVM only)' }
155
156
  }
156
157
  }
157
158
  }
@@ -838,6 +839,7 @@ export function buildCommands(deps = {}) {
838
839
  api = null,
839
840
  promptFn = prompt,
840
841
  log = console.log,
842
+ errorOutput = console.error,
841
843
  NansenAPIClass = NansenAPI,
842
844
  saveConfigFn = saveConfig,
843
845
  deleteConfigFn = deleteConfig,
@@ -905,7 +907,7 @@ export function buildCommands(deps = {}) {
905
907
  try {
906
908
  content = fs.readFileSync(changelogPath, 'utf8');
907
909
  } catch {
908
- errorOutput('CHANGELOG.md not found. Visit https://github.com/nansen-ai/nansen-cli/blob/main/CHANGELOG.md');
910
+ log('CHANGELOG.md not found. Visit https://github.com/nansen-ai/nansen-cli/blob/main/CHANGELOG.md');
909
911
  return;
910
912
  }
911
913
  const since = options.since;
@@ -1307,14 +1309,31 @@ export function buildCommands(deps = {}) {
1307
1309
  cmds['trade'] = async (args, apiInstance, flags, options) => {
1308
1310
  const sub = args[0];
1309
1311
  if (!sub || sub === 'help') {
1310
- return {
1311
- commands: ['quote', 'execute'],
1312
- description: 'DEX trading commands',
1313
- example: 'nansen trade quote --chain ethereum --from ETH --to USDC --amount 1'
1314
- };
1312
+ log(`nansen trade — DEX trading commands
1313
+
1314
+ SUBCOMMANDS:
1315
+ quote Get a swap quote (price, route, fees)
1316
+ execute Sign and broadcast a quoted swap
1317
+
1318
+ USAGE:
1319
+ nansen trade quote --chain <chain> --from <token> --to <token> --amount <units>
1320
+ nansen trade execute --quote <quoteId>
1321
+
1322
+ EXAMPLES:
1323
+ nansen trade quote --chain solana --from SOL --to USDC --amount 1000000000
1324
+ nansen trade quote --chain base --from ETH --to USDC --amount 1000000000000000000
1325
+ nansen trade execute --quote 1708900000000-abc123
1326
+
1327
+ SYMBOLS:
1328
+ Common tokens resolve automatically: SOL, ETH, BNB, USDC, USDT, WETH, WBNB
1329
+ Raw addresses are also accepted.`);
1330
+ return;
1315
1331
  }
1316
1332
  if (!tradingCmds[sub]) {
1317
- return { error: `Unknown trade subcommand: ${sub}`, available: ['quote', 'execute'] };
1333
+ log(`Unknown trade subcommand: ${sub}`);
1334
+ log(`Available: quote, execute`);
1335
+ log(`Run 'nansen trade help' for usage.`);
1336
+ return;
1318
1337
  }
1319
1338
  return tradingCmds[sub](args.slice(1), apiInstance, flags, options);
1320
1339
  };