nansen-cli 1.8.0 → 1.9.1
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/CHANGELOG.md +103 -0
- package/README.md +1 -1
- package/package.json +5 -1
- package/src/api.js +51 -11
- package/src/chain-ids.js +19 -0
- package/src/cli.js +28 -9
- package/src/trading.js +324 -25
- package/src/transfer.js +133 -2
- package/src/wallet.js +11 -9
- package/src/walletconnect-exec.js +22 -0
- package/src/walletconnect-trading.js +91 -0
- package/src/walletconnect-x402.js +215 -0
- package/.changeset/README.md +0 -8
- package/AGENTS.md +0 -176
- package/CLAUDE.md +0 -217
- package/SKILL.md +0 -136
- package/TODO.md +0 -42
- package/scripts/check-changeset.js +0 -28
- package/vitest.e2e.config.js +0 -10
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.9.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#110](https://github.com/nansen-ai/nansen-cli/pull/110) [`82aa780`](https://github.com/nansen-ai/nansen-cli/commit/82aa78022bdcd62987b0949e090f19f563699d9a) Thanks [@TimNooren](https://github.com/TimNooren)! - Fix `nansen changelog` always showing "CHANGELOG.md not found". Added a `files` field to `package.json` to explicitly bundle `CHANGELOG.md` with the published package. Also excludes `src/__tests__/` from the package, reducing package size from ~537 kB to ~269 kB.
|
|
8
|
+
|
|
9
|
+
## 1.9.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [#98](https://github.com/nansen-ai/nansen-cli/pull/98) [`2f3f556`](https://github.com/nansen-ai/nansen-cli/commit/2f3f556d008a1f8ec40d57a8a2822bedbc6b60cb) Thanks [@Codier](https://github.com/Codier)! - Add symbol shortcuts for common tokens (SOL, ETH, USDC, USDT, etc.) that resolve to canonical addresses per chain. Users can now use `--from SOL --to USDC` instead of raw contract addresses.
|
|
14
|
+
|
|
15
|
+
- [#32](https://github.com/nansen-ai/nansen-cli/pull/32) [`08a8d21`](https://github.com/nansen-ai/nansen-cli/commit/08a8d21be6e9196661be737545e790af180aebc3) Thanks [@arein](https://github.com/arein)! - Add WalletConnect support for trading, transfers, and x402 auto-payment (EVM only)
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- [#99](https://github.com/nansen-ai/nansen-cli/pull/99) [`9144cba`](https://github.com/nansen-ai/nansen-cli/commit/9144cba38b06c90d462df97ea6cbcdeaed26fa36) Thanks [@Codier](https://github.com/Codier)! - Show clear error when `--amount` contains a decimal (e.g. `0.005`) instead of base units (lamports, wei). Detected client-side before hitting the API.
|
|
20
|
+
|
|
21
|
+
- [#100](https://github.com/nansen-ai/nansen-cli/pull/100) [`19559bf`](https://github.com/nansen-ai/nansen-cli/commit/19559bfea6c22f6bd6b8c278ed5e6ae6d64866d5) Thanks [@Codier](https://github.com/Codier)! - Fix `nansen trade help` returning blank output. Now prints subcommands, usage, and examples. Also fixes `errorOutput` ReferenceError in `buildCommands` scope (affected `trade` and `changelog` commands).
|
|
22
|
+
|
|
23
|
+
- [#93](https://github.com/nansen-ai/nansen-cli/pull/93) [`342c91f`](https://github.com/nansen-ai/nansen-cli/commit/342c91fdeb6d98d6b5c10a58cb9702eb5afe096f) Thanks [@Codier](https://github.com/Codier)! - Warn when `--from` is a wrapped native token (WETH/WBNB) or native sentinel, so AI agents can correct the token before execution fails
|
|
24
|
+
|
|
25
|
+
## 1.8.0
|
|
26
|
+
|
|
27
|
+
### Minor Changes
|
|
28
|
+
|
|
29
|
+
- [#56](https://github.com/nansen-ai/nansen-cli/pull/56) [`d10998a`](https://github.com/nansen-ai/nansen-cli/commit/d10998aa2be19f80e8476d19bfd46029757a7335) Thanks [@askeluv](https://github.com/askeluv)! - Add CHANGELOG.md, `nansen changelog` command, and post-update "what's new" notice
|
|
30
|
+
|
|
31
|
+
- Added CHANGELOG.md following Keep a Changelog format with history back to v1.5.0
|
|
32
|
+
- Added `nansen changelog` command with `--since <version>` filtering
|
|
33
|
+
- Added one-time upgrade notice on first run after version update (prints to stderr)
|
|
34
|
+
|
|
35
|
+
- [#77](https://github.com/nansen-ai/nansen-cli/pull/77) [`46e4660`](https://github.com/nansen-ai/nansen-cli/commit/46e4660034d9681405d09a5184f78525c300b8a5) Thanks [@0xlaveen](https://github.com/0xlaveen)! - Add token-ohlcv endpoint for OHLCV candle data
|
|
36
|
+
|
|
37
|
+
- [#75](https://github.com/nansen-ai/nansen-cli/pull/75) [`287937e`](https://github.com/nansen-ai/nansen-cli/commit/287937e1d307e0b3f25648863d0c5b4a54d215ff) Thanks [@TimNooren](https://github.com/TimNooren)! - Restructure CLI into research/trade/wallet namespaces
|
|
38
|
+
|
|
39
|
+
- Commands reorganized: `smart-money`, `profiler`, `token`, `portfolio` now live under `nansen research`
|
|
40
|
+
- New `nansen trade` namespace for `quote` and `execute`
|
|
41
|
+
- New `nansen wallet` namespace for wallet management
|
|
42
|
+
- Old top-level commands still work with deprecation warnings
|
|
43
|
+
|
|
44
|
+
- [#61](https://github.com/nansen-ai/nansen-cli/pull/61) [`9af0192`](https://github.com/nansen-ai/nansen-cli/commit/9af01921871be1d0537047cb4ad9733e01876646) Thanks [@askeluv](https://github.com/askeluv)! - Add ENS name resolution for profiler commands. Use `.eth` names directly in `--address` flags — resolved automatically via ensideas API with onchain RPC fallback. Works across all profiler subcommands, batch, and trace operations.
|
|
45
|
+
|
|
46
|
+
All notable changes to the Nansen CLI will be documented in this file.
|
|
47
|
+
|
|
48
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
49
|
+
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
50
|
+
|
|
51
|
+
## [1.7.0] - 2026-02-24
|
|
52
|
+
|
|
53
|
+
### Added
|
|
54
|
+
|
|
55
|
+
- **Trading commands** — `quote` and `execute` for DEX swaps (EVM + Solana)
|
|
56
|
+
- **Wallet management** — `wallet create`, `list`, `show`, `export`, `default`, `delete`
|
|
57
|
+
- **Wallet send** — transfer tokens on EVM and Solana (`wallet send`)
|
|
58
|
+
- **x402 auto-payment** — automatic payment via Base USDC or Solana SPL USDC
|
|
59
|
+
- Explorer links in transaction output
|
|
60
|
+
- `--dry-run` flag for `wallet send`
|
|
61
|
+
- x402 low balance warning
|
|
62
|
+
- AI Agent Access setup docs and improved onboarding flow
|
|
63
|
+
|
|
64
|
+
### Fixed
|
|
65
|
+
|
|
66
|
+
- Solana execute crash with OKX quotes
|
|
67
|
+
- x402 auto-pay retry path (3 reference errors)
|
|
68
|
+
- Gas estimation — use API `quote.gas` as floor
|
|
69
|
+
- Pre-flight simulation moved after approval (industry standard)
|
|
70
|
+
- EVM signing edge cases with pure JS ECDSA
|
|
71
|
+
- Wallet send crashes on amount parsing and silent success
|
|
72
|
+
- Solana confirmation and SPL token transfer account ordering
|
|
73
|
+
- Suppress duplicate JSON output from quote/execute
|
|
74
|
+
- Suppress approval warning for native ETH swaps
|
|
75
|
+
|
|
76
|
+
### Changed
|
|
77
|
+
|
|
78
|
+
- Pricing clarity — from $0.01/call, min $0.05 balance
|
|
79
|
+
- Consolidated crypto primitives into shared module
|
|
80
|
+
|
|
81
|
+
## [1.6.0] - 2026-02-14
|
|
82
|
+
|
|
83
|
+
### Added
|
|
84
|
+
|
|
85
|
+
- `token indicators` endpoint
|
|
86
|
+
- `profiler search` — general entity search command
|
|
87
|
+
- `--x402-payment-signature` flag for pre-signed payment headers
|
|
88
|
+
- `X-Client-Type` and `X-Client-Version` tracking headers on all API requests
|
|
89
|
+
|
|
90
|
+
### Fixed
|
|
91
|
+
|
|
92
|
+
- Error JSON now outputs to stdout (not stderr) for consistent agent parsing
|
|
93
|
+
- Config loading — environment variables correctly override file config
|
|
94
|
+
|
|
95
|
+
## [1.5.1] - 2026-02-07
|
|
96
|
+
|
|
97
|
+
### Added
|
|
98
|
+
|
|
99
|
+
- Allow API requests without API key when using x402 payment flow
|
|
100
|
+
|
|
101
|
+
## [1.5.0] - 2026-01-31
|
|
102
|
+
|
|
103
|
+
_Baseline version. Changes above are relative to this release._
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/nansen-cli)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
[](https://github.com/nansen-ai/nansen-cli/actions/workflows/ci.yml)
|
|
6
6
|
|
|
7
7
|
> **Built by agents, for agents.** We prioritize the best possible AI agent experience.
|
|
8
8
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nansen-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.1",
|
|
4
4
|
"description": "Command-line interface for Nansen API - designed for AI agents",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
8
|
"nansen": "./src/index.js"
|
|
9
9
|
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src/*.js",
|
|
12
|
+
"CHANGELOG.md"
|
|
13
|
+
],
|
|
10
14
|
"scripts": {
|
|
11
15
|
"start": "node src/index.js",
|
|
12
16
|
"pretest": "node scripts/check-changeset.js",
|
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
|
|
509
|
-
|
|
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 { /*
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
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, {
|
package/src/chain-ids.js
ADDED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
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
|
-
|
|
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
|
};
|