nansen-cli 1.6.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/AGENTS.md +176 -0
- package/CLAUDE.md +16 -19
- package/README.md +179 -110
- package/SKILL.md +25 -21
- package/TODO.md +17 -0
- package/package.json +3 -1
- package/scripts/check-changeset.js +28 -0
- package/src/api.js +81 -60
- package/src/cli.js +401 -354
- package/src/crypto.js +215 -0
- package/src/ens.js +163 -0
- package/src/trading.js +1081 -0
- package/src/transfer.js +723 -0
- package/src/update-check.js +35 -0
- package/src/wallet.js +764 -0
- package/src/x402-evm.js +207 -0
- package/src/x402-svm.js +474 -0
- package/src/x402.js +205 -0
- package/vitest.e2e.config.js +10 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# AGENTS.md — Contributor Guide
|
|
2
|
+
|
|
3
|
+
Guidance for AI coding agents (Claude Code, Codex, Copilot, etc.) working on this repository. If you're an agent **using** the CLI, see [README.md](README.md).
|
|
4
|
+
|
|
5
|
+
## Architecture
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
src/
|
|
9
|
+
├── index.js # Entry point (shebang, calls runCLI)
|
|
10
|
+
├── cli.js # Command router, arg parsing, schema, help text
|
|
11
|
+
├── api.js # NansenAPI client (REST, retry, cache, x402 auto-pay)
|
|
12
|
+
├── wallet.js # Wallet CRUD (create/list/show/export/delete/send)
|
|
13
|
+
├── trading.js # Quote + execute swaps (OKX router via API)
|
|
14
|
+
├── transfer.js # Token/native transfers (EVM + Solana)
|
|
15
|
+
├── x402.js # x402 payment orchestration (picks network, signs)
|
|
16
|
+
├── x402-evm.js # EVM payment signing (EIP-3009 transferWithAuthorization)
|
|
17
|
+
├── x402-svm.js # Solana payment signing (SPL transfer)
|
|
18
|
+
├── crypto.js # Key encryption/decryption (AES-256-GCM or plaintext)
|
|
19
|
+
└── update-check.js # Version upgrade notice
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Command routing
|
|
23
|
+
|
|
24
|
+
`src/index.js` → `runCLI()` in `src/cli.js`
|
|
25
|
+
|
|
26
|
+
Commands are built by three functions, merged in `runCLI()`:
|
|
27
|
+
- `buildCommands()` in cli.js — analytics commands (smart-money, profiler, token, etc.)
|
|
28
|
+
- `buildWalletCommands()` in wallet.js — wallet subcommands
|
|
29
|
+
- `buildTradingCommands()` in trading.js — quote/execute
|
|
30
|
+
|
|
31
|
+
Commands listed in `NO_AUTH_COMMANDS` skip API initialization. Everything else instantiates `NansenAPI` with retry, cache, and x402 config.
|
|
32
|
+
|
|
33
|
+
### Data flow: trade
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
CLI args → api.js GET /defi/quote → quote response
|
|
37
|
+
→ wallet.js decrypt key → trading.js sign tx → api.js POST /defi/execute → broadcast
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Data flow: x402 auto-pay
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
api.js (any call) → 402 response with payment requirements
|
|
44
|
+
→ x402.js rankRequirements() → picks cheapest network (EVM first)
|
|
45
|
+
→ x402-evm.js or x402-svm.js → sign USDC payment
|
|
46
|
+
→ api.js retries original request with Payment-Signature header
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
If EVM payment fails (insufficient funds), the async generator yields a Solana signature as fallback.
|
|
50
|
+
|
|
51
|
+
### Output convention
|
|
52
|
+
|
|
53
|
+
Core functions return data objects. The CLI layer formats via `formatOutput()`. Never `console.log` in core functions — use the `log` dependency injection for CLI output.
|
|
54
|
+
|
|
55
|
+
## Development
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm install # Install dependencies
|
|
59
|
+
npm test # Run tests (vitest)
|
|
60
|
+
npm run test:watch # Watch mode
|
|
61
|
+
npm run test:coverage # With coverage
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Running locally
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
node src/index.js <command> [options]
|
|
68
|
+
|
|
69
|
+
# Examples
|
|
70
|
+
node src/index.js wallet create my-wallet
|
|
71
|
+
node src/index.js smart-money --chain solana --limit 5
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Testing
|
|
75
|
+
|
|
76
|
+
- **Framework:** Vitest
|
|
77
|
+
- **Test files:** `src/__tests__/*.test.js`
|
|
78
|
+
- **Current:** 577 tests across 13 test files
|
|
79
|
+
- **All new code must have tests**
|
|
80
|
+
- **Mock all RPC/API calls** — never hit real networks in tests
|
|
81
|
+
|
|
82
|
+
### Test structure
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
86
|
+
|
|
87
|
+
global.fetch = vi.fn();
|
|
88
|
+
|
|
89
|
+
describe('featureName', () => {
|
|
90
|
+
beforeEach(() => {
|
|
91
|
+
fetch.mockReset();
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should do the thing', async () => {
|
|
95
|
+
fetch.mockResolvedValueOnce({
|
|
96
|
+
ok: true,
|
|
97
|
+
json: async () => ({ jsonrpc: '2.0', result: '0x...', id: 1 })
|
|
98
|
+
});
|
|
99
|
+
// test logic
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Required RPC mocks by code path
|
|
105
|
+
|
|
106
|
+
**EVM transfers:** `eth_getBalance`, `eth_gasPrice`, `eth_maxPriorityFeePerGas`, `eth_getTransactionCount`, `eth_estimateGas`, `eth_getCode`, `eth_sendRawTransaction`, `eth_getTransactionReceipt`
|
|
107
|
+
|
|
108
|
+
**Solana transfers:** `getBalance`, `getLatestBlockhash`, `sendTransaction`, `getSignatureStatuses`
|
|
109
|
+
|
|
110
|
+
**SPL token transfers** (additionally): `getTokenAccountsByOwner`, `getAccountInfo`
|
|
111
|
+
|
|
112
|
+
**Wallet operations:** No RPC mocks needed (file I/O only). Mock `fs` if testing file paths.
|
|
113
|
+
|
|
114
|
+
**API calls:** Mock `fetch` to return `{ ok: true, json: () => ({...}) }` or `{ ok: false, status: 402, headers: new Headers({...}) }` for x402 paths.
|
|
115
|
+
|
|
116
|
+
## Style Guide
|
|
117
|
+
|
|
118
|
+
- **ESM only** (`import`/`export`). No TypeScript, no transpilation.
|
|
119
|
+
- **No interactive prompts in core functions.** Use env vars: `NANSEN_WALLET_PASSWORD`, `NANSEN_API_KEY`.
|
|
120
|
+
- **Error handling:** `throw new Error('descriptive message')` in core. CLI catches and formats.
|
|
121
|
+
- **Actionable error messages** — tell the user what to do:
|
|
122
|
+
- ❌ `"Authentication failed"`
|
|
123
|
+
- ✅ `"Not logged in. Run: nansen login"`
|
|
124
|
+
- **BigInt for token amounts.** Never use floating point. Parse to BigInt with decimals.
|
|
125
|
+
- **Chain branching:** Use `chain === 'solana'` checks, not inheritance/polymorphism.
|
|
126
|
+
- **Minimal dependencies.** Prefer Node.js built-in APIs (crypto, fs, path, http).
|
|
127
|
+
|
|
128
|
+
## PR Checklist
|
|
129
|
+
|
|
130
|
+
- [ ] `npm test` passes (all tests)
|
|
131
|
+
- [ ] New code paths have test coverage
|
|
132
|
+
- [ ] No hardcoded secrets, API keys, or private keys
|
|
133
|
+
- [ ] No `console.log` in core functions (use `log` dep injection)
|
|
134
|
+
- [ ] Error messages are actionable (tell user what to do)
|
|
135
|
+
- [ ] CLI help text updated if adding/changing commands
|
|
136
|
+
- [ ] RPC mocks cover all methods in the code path
|
|
137
|
+
- [ ] Wallet flows work both with and without `NANSEN_WALLET_PASSWORD`
|
|
138
|
+
- [ ] Changeset added if changing user-facing behavior (add a `.changeset/<name>.md` file — `npm test` will warn if missing)
|
|
139
|
+
|
|
140
|
+
## Chains & Networks
|
|
141
|
+
|
|
142
|
+
**EVM:** Ethereum (chain ID 1), Base (8453). `CHAIN_IDS` in transfer.js only maps these two — other EVM chains will fail for transfers.
|
|
143
|
+
|
|
144
|
+
**Solana:** mainnet-beta. Supports native SOL, standard SPL tokens, and Token-2022 (Token Extensions).
|
|
145
|
+
|
|
146
|
+
**RPC endpoints:** Hardcoded in `CHAIN_RPCS` (transfer.js). Nansen API handles RPC for trading.
|
|
147
|
+
|
|
148
|
+
## Key Constants
|
|
149
|
+
|
|
150
|
+
| Constant | Value |
|
|
151
|
+
|----------|-------|
|
|
152
|
+
| USDC (Base) | `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` |
|
|
153
|
+
| USDC (Solana) | `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v` |
|
|
154
|
+
| x402 payment | $0.05 USDC per API call |
|
|
155
|
+
| Gas buffer | API provides `quote.gas` with 1.5x multiplier — use directly |
|
|
156
|
+
|
|
157
|
+
## Endpoint Quirks
|
|
158
|
+
|
|
159
|
+
These are internal details agents should know when writing or debugging tests:
|
|
160
|
+
|
|
161
|
+
- **`token holders --smart-money`** — Returns `UNSUPPORTED_FILTER` for tokens without smart money tracking. Not all tokens have this data.
|
|
162
|
+
- **`token flow-intelligence`** — May return all-zero flows for illiquid tokens. Normal, not an error.
|
|
163
|
+
- **`token screener --search`** — Client-side filtering. The CLI fetches up to 500 results, then filters locally.
|
|
164
|
+
- **`--fields`** — Applies to the entire response tree, including the `success`/`data` wrapper.
|
|
165
|
+
- **Profiler beta endpoints** use `recordsPerPage` instead of `per_page`. The CLI handles this automatically.
|
|
166
|
+
- **`profiler perp-positions`** — No pagination support; the API ignores the pagination parameter.
|
|
167
|
+
|
|
168
|
+
## Known Gotchas
|
|
169
|
+
|
|
170
|
+
1. **EIP-7702 delegated accounts** on Base have contract code. Always use `eth_estimateGas`, never hardcode 21000 gas.
|
|
171
|
+
2. **Solana SPL account ordering:** Writable accounts (destATA) must precede readonly (mint) in the transaction message.
|
|
172
|
+
3. **`getSignatureStatuses`** over `confirmTransaction` — the latter is deprecated and unreliable on public RPCs.
|
|
173
|
+
4. **`--max` native SOL:** Reserve 5000 lamports for fee. On EVM L2s, reserve 3x estimated gas for L1 data posting fees.
|
|
174
|
+
5. **Token-2022:** Use `TOKEN_2022_PROGRAM_ID` and `TransferCheckedInstruction` (not plain `Transfer`).
|
|
175
|
+
6. **CreateATA path:** When recipient doesn't have a token account, the sender creates it. This path in transfer.js has limited test coverage — add tests if modifying.
|
|
176
|
+
7. **`CHAIN_IDS` is incomplete:** Only ethereum and base are mapped. Adding new EVM chain support requires updating this map.
|
package/CLAUDE.md
CHANGED
|
@@ -125,7 +125,7 @@ Returns JSON with all commands, subcommands, option types/defaults, return field
|
|
|
125
125
|
|
|
126
126
|
### Field Filtering
|
|
127
127
|
```bash
|
|
128
|
-
nansen smart-money netflow --fields token_symbol,net_flow_usd,chain
|
|
128
|
+
nansen research smart-money netflow --fields token_symbol,net_flow_usd,chain
|
|
129
129
|
```
|
|
130
130
|
Reduces response size by including only specified fields. Works with nested data structures.
|
|
131
131
|
|
|
@@ -180,41 +180,38 @@ Structured error codes for programmatic handling:
|
|
|
180
180
|
|
|
181
181
|
## Publishing (npm)
|
|
182
182
|
|
|
183
|
-
|
|
183
|
+
**DO NOT manually run `npm version` or `npm publish`. CI handles everything.**
|
|
184
184
|
|
|
185
|
-
|
|
185
|
+
1. **Push to main** — CI runs tests
|
|
186
|
+
2. **CI creates a "Version Packages" PR** — bumps version + updates CHANGELOG
|
|
187
|
+
3. **Merge the Version PR** — CI auto-publishes to npm
|
|
186
188
|
|
|
187
|
-
|
|
188
|
-
```bash
|
|
189
|
-
npx changeset
|
|
190
|
-
# Or manually create .changeset/<name>.md
|
|
191
|
-
```
|
|
189
|
+
If you mess up: accidentally bumped version manually? `git revert` and add a changeset instead. CI publish failed? Check GitHub Actions logs, likely needs `NPM_TOKEN` secret refresh.
|
|
192
190
|
|
|
193
|
-
|
|
191
|
+
## Changesets
|
|
194
192
|
|
|
195
|
-
|
|
193
|
+
Every PR that changes user-facing behavior **must** include a changeset file. `npm test` will warn if one is missing. The changeset description ends up in CHANGELOG.md (auto-generated by CI), so write it as a user-facing changelog entry.
|
|
196
194
|
|
|
197
|
-
|
|
195
|
+
**Needs a changeset:** new features, bug fixes, breaking changes, changed CLI output, new/modified commands.
|
|
196
|
+
|
|
197
|
+
**Does NOT need a changeset:** docs-only, test-only, refactors with no behavior change, CI/tooling.
|
|
198
|
+
|
|
199
|
+
Add a file to `.changeset/` with a descriptive kebab-case name:
|
|
198
200
|
|
|
199
|
-
### Changeset format:
|
|
200
201
|
```markdown
|
|
201
202
|
---
|
|
202
203
|
"nansen-cli": minor
|
|
203
204
|
---
|
|
204
205
|
|
|
205
|
-
|
|
206
|
+
Short description of the change (appears in CHANGELOG)
|
|
206
207
|
```
|
|
207
208
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
### If you mess up:
|
|
211
|
-
- Accidentally bumped version manually? `git revert` and add a changeset instead
|
|
212
|
-
- CI publish failed? Check GitHub Actions logs, likely needs `NPM_TOKEN` secret refresh
|
|
209
|
+
Use `patch` for bug fixes, `minor` for new features, `major` for breaking changes.
|
|
213
210
|
|
|
214
211
|
## PR Checklist
|
|
215
212
|
|
|
216
213
|
- [ ] Tests pass (`npm test`)
|
|
217
214
|
- [ ] New endpoints have tests in all 3 test files
|
|
218
215
|
- [ ] README.md updated if adding user-facing features
|
|
219
|
-
- [ ]
|
|
216
|
+
- [ ] Changeset added for user-facing changes (see above)
|
|
220
217
|
- [ ] No new dependencies (keep it lightweight)
|
package/README.md
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/nansen-cli)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
[]()
|
|
5
|
+
[]()
|
|
7
6
|
|
|
8
7
|
> **Built by agents, for agents.** We prioritize the best possible AI agent experience.
|
|
9
8
|
|
|
@@ -27,39 +26,83 @@ npm link
|
|
|
27
26
|
|
|
28
27
|
## Configuration
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
### For AI Agents (Recommended)
|
|
30
|
+
|
|
31
|
+
Use the [AI Agent Setup](https://app.nansen.ai/auth/agent-setup) flow:
|
|
32
|
+
|
|
33
|
+
1. Your agent will ask you to visit: **[app.nansen.ai/auth/agent-setup](https://app.nansen.ai/auth/agent-setup)**
|
|
34
|
+
2. Sign in with your Nansen account
|
|
35
|
+
3. Copy the message shown
|
|
36
|
+
4. Paste it back to your agent
|
|
37
|
+
|
|
38
|
+
Your agent saves the key and handles everything else automatically.
|
|
39
|
+
|
|
40
|
+
### Manual Setup
|
|
41
|
+
|
|
42
|
+
**Option 1: Interactive login**
|
|
31
43
|
```bash
|
|
32
44
|
nansen login
|
|
33
45
|
# Enter your API key when prompted
|
|
34
46
|
# ✓ Saved to ~/.nansen/config.json
|
|
35
47
|
```
|
|
36
48
|
|
|
37
|
-
**Option 2: Environment variable**
|
|
49
|
+
**Option 2: Environment variable (best for agents)**
|
|
38
50
|
```bash
|
|
39
51
|
export NANSEN_API_KEY=your-api-key
|
|
40
52
|
```
|
|
41
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
|
+
|
|
42
59
|
Get your API key at [app.nansen.ai/api](https://app.nansen.ai/api).
|
|
43
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
|
+
|
|
44
77
|
## Quick Start
|
|
45
78
|
|
|
46
79
|
```bash
|
|
47
80
|
# Get trending tokens on Solana
|
|
48
|
-
nansen token screener --chain solana --timeframe 24h --pretty
|
|
81
|
+
nansen research token screener --chain solana --timeframe 24h --pretty
|
|
49
82
|
|
|
50
83
|
# Check Smart Money activity
|
|
51
|
-
nansen smart-money netflow --chain solana --pretty
|
|
84
|
+
nansen research smart-money netflow --chain solana --pretty
|
|
52
85
|
|
|
53
86
|
# Profile a wallet
|
|
54
|
-
nansen profiler balance --address 0x28c6c06298d514db089934071355e5743bf21d60 --chain ethereum --pretty
|
|
87
|
+
nansen research profiler balance --address 0x28c6c06298d514db089934071355e5743bf21d60 --chain ethereum --pretty
|
|
55
88
|
|
|
56
|
-
# Search for
|
|
57
|
-
nansen
|
|
89
|
+
# Search for tokens/entities
|
|
90
|
+
nansen research search "Vitalik Buterin" --pretty
|
|
58
91
|
```
|
|
59
92
|
|
|
60
93
|
## Commands
|
|
61
94
|
|
|
62
|
-
|
|
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
|
|
63
106
|
|
|
64
107
|
Track trading and holding activity of sophisticated market participants.
|
|
65
108
|
|
|
@@ -72,17 +115,19 @@ Track trading and holding activity of sophisticated market participants.
|
|
|
72
115
|
| `dcas` | DCA strategies on Jupiter |
|
|
73
116
|
| `historical-holdings` | Historical holdings over time |
|
|
74
117
|
|
|
75
|
-
**Smart Money Labels:**
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
- `30D Smart Trader` - Top performers (30-day window)
|
|
79
|
-
- `90D Smart Trader` - Top performers (90-day window)
|
|
80
|
-
- `180D Smart Trader` - Top performers (180-day window)
|
|
81
|
-
- `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
|
|
82
121
|
|
|
83
|
-
|
|
122
|
+
**ENS Name Resolution:** You can use `.eth` names anywhere an `--address` is accepted:
|
|
123
|
+
|
|
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
|
+
```
|
|
84
129
|
|
|
85
|
-
|
|
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.
|
|
86
131
|
|
|
87
132
|
| Subcommand | Description |
|
|
88
133
|
|------------|-------------|
|
|
@@ -98,9 +143,7 @@ Detailed information about any blockchain address.
|
|
|
98
143
|
| `perp-positions` | Current perpetual positions |
|
|
99
144
|
| `perp-trades` | Perpetual trading history |
|
|
100
145
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
Deep analytics for any token.
|
|
146
|
+
#### `research token` - Token God Mode
|
|
104
147
|
|
|
105
148
|
| Subcommand | Description |
|
|
106
149
|
|------------|-------------|
|
|
@@ -113,53 +156,51 @@ Deep analytics for any token.
|
|
|
113
156
|
| `flow-intelligence` | Detailed flow intelligence by label |
|
|
114
157
|
| `transfers` | Token transfer history |
|
|
115
158
|
| `jup-dca` | Jupiter DCA orders for token |
|
|
159
|
+
| `ohlcv` | OHLCV candle data for a token |
|
|
116
160
|
| `perp-trades` | Perp trades by token symbol |
|
|
117
161
|
| `perp-positions` | Open perp positions by token symbol |
|
|
118
162
|
| `perp-pnl-leaderboard` | Perp PnL leaderboard by token |
|
|
119
163
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
| Subcommand | Description |
|
|
123
|
-
|------------|-------------|
|
|
124
|
-
| `defi` | DeFi holdings across protocols |
|
|
164
|
+
#### `research search` / `research perp` / `research portfolio` / `research points`
|
|
125
165
|
|
|
126
|
-
|
|
166
|
+
See `nansen research help` or `nansen schema --pretty` for full details.
|
|
127
167
|
|
|
128
|
-
|
|
168
|
+
### `trade` - DEX Trading
|
|
129
169
|
|
|
130
170
|
```bash
|
|
131
|
-
|
|
132
|
-
nansen
|
|
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
|
|
133
176
|
```
|
|
134
177
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
|
138
|
-
|
|
139
|
-
|
|
|
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.
|
|
140
191
|
|
|
141
192
|
### `schema` - Schema Discovery
|
|
142
193
|
|
|
143
|
-
|
|
194
|
+
No API key required. Machine-readable command reference for agent introspection.
|
|
144
195
|
|
|
145
196
|
```bash
|
|
146
|
-
#
|
|
147
|
-
nansen schema --pretty
|
|
148
|
-
|
|
149
|
-
# Get schema for specific command
|
|
150
|
-
nansen schema smart-money --pretty
|
|
197
|
+
nansen schema --pretty # All commands
|
|
198
|
+
nansen schema research --pretty # Research commands
|
|
151
199
|
```
|
|
152
200
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
### `cache` - Cache Management
|
|
201
|
+
### Deprecated Flat Commands
|
|
156
202
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
```bash
|
|
160
|
-
# Clear all cached responses
|
|
161
|
-
nansen cache clear
|
|
162
|
-
```
|
|
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.
|
|
163
204
|
|
|
164
205
|
## Options
|
|
165
206
|
|
|
@@ -168,10 +209,9 @@ nansen cache clear
|
|
|
168
209
|
| `--pretty` | Format JSON output for readability |
|
|
169
210
|
| `--table` | Format output as human-readable table |
|
|
170
211
|
| `--fields <list>` | Comma-separated fields to include (reduces response size) |
|
|
171
|
-
| `--
|
|
172
|
-
| `--no-cache` |
|
|
212
|
+
| `--stream` | Output as NDJSON for incremental processing |
|
|
213
|
+
| `--cache` / `--no-cache` | Enable/disable response caching |
|
|
173
214
|
| `--cache-ttl <s>` | Cache TTL in seconds (default: 300) |
|
|
174
|
-
| `--stream` | Output as JSON lines (NDJSON) for incremental processing |
|
|
175
215
|
| `--chain <chain>` | Blockchain to query |
|
|
176
216
|
| `--chains <json>` | Multiple chains as JSON array |
|
|
177
217
|
| `--limit <n>` | Number of results |
|
|
@@ -179,91 +219,120 @@ nansen cache clear
|
|
|
179
219
|
| `--sort <field:dir>` | Sort results (e.g., `--sort value_usd:desc`) |
|
|
180
220
|
| `--symbol <sym>` | Token symbol for perp endpoints (e.g., BTC, ETH) |
|
|
181
221
|
| `--filters <json>` | Filter criteria as JSON |
|
|
182
|
-
| `--order-by <json>` | Sort order as JSON array (advanced) |
|
|
183
222
|
| `--labels <label>` | Smart Money label filter |
|
|
184
223
|
| `--smart-money` | Filter for Smart Money only |
|
|
185
224
|
| `--timeframe <tf>` | Time window (5m, 10m, 1h, 6h, 24h, 7d, 30d) |
|
|
186
225
|
|
|
187
226
|
## Supported Chains
|
|
188
227
|
|
|
189
|
-
`ethereum
|
|
228
|
+
`ethereum` `solana` `base` `bnb` `arbitrum` `polygon` `optimism` `avalanche` `linea` `scroll` `zksync` `mantle` `ronin` `sei` `plasma` `sonic` `unichain` `monad` `hyperevm` `iotaevm`
|
|
190
229
|
|
|
191
|
-
|
|
230
|
+
> Run `nansen schema` to get the current chain list (source of truth).
|
|
192
231
|
|
|
193
|
-
|
|
232
|
+
## Agent-Optimized Patterns
|
|
194
233
|
|
|
195
|
-
|
|
196
|
-
- **Structured Output**: All responses are JSON with consistent schema — no parsing HTML or unstructured text
|
|
197
|
-
- **Predictable Errors**: Errors include status codes and actionable details agents can handle programmatically
|
|
198
|
-
- **Zero Config**: Works with just an API key — no complex setup
|
|
199
|
-
- **Composable**: Commands can be chained with shell pipes
|
|
200
|
-
- **Discoverable**: `help` commands at every level for agent introspection
|
|
234
|
+
### Reduce Token Burn with `--fields`
|
|
201
235
|
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
"error": "API error message",
|
|
216
|
-
"code": "UNAUTHORIZED",
|
|
217
|
-
"status": 401,
|
|
218
|
-
"details": {...}
|
|
219
|
-
}
|
|
236
|
+
```bash
|
|
237
|
+
# ❌ Returns everything (huge JSON, wastes agent context)
|
|
238
|
+
nansen research smart-money netflow --chain solana
|
|
239
|
+
|
|
240
|
+
# ✅ Only what you need
|
|
241
|
+
nansen research smart-money netflow --chain solana --fields token_symbol,net_flow_usd,chain --limit 10
|
|
242
|
+
```
|
|
243
|
+
|
|
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
|
|
220
249
|
```
|
|
221
250
|
|
|
222
|
-
|
|
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
|
|
223
259
|
|
|
224
260
|
```bash
|
|
225
|
-
#
|
|
226
|
-
nansen
|
|
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
|
+
```
|
|
227
266
|
|
|
228
|
-
|
|
229
|
-
nansen smart-money dex-trades --chain ethereum --labels Fund --table
|
|
267
|
+
## Pagination
|
|
230
268
|
|
|
231
|
-
|
|
232
|
-
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).
|
|
233
270
|
|
|
234
|
-
|
|
235
|
-
nansen smart-money historical-holdings --chain solana --days 7
|
|
271
|
+
**Detecting the last page:** If results returned < your `--limit`, you've reached the end.
|
|
236
272
|
|
|
237
|
-
|
|
238
|
-
nansen token perp-positions --symbol BTC --pretty
|
|
273
|
+
## Output Format
|
|
239
274
|
|
|
240
|
-
|
|
241
|
-
nansen token pnl --token JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN --chain solana --days 30 --sort pnl_usd:desc --table
|
|
275
|
+
### Response envelope
|
|
242
276
|
|
|
243
|
-
|
|
244
|
-
|
|
277
|
+
```json
|
|
278
|
+
// Success
|
|
279
|
+
{ "success": true, "data": <raw_api_response> }
|
|
245
280
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
nansen schema token --pretty
|
|
281
|
+
// Error
|
|
282
|
+
{ "success": false, "error": "message", "code": "ERROR_CODE", "status": 401, "details": {...} }
|
|
249
283
|
```
|
|
250
284
|
|
|
251
|
-
|
|
285
|
+
### Response shapes vary by endpoint
|
|
252
286
|
|
|
253
|
-
|
|
254
|
-
# Run tests (mocked, no API key needed)
|
|
255
|
-
npm test
|
|
287
|
+
The `data` field structure differs across endpoints:
|
|
256
288
|
|
|
257
|
-
|
|
258
|
-
|
|
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 |
|
|
259
298
|
|
|
260
|
-
|
|
261
|
-
|
|
299
|
+
`--table` and `--stream` handle this automatically. For raw JSON parsing:
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
nansen research smart-money netflow --chain solana | jq 'keys, .data | keys'
|
|
262
303
|
```
|
|
263
304
|
|
|
264
|
-
|
|
305
|
+
### Error codes
|
|
306
|
+
|
|
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
|
+
```
|
|
265
334
|
|
|
266
|
-
|
|
335
|
+
See [AGENTS.md](AGENTS.md) for contributor guidance (architecture, testing patterns, style guide).
|
|
267
336
|
|
|
268
337
|
## API Coverage
|
|
269
338
|
|