nansen-cli 1.7.0 → 1.8.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/README.md CHANGED
@@ -2,8 +2,7 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/nansen-cli.svg)](https://www.npmjs.com/package/nansen-cli)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![Tests](https://img.shields.io/badge/tests-325%20passing-brightgreen.svg)]()
6
- [![Coverage](https://img.shields.io/badge/coverage-83%25-brightgreen.svg)]()
5
+ [![Tests](https://img.shields.io/badge/tests-577%20passing-brightgreen.svg)]()
7
6
 
8
7
  > **Built by agents, for agents.** We prioritize the best possible AI agent experience.
9
8
 
@@ -47,32 +46,63 @@ nansen login
47
46
  # ✓ Saved to ~/.nansen/config.json
48
47
  ```
49
48
 
50
- **Option 2: Environment variable**
49
+ **Option 2: Environment variable (best for agents)**
51
50
  ```bash
52
51
  export NANSEN_API_KEY=your-api-key
53
52
  ```
54
53
 
54
+ **Option 3: Direct config file**
55
+ ```bash
56
+ mkdir -p ~/.nansen && echo '{"apiKey":"<key>","baseUrl":"https://api.nansen.ai"}' > ~/.nansen/config.json && chmod 600 ~/.nansen/config.json
57
+ ```
58
+
55
59
  Get your API key at [app.nansen.ai/api](https://app.nansen.ai/api).
56
60
 
61
+ ### Auth Priority
62
+
63
+ 1. `NANSEN_API_KEY` env var (highest)
64
+ 2. `~/.nansen/config.json` file
65
+ 3. Interactive prompt
66
+
67
+ ### Verify It Works
68
+
69
+ ```bash
70
+ # Check CLI is installed (no API key needed):
71
+ nansen schema | head -1
72
+
73
+ # Verify API access:
74
+ nansen research token screener --chain solana --limit 1
75
+ ```
76
+
57
77
  ## Quick Start
58
78
 
59
79
  ```bash
60
80
  # Get trending tokens on Solana
61
- nansen token screener --chain solana --timeframe 24h --pretty
81
+ nansen research token screener --chain solana --timeframe 24h --pretty
62
82
 
63
83
  # Check Smart Money activity
64
- nansen smart-money netflow --chain solana --pretty
84
+ nansen research smart-money netflow --chain solana --pretty
65
85
 
66
86
  # Profile a wallet
67
- nansen profiler balance --address 0x28c6c06298d514db089934071355e5743bf21d60 --chain ethereum --pretty
87
+ nansen research profiler balance --address 0x28c6c06298d514db089934071355e5743bf21d60 --chain ethereum --pretty
68
88
 
69
- # Search for an entity
70
- nansen profiler search --query "Vitalik Buterin" --pretty
89
+ # Search for tokens/entities
90
+ nansen research search "Vitalik Buterin" --pretty
71
91
  ```
72
92
 
73
93
  ## Commands
74
94
 
75
- ### `smart-money` - Smart Money Analytics
95
+ All analytics live under `nansen research`, trading under `nansen trade`, and wallet management under `nansen wallet`.
96
+
97
+ ### `research` - Research & Analytics
98
+
99
+ ```
100
+ nansen research <category> <subcommand> [options]
101
+ ```
102
+
103
+ **Category aliases:** `sm` (smart-money), `tgm` (token), `prof` (profiler), `port` (portfolio)
104
+
105
+ #### `research smart-money` - Smart Money Analytics
76
106
 
77
107
  Track trading and holding activity of sophisticated market participants.
78
108
 
@@ -85,17 +115,19 @@ Track trading and holding activity of sophisticated market participants.
85
115
  | `dcas` | DCA strategies on Jupiter |
86
116
  | `historical-holdings` | Historical holdings over time |
87
117
 
88
- **Smart Money Labels:**
89
- - `Fund` - Institutional investment funds
90
- - `Smart Trader` - Historically profitable traders
91
- - `30D Smart Trader` - Top performers (30-day window)
92
- - `90D Smart Trader` - Top performers (90-day window)
93
- - `180D Smart Trader` - Top performers (180-day window)
94
- - `Smart HL Perps Trader` - Profitable Hyperliquid traders
118
+ **Smart Money Labels:** `Fund`, `Smart Trader`, `30D Smart Trader`, `90D Smart Trader`, `180D Smart Trader`, `Smart HL Perps Trader`
119
+
120
+ #### `research profiler` - Wallet Profiling
95
121
 
96
- ### `profiler` - Wallet Profiling
122
+ **ENS Name Resolution:** You can use `.eth` names anywhere an `--address` is accepted:
97
123
 
98
- Detailed information about any blockchain address.
124
+ ```bash
125
+ nansen research profiler balance --address vitalik.eth
126
+ nansen research profiler labels --address nansen.eth --chain ethereum
127
+ nansen research profiler transactions --address vitalik.eth --table
128
+ ```
129
+
130
+ ENS names are automatically resolved to `0x` addresses via public APIs (with onchain RPC fallback). Works on all EVM chains. The resolved name and address are included as `_ens` metadata in JSON output.
99
131
 
100
132
  | Subcommand | Description |
101
133
  |------------|-------------|
@@ -111,9 +143,7 @@ Detailed information about any blockchain address.
111
143
  | `perp-positions` | Current perpetual positions |
112
144
  | `perp-trades` | Perpetual trading history |
113
145
 
114
- ### `token` - Token God Mode
115
-
116
- Deep analytics for any token.
146
+ #### `research token` - Token God Mode
117
147
 
118
148
  | Subcommand | Description |
119
149
  |------------|-------------|
@@ -126,53 +156,51 @@ Deep analytics for any token.
126
156
  | `flow-intelligence` | Detailed flow intelligence by label |
127
157
  | `transfers` | Token transfer history |
128
158
  | `jup-dca` | Jupiter DCA orders for token |
159
+ | `ohlcv` | OHLCV candle data for a token |
129
160
  | `perp-trades` | Perp trades by token symbol |
130
161
  | `perp-positions` | Open perp positions by token symbol |
131
162
  | `perp-pnl-leaderboard` | Perp PnL leaderboard by token |
132
163
 
133
- ### `portfolio` - Portfolio Analytics
134
-
135
- | Subcommand | Description |
136
- |------------|-------------|
137
- | `defi` | DeFi holdings across protocols |
164
+ #### `research search` / `research perp` / `research portfolio` / `research points`
138
165
 
139
- ### `search` - Search
166
+ See `nansen research help` or `nansen schema --pretty` for full details.
140
167
 
141
- Search for tokens and entities across Nansen.
168
+ ### `trade` - DEX Trading
142
169
 
143
170
  ```bash
144
- nansen search "uniswap" --pretty
145
- nansen search "uniswap" --type token --chain ethereum
171
+ # Get a swap quote
172
+ nansen trade quote --from USDC --to SOL --amount 10 --chain solana
173
+
174
+ # Execute the swap
175
+ nansen trade execute --from USDC --to SOL --amount 10 --chain solana
146
176
  ```
147
177
 
148
- | Option | Description |
149
- |--------|-------------|
150
- | `--type` | Filter by result type: `token`, `entity`, or `any` (default) |
151
- | `--chain` | Filter by chain |
152
- | `--limit` | Max results, 1-50 (default: 25) |
178
+ ### `wallet` - Local Wallet Management
179
+
180
+ | Subcommand | Description |
181
+ |------------|-------------|
182
+ | `create` | Create a new wallet (EVM + Solana keypair) |
183
+ | `list` | List all wallets |
184
+ | `show` | Show wallet addresses |
185
+ | `export` | Export private keys |
186
+ | `default` | Set default wallet |
187
+ | `delete` | Delete a wallet |
188
+ | `send` | Send tokens (native or ERC-20/SPL) |
189
+
190
+ Wallets are passwordless by default (keys stored like SSH keys). Set `NANSEN_WALLET_PASSWORD` env var for encryption at rest.
153
191
 
154
192
  ### `schema` - Schema Discovery
155
193
 
156
- Output JSON schema for agent introspection. No API key required.
194
+ No API key required. Machine-readable command reference for agent introspection.
157
195
 
158
196
  ```bash
159
- # Get full schema
160
- nansen schema --pretty
161
-
162
- # Get schema for specific command
163
- nansen schema smart-money --pretty
197
+ nansen schema --pretty # All commands
198
+ nansen schema research --pretty # Research commands
164
199
  ```
165
200
 
166
- Returns command definitions, option types/defaults, supported chains, and smart money labels.
167
-
168
- ### `cache` - Cache Management
201
+ ### Deprecated Flat Commands
169
202
 
170
- Manage the local response cache.
171
-
172
- ```bash
173
- # Clear all cached responses
174
- nansen cache clear
175
- ```
203
+ The old flat commands (`nansen smart-money`, `nansen token`, `nansen profiler`, `nansen search`, `nansen perp`, `nansen portfolio`, `nansen points`, `nansen quote`, `nansen execute`) still work but print a deprecation warning to stderr. Use the new `research` and `trade` namespaces instead.
176
204
 
177
205
  ## Options
178
206
 
@@ -181,10 +209,9 @@ nansen cache clear
181
209
  | `--pretty` | Format JSON output for readability |
182
210
  | `--table` | Format output as human-readable table |
183
211
  | `--fields <list>` | Comma-separated fields to include (reduces response size) |
184
- | `--cache` | Enable response caching |
185
- | `--no-cache` | Bypass cache for this request |
212
+ | `--stream` | Output as NDJSON for incremental processing |
213
+ | `--cache` / `--no-cache` | Enable/disable response caching |
186
214
  | `--cache-ttl <s>` | Cache TTL in seconds (default: 300) |
187
- | `--stream` | Output as JSON lines (NDJSON) for incremental processing |
188
215
  | `--chain <chain>` | Blockchain to query |
189
216
  | `--chains <json>` | Multiple chains as JSON array |
190
217
  | `--limit <n>` | Number of results |
@@ -192,96 +219,120 @@ nansen cache clear
192
219
  | `--sort <field:dir>` | Sort results (e.g., `--sort value_usd:desc`) |
193
220
  | `--symbol <sym>` | Token symbol for perp endpoints (e.g., BTC, ETH) |
194
221
  | `--filters <json>` | Filter criteria as JSON |
195
- | `--order-by <json>` | Sort order as JSON array (advanced) |
196
222
  | `--labels <label>` | Smart Money label filter |
197
223
  | `--smart-money` | Filter for Smart Money only |
198
224
  | `--timeframe <tf>` | Time window (5m, 10m, 1h, 6h, 24h, 7d, 30d) |
199
225
 
200
226
  ## Supported Chains
201
227
 
202
- `ethereum`, `solana`, `base`, `bnb`, `arbitrum`, `polygon`, `optimism`, `avalanche`, `linea`, `scroll`, `zksync`, `mantle`, `ronin`, `sei`, `plasma`, `sonic`, `unichain`, `monad`, `hyperevm`, `iotaevm`
228
+ `ethereum` `solana` `base` `bnb` `arbitrum` `polygon` `optimism` `avalanche` `linea` `scroll` `zksync` `mantle` `ronin` `sei` `plasma` `sonic` `unichain` `monad` `hyperevm` `iotaevm`
203
229
 
204
- ## AI Agent Integration
230
+ > Run `nansen schema` to get the current chain list (source of truth).
205
231
 
206
- This CLI is built specifically for AI agents. Every design decision prioritizes agent usability.
232
+ ## Agent-Optimized Patterns
207
233
 
208
- **Getting Started:**
209
- Direct your users to [app.nansen.ai/auth/agent-setup](https://app.nansen.ai/auth/agent-setup) for seamless authentication. See [AI Agent Access](https://docs.nansen.ai/reference/ai-agent-access) for full documentation.
234
+ ### Reduce Token Burn with `--fields`
210
235
 
211
- **Why agents love it:**
212
- - **Structured Output**: All responses are JSON with consistent schema — no parsing HTML or unstructured text
213
- - **Predictable Errors**: Errors include status codes and actionable details agents can handle programmatically
214
- - **Zero Config**: Works with just an API key — no complex setup
215
- - **Composable**: Commands can be chained with shell pipes
216
- - **Discoverable**: `help` commands at every level for agent introspection
236
+ ```bash
237
+ # Returns everything (huge JSON, wastes agent context)
238
+ nansen research smart-money netflow --chain solana
217
239
 
218
- ```json
219
- // Success response
220
- {
221
- "success": true,
222
- "data": {
223
- "results": [...],
224
- "pagination": {...}
225
- }
226
- }
227
-
228
- // Error response
229
- {
230
- "success": false,
231
- "error": "API error message",
232
- "code": "UNAUTHORIZED",
233
- "status": 401,
234
- "details": {...}
235
- }
240
+ # ✅ Only what you need
241
+ nansen research smart-money netflow --chain solana --fields token_symbol,net_flow_usd,chain --limit 10
236
242
  ```
237
243
 
238
- ## Examples
244
+ ### Use `--stream` for Large Results
245
+
246
+ ```bash
247
+ # NDJSON mode — process line by line, don't buffer giant arrays
248
+ nansen research token dex-trades --chain solana --limit 100 --stream
249
+ ```
250
+
251
+ ### x402 Micropayments
252
+
253
+ When the API returns a 402 Payment Required, the CLI automatically handles payment if a funded wallet exists:
254
+
255
+ 1. CLI detects 402 response with payment requirements
256
+ 2. Signs a USDC payment ($0.05/call) using your wallet
257
+ 3. Retries the request with the payment signature
258
+ 4. Falls back from EVM to Solana if first network has insufficient funds
239
259
 
240
260
  ```bash
241
- # Get trending tokens as a table, sorted by volume
242
- nansen token screener --chain solana --sort buy_volume:desc --table
261
+ # Fund your wallet, then API calls auto-pay
262
+ nansen wallet create
263
+ # Send USDC to the displayed address
264
+ nansen research smart-money netflow --chain solana # auto-pays if no API key
265
+ ```
243
266
 
244
- # Get Smart Money DEX trades from Funds only
245
- nansen smart-money dex-trades --chain ethereum --labels Fund --table
267
+ ## Pagination
246
268
 
247
- # Get token holders with Smart Money filter
248
- nansen token holders --token So11111111111111111111111111111111111111112 --chain solana --smart-money
269
+ Use `--limit N` to control result count. The CLI always fetches page 1 (there is no `--page` flag).
249
270
 
250
- # Get historical holdings for the past 7 days
251
- nansen smart-money historical-holdings --chain solana --days 7
271
+ **Detecting the last page:** If results returned < your `--limit`, you've reached the end.
252
272
 
253
- # Get BTC perpetual positions on Hyperliquid
254
- nansen token perp-positions --symbol BTC --pretty
273
+ ## Output Format
255
274
 
256
- # Get top PnL traders for a token, sorted by realized PnL
257
- nansen token pnl --token JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN --chain solana --days 30 --sort pnl_usd:desc --table
275
+ ### Response envelope
258
276
 
259
- # Filter response to specific fields (reduces tokens for AI agents)
260
- nansen smart-money netflow --chain solana --fields token_symbol,net_flow_usd,chain
277
+ ```json
278
+ // Success
279
+ { "success": true, "data": <raw_api_response> }
261
280
 
262
- # Get schema for agent introspection
263
- nansen schema --pretty
264
- nansen schema token --pretty
281
+ // Error
282
+ { "success": false, "error": "message", "code": "ERROR_CODE", "status": 401, "details": {...} }
265
283
  ```
266
284
 
267
- ## Development
285
+ ### Response shapes vary by endpoint
268
286
 
269
- ```bash
270
- # Run tests (mocked, no API key needed)
271
- npm test
287
+ The `data` field structure differs across endpoints:
288
+
289
+ | Shape | Example endpoints |
290
+ |-------|------------------|
291
+ | `data.data` (array) | token screener |
292
+ | `data.results` (array) | entity search |
293
+ | `data.data.results` (array) | most profiler endpoints |
294
+ | `data.netflows` | smart-money netflow |
295
+ | `data.trades` | smart-money dex-trades |
296
+ | `data.holdings` | smart-money holdings |
297
+ | `data.holders` | token holders |
272
298
 
273
- # Run with coverage
274
- npm run test:coverage
299
+ `--table` and `--stream` handle this automatically. For raw JSON parsing:
275
300
 
276
- # Run against live API
277
- NANSEN_API_KEY=your-key npm run test:live
301
+ ```bash
302
+ nansen research smart-money netflow --chain solana | jq 'keys, .data | keys'
278
303
  ```
279
304
 
280
- See [CONTRIBUTING.md](CONTRIBUTING.md) for development guidelines.
305
+ ### Error codes
281
306
 
282
- **AI agents:** See [AGENTS.md](AGENTS.md) for the agent quick-start (install, auth, patterns, troubleshooting).
307
+ | Code | Action |
308
+ |------|--------|
309
+ | `CREDITS_EXHAUSTED` | Stop all API calls immediately — do not retry. Check your plan at [app.nansen.ai](https://app.nansen.ai). |
310
+ | `RATE_LIMITED` | Auto-retry handles this. |
311
+ | `UNSUPPORTED_FILTER` | Remove the filter and retry. |
312
+ | `UNAUTHORIZED` | Key is wrong or missing. Re-auth. |
313
+ | `INVALID_ADDRESS` | Check address format for the chain. |
314
+
315
+ ## Troubleshooting
316
+
317
+ | Symptom | Fix |
318
+ |---------|-----|
319
+ | `command not found: nansen` | `npm install -g nansen-cli` or `npx nansen-cli` |
320
+ | `UNAUTHORIZED` after login | Check `cat ~/.nansen/config.json`. Write directly if needed. |
321
+ | Login hangs | Skip `nansen login`, write config directly. |
322
+ | Huge JSON response | Use `--fields` to select only needed columns. |
323
+ | Perp endpoints empty | Use `--symbol BTC` not `--token`. Perps are Hyperliquid-only. |
324
+ | `UNSUPPORTED_FILTER` on token holders | Not all tokens have smart money data. Remove `--smart-money`. |
325
+ | `CREDITS_EXHAUSTED` | Check your plan at [app.nansen.ai](https://app.nansen.ai). |
326
+
327
+ ## Development
328
+
329
+ ```bash
330
+ npm test # Run tests (mocked, no API key needed)
331
+ npm run test:coverage # With coverage
332
+ npm run test:live # Against live API (needs NANSEN_API_KEY)
333
+ ```
283
334
 
284
- **AI contributors:** See [CLAUDE.md](CLAUDE.md) for agent-specific guidance on contributing to this repo.
335
+ See [AGENTS.md](AGENTS.md) for contributor guidance (architecture, testing patterns, style guide).
285
336
 
286
337
  ## API Coverage
287
338
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nansen-cli",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "Command-line interface for Nansen API - designed for AI agents",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -9,10 +9,12 @@
9
9
  },
10
10
  "scripts": {
11
11
  "start": "node src/index.js",
12
+ "pretest": "node scripts/check-changeset.js",
12
13
  "test": "vitest run",
13
14
  "test:watch": "vitest",
14
15
  "test:coverage": "vitest run --coverage",
15
16
  "test:live": "NANSEN_LIVE_TEST=1 vitest run",
17
+ "test:swap": "vitest run --config vitest.e2e.config.js",
16
18
  "changeset": "changeset",
17
19
  "changeset:version": "changeset version",
18
20
  "changeset:publish": "changeset publish"
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Non-blocking check: warns if the current branch has no new changeset file
5
+ * compared to main. Runs as a pretest hook so agents and humans see a reminder.
6
+ * Always exits 0 — this is a nudge, not a gate.
7
+ */
8
+
9
+ import { execSync } from "child_process";
10
+
11
+ try {
12
+ const branch = execSync("git rev-parse --abbrev-ref HEAD", { encoding: "utf8" }).trim();
13
+ if (branch === "main") process.exit(0);
14
+
15
+ const newChangesets = execSync(
16
+ "git diff main --name-only --diff-filter=A -- .changeset/*.md",
17
+ { encoding: "utf8" }
18
+ ).trim();
19
+
20
+ if (!newChangesets) {
21
+ console.error(
22
+ "\x1b[33m[changeset] No new changeset file found on this branch. " +
23
+ "If this PR changes user-facing behavior, add one: npx changeset\x1b[0m"
24
+ );
25
+ }
26
+ } catch {
27
+ // Not a git repo, main doesn't exist, etc. — skip silently.
28
+ }