nansen-cli 1.27.0 → 1.28.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/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/skills/nansen-token-screener/SKILL.md +54 -0
- package/src/api.js +7 -0
- package/src/cli.js +49 -5
- package/src/keychain.js +1 -0
- package/src/limit-order.js +873 -0
- package/src/privy.js +9 -0
- package/src/schema.json +146 -1
- package/src/telemetry.js +5 -1
- package/src/trading.js +14 -0
- package/src/transfer.js +1 -1
- package/src/walletconnect-trading.js +25 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.28.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#417](https://github.com/nansen-ai/nansen-cli/pull/417) [`ae6079f`](https://github.com/nansen-ai/nansen-cli/commit/ae6079f12d06d11fe357237b84387fcaffcfd387) Thanks [@0xlaveen](https://github.com/0xlaveen)! - Add `trade limit-order` commands (create, list, cancel, update) for Jupiter Limit Order V2 on Solana. Supports local, Privy, and WalletConnect wallets.
|
|
8
|
+
|
|
9
|
+
- [#413](https://github.com/nansen-ai/nansen-cli/pull/413) [`94bd349`](https://github.com/nansen-ai/nansen-cli/commit/94bd349bdf9a0a3f3389975144281306eea0e4ca) Thanks [@jake-kennis](https://github.com/jake-kennis)! - Add `top-tokens` subcommand to discover top-scoring tokens by Nansen Score. Calls the public endpoint (`/api/v1/nansen-score/top-tokens`) with optional `--market-cap` filter.
|
|
10
|
+
|
|
11
|
+
## 1.27.1
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [#408](https://github.com/nansen-ai/nansen-cli/pull/408) [`d1e9787`](https://github.com/nansen-ai/nansen-cli/commit/d1e97871b897153a9e1cd587897ff2f4bbed6c88) Thanks [@0xlaveen](https://github.com/0xlaveen)! - Add cross-chain notes to trade help text and document --to-chain constraints in schema.json.
|
|
16
|
+
|
|
3
17
|
## 1.27.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -45,10 +45,64 @@ nansen research token indicators --token $TOKEN --chain $CHAIN
|
|
|
45
45
|
# Flow intelligence — only use for promising tokens from screener/indicators above
|
|
46
46
|
nansen research token flow-intelligence --token $TOKEN --chain $CHAIN
|
|
47
47
|
# → net_flow_usd per label: smart_trader, whale, exchange, fresh_wallets, public_figure
|
|
48
|
+
|
|
49
|
+
# Nansen Score Top Tokens — "what should I buy?" (public endpoint, any authenticated API key)
|
|
50
|
+
# Use this FIRST for discovery, then drill into individual tokens with `indicators` above
|
|
51
|
+
nansen research token top-tokens --limit 25
|
|
52
|
+
nansen research token top-tokens --market-cap largecap --limit 10
|
|
53
|
+
# → chain, token_address, token_symbol, performance_score, risk_score,
|
|
54
|
+
# per-indicator contributions, market_cap_group, latest_date, last_trigger_on
|
|
48
55
|
```
|
|
49
56
|
|
|
50
57
|
Screener timeframes: `5m`, `10m`, `1h`, `6h`, `24h`, `7d`, `30d`
|
|
51
58
|
|
|
52
59
|
Indicators: score is "bullish"/"bearish"/"neutral". signal_percentile > 70 = historically significant. Some tokens return empty indicators — not an error.
|
|
53
60
|
|
|
61
|
+
## Top tokens — Nansen Score field reference
|
|
62
|
+
|
|
63
|
+
Results are pre-filtered to `performance_score >= 15` server-side and returned sorted by:
|
|
64
|
+
1. `performance_score` DESC
|
|
65
|
+
2. `market_cap_group` priority (largecap → midcap → lowcap)
|
|
66
|
+
3. `risk_score` DESC
|
|
67
|
+
4. 24h volume DESC
|
|
68
|
+
|
|
69
|
+
So row 0 is always the strongest candidate for the filter you applied — no client-side ranking needed.
|
|
70
|
+
|
|
71
|
+
Market cap buckets (used in both the sort priority and the `--market-cap` filter):
|
|
72
|
+
- `lowcap`: market cap < $100M
|
|
73
|
+
- `midcap`: market cap $100M – $1B
|
|
74
|
+
- `largecap`: market cap > $1B
|
|
75
|
+
|
|
76
|
+
Every contribution is **ternary** — exactly one of `{negative, 0, positive}` per field. No partial values. Zero means "indicator didn't apply to this token" (out of scope), not "indicator was neutral".
|
|
77
|
+
|
|
78
|
+
**Performance Score (Alpha — "likely to outperform BTC over 7–30d")**
|
|
79
|
+
Range: `-60 to +75` (arithmetic bounds; live max is closer to `+45` since no single token hits every positive indicator simultaneously). Buy threshold: `>= 15`. Sum of the five `*_performance` fields below.
|
|
80
|
+
| Field | Contribution | Trigger | What the underlying indicator measures |
|
|
81
|
+
|---|---|---|---|
|
|
82
|
+
| `price_momentum_performance` | +30 / 0 | upstream score `bullish` → +30 | Price momentum, scored against separate thresholds for large-cap vs. low/mid-cap tokens. |
|
|
83
|
+
| `chain_fees_performance` | +30 / 0 | `bullish` (30-day fee growth > +1%) → +30 | 30-day spending momentum on network fees (geometric mean of daily returns). **Only tracked for a handful of L1 native tokens (e.g. ETH, TRX, AVAX, RON); always 0 for every other token.** |
|
|
84
|
+
| `trading_range_performance` | +15 / 0 | `bullish` (price breaks above resistance in an uptrend) → +15 | 14-day price trend combined with position vs. nearest support/resistance. In practice fires mostly on established tokens that have well-defined levels — can fire at any market cap, but is rare for new / low-liquidity tokens. |
|
|
85
|
+
| `chain_tvl_performance` | 0 / -35 | `bearish` (composite TVL growth < 0) → -35 | TVL momentum composite signal. Only non-zero for chains / L2s whose TVL is tracked. No positive path exists — the field only deducts. |
|
|
86
|
+
| `protocol_fees_performance` | 0 / -25 | `bearish` (14-day fee growth < -3%) → -25 | 14-day protocol fee momentum. Only non-zero for tokens backed by protocols with measurable fee revenue. No positive path — deduction only. |
|
|
87
|
+
|
|
88
|
+
**Risk Score (Safety — "filters falling knives / dangerous setups")**
|
|
89
|
+
Range: `-60 to +80` (arithmetic bounds). Safety threshold: `> 0` (positive = safer, negative = riskier). Sum of the four `*_risk` fields below. For every risk field: upstream score `low` → positive contribution, `high` → negative contribution, `medium`/missing → 0.
|
|
90
|
+
| Field | Contribution | What the underlying indicator measures |
|
|
91
|
+
|---|---|---|
|
|
92
|
+
| `btc_reflexivity_risk` | +40 / -20 | Rolling 5-event median ratio of token drop to BTC drop on days BTC falls >3%. Ratio ≤ 1 → `low` → **+40** (token holds up as well as or better than BTC on drawdowns). Ratio > 1 → `high` → **-20** (token drops harder than BTC). Skipped for stablecoins and tokens with <$1M 24h volume. |
|
|
93
|
+
| `liquidity_risk` | +20 / -20 | Ratio of on-chain liquidity to market cap (`total_liquidity_usd / market_cap_usd`). Higher ratio → `low` → **+20** (deep books relative to cap). Very thin ratio → `high` → **-20**. |
|
|
94
|
+
| `concentration_risk` | +10 / -10 | Top-10 holder concentration as a fraction of supply. `< 0.12` → `low` → **+10** (well-distributed). `> 0.55` → `high` → **-10** (whale-concentrated). |
|
|
95
|
+
| `inflation_risk` | +10 / -10 | EMA of daily token supply inflation rate. Negative / near-zero → `low` → **+10** (stable or deflationary supply). Strongly positive → `high` → **-10** (high dilution). Only evaluated for tokens >= $100M market cap. |
|
|
96
|
+
|
|
97
|
+
Other response fields:
|
|
98
|
+
- `market_cap_group`: `lowcap` / `midcap` / `largecap` — see thresholds above.
|
|
99
|
+
- `latest_date`: ISO datetime of the most recent indicator refresh for this token.
|
|
100
|
+
- `last_trigger_on`: ISO datetime of the most recent trigger across contributing indicators (MAX aggregate — individual indicators may be days-to-months stale even when this looks fresh). Use `indicators` on a specific token to audit per-indicator ages.
|
|
101
|
+
|
|
102
|
+
**Stablecoins rank high but aren't picks.** USDC, USDT, DAI, FDUSD and similar score well on chain_fees + liquidity indicators but aren't what "what should I buy" means. Filter them out of the shortlist using the canonical whitelist at `nansen-dbt-ch-tokens/seeds/stablecoins_for_indicator.csv` before drilling into `indicators`.
|
|
103
|
+
|
|
104
|
+
Typical workflow: start with `top-tokens` for a shortlist → drop stablecoins → run `indicators` on the top 3–5 to inspect individual signals and their signal_percentile → `flow-intelligence` only on the finalists to confirm SM conviction.
|
|
105
|
+
|
|
106
|
+
Field meanings and contribution mappings above are sourced from `nansen-dbt-ch-tokens/models/indicators/api_nansen_score_indicators_all_tokens_latest.sql` and per-indicator model yml files. Sign conventions and live value ranges were validated against production ClickHouse data.
|
|
107
|
+
|
|
54
108
|
Flow intelligence is credit-heavy. Use it to confirm SM conviction on tokens that already look promising from screener + indicators, not as a first pass on every token.
|
package/src/api.js
CHANGED
|
@@ -1203,6 +1203,13 @@ export class NansenAPI {
|
|
|
1203
1203
|
});
|
|
1204
1204
|
}
|
|
1205
1205
|
|
|
1206
|
+
async topTokens(params = {}) {
|
|
1207
|
+
const { marketCapGroup, limit = 25 } = params;
|
|
1208
|
+
const body = { limit };
|
|
1209
|
+
if (marketCapGroup) body.market_cap_group = marketCapGroup;
|
|
1210
|
+
return this.request('/api/v1/nansen-score/top-tokens', body);
|
|
1211
|
+
}
|
|
1212
|
+
|
|
1206
1213
|
// ============= Perp Endpoints =============
|
|
1207
1214
|
|
|
1208
1215
|
async perpScreener(params = {}) {
|
package/src/cli.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { NansenAPI, NansenError, CommandError, ErrorCode, saveConfig, deleteConfig, getConfigFile, clearCache, getCacheDir, validateAddress, normalizeAddress, sleep } from './api.js';
|
|
7
7
|
import { buildWalletCommands } from './wallet.js';
|
|
8
8
|
import { buildTradingCommands } from './trading.js';
|
|
9
|
+
import { buildLimitOrderCommands } from './limit-order.js';
|
|
9
10
|
import { formatAlertsTable, buildAlertsCommands } from './commands/alerts.js';
|
|
10
11
|
import { buildAgentCommands } from './commands/agent.js';
|
|
11
12
|
import { resolveAddress, isEnsName } from './ens.js';
|
|
@@ -1276,8 +1277,13 @@ export function buildCommands(deps = {}) {
|
|
|
1276
1277
|
const withLabels = resolveBooleanOption(options, flags, 'premium-labels');
|
|
1277
1278
|
return apiInstance.tokenPerpPnlLeaderboard({ tokenSymbol, filters, orderBy, pagination, days, withLabels });
|
|
1278
1279
|
},
|
|
1280
|
+
'top-tokens': () => {
|
|
1281
|
+
const marketCapGroup = options['market-cap'] || options['market-cap-group'];
|
|
1282
|
+
const limit = options.limit ? parseInt(options.limit) : undefined;
|
|
1283
|
+
return apiInstance.topTokens({ marketCapGroup, limit });
|
|
1284
|
+
},
|
|
1279
1285
|
'help': () => ({
|
|
1280
|
-
commands: ['info', 'ohlcv', 'screener', 'holders', 'flows', 'dex-trades', 'pnl', 'who-bought-sold', 'flow-intelligence', 'transfers', 'jup-dca', 'perp-trades', 'perp-positions', 'perp-pnl-leaderboard'],
|
|
1286
|
+
commands: ['info', 'ohlcv', 'screener', 'holders', 'flows', 'dex-trades', 'pnl', 'who-bought-sold', 'flow-intelligence', 'transfers', 'jup-dca', 'perp-trades', 'perp-positions', 'perp-pnl-leaderboard', 'top-tokens'],
|
|
1281
1287
|
description: 'Token God Mode endpoints',
|
|
1282
1288
|
example: 'nansen token screener --chain solana --timeframe 24h --smart-money --include-stablecoins false'
|
|
1283
1289
|
})
|
|
@@ -1474,8 +1480,9 @@ export function buildCommands(deps = {}) {
|
|
|
1474
1480
|
return cmds[category](args.slice(1), apiInstance, flags, options);
|
|
1475
1481
|
};
|
|
1476
1482
|
|
|
1477
|
-
// 'trade' delegates to quote/execute from buildTradingCommands
|
|
1483
|
+
// 'trade' delegates to quote/execute from buildTradingCommands and limit-order from buildLimitOrderCommands
|
|
1478
1484
|
const tradingCmds = buildTradingCommands(deps);
|
|
1485
|
+
const limitOrderCmds = buildLimitOrderCommands(deps);
|
|
1479
1486
|
cmds['trade'] = async (args, apiInstance, flags, options) => {
|
|
1480
1487
|
const sub = args[0];
|
|
1481
1488
|
if (!sub || sub === 'help') {
|
|
@@ -1485,12 +1492,14 @@ SUBCOMMANDS:
|
|
|
1485
1492
|
quote Get a swap quote (price, route, fees)
|
|
1486
1493
|
execute Sign and broadcast a quoted swap
|
|
1487
1494
|
bridge-status Check cross-chain bridge transaction status
|
|
1495
|
+
limit-order Limit order management (Solana only)
|
|
1488
1496
|
|
|
1489
1497
|
USAGE:
|
|
1490
1498
|
nansen trade quote --chain <chain> --from <token> --to <token> --amount <units> [--wallet <name>]
|
|
1491
1499
|
nansen trade quote --chain <chain> --to-chain <chain> --from <token> --to <token> --amount <units>
|
|
1492
1500
|
nansen trade execute --quote <quoteId> [--wallet <name>]
|
|
1493
1501
|
nansen trade bridge-status --tx-hash <hash> --from-chain <chain> --to-chain <chain>
|
|
1502
|
+
nansen trade limit-order <create|list|cancel|update> [options]
|
|
1494
1503
|
|
|
1495
1504
|
EXAMPLES:
|
|
1496
1505
|
nansen trade quote --chain solana --from SOL --to USDC --amount 1000000000
|
|
@@ -1498,18 +1507,53 @@ EXAMPLES:
|
|
|
1498
1507
|
nansen trade quote --chain base --to-chain solana --from USDC --to USDC --amount 1000000
|
|
1499
1508
|
nansen trade execute --quote 1708900000000-abc123
|
|
1500
1509
|
nansen trade bridge-status --tx-hash 0xabc... --from-chain base --to-chain solana
|
|
1510
|
+
nansen trade limit-order create --from SOL --to USDC --amount 1000000000 --trigger-mint SOL --trigger-condition below --trigger-price 80
|
|
1511
|
+
nansen trade limit-order list
|
|
1501
1512
|
|
|
1502
1513
|
WALLET:
|
|
1503
|
-
--wallet <name> Use a named wallet, or "walletconnect" / "wc" for WalletConnect
|
|
1514
|
+
--wallet <name> Use a named wallet, or "walletconnect" / "wc" for WalletConnect.
|
|
1504
1515
|
Defaults to the default local wallet if omitted.
|
|
1505
1516
|
|
|
1506
1517
|
SYMBOLS:
|
|
1507
1518
|
Common tokens resolve automatically: SOL, ETH, USDC, USDT, WETH
|
|
1508
|
-
Raw addresses are also accepted
|
|
1519
|
+
Raw addresses are also accepted.
|
|
1520
|
+
|
|
1521
|
+
CROSS-CHAIN NOTES (when using --to-chain):
|
|
1522
|
+
Supported combos:
|
|
1523
|
+
native → native (ETH <-> SOL) — requires $5+ per trade
|
|
1524
|
+
USDC → USDC (both directions)
|
|
1525
|
+
USDC → native (USDC → ETH or SOL)
|
|
1526
|
+
native → USDC (ETH/SOL → USDC)
|
|
1527
|
+
non-native → non-native — not supported (use USDC as intermediate)
|
|
1528
|
+
Bridge provider: Li.Fi
|
|
1529
|
+
Typical bridge time: 1-5 minutes`);
|
|
1509
1530
|
return;
|
|
1510
1531
|
}
|
|
1532
|
+
if (sub === 'limit-order') {
|
|
1533
|
+
const loSub = args[1];
|
|
1534
|
+
if (!loSub || loSub === 'help') {
|
|
1535
|
+
log(`nansen trade limit-order — Limit order commands (Solana only)
|
|
1536
|
+
|
|
1537
|
+
SUBCOMMANDS:
|
|
1538
|
+
create Place a new limit order
|
|
1539
|
+
list List your limit orders
|
|
1540
|
+
cancel Cancel an open order
|
|
1541
|
+
update Update trigger price or slippage
|
|
1542
|
+
|
|
1543
|
+
USAGE:
|
|
1544
|
+
nansen trade limit-order create --from <token> --to <token> --amount <units> --trigger-mint <token> --trigger-condition <above|below> --trigger-price <usd>
|
|
1545
|
+
nansen trade limit-order list [--state <active|past>]
|
|
1546
|
+
nansen trade limit-order cancel --order <orderId>
|
|
1547
|
+
nansen trade limit-order update --order <orderId> --trigger-price <usd>`);
|
|
1548
|
+
return;
|
|
1549
|
+
}
|
|
1550
|
+
if (!limitOrderCmds[loSub]) {
|
|
1551
|
+
throw new NansenError(`Unknown limit-order subcommand: ${loSub}. Available: create, list, cancel, update`, ErrorCode.UNKNOWN);
|
|
1552
|
+
}
|
|
1553
|
+
return limitOrderCmds[loSub](args.slice(2), apiInstance, flags, options);
|
|
1554
|
+
}
|
|
1511
1555
|
if (!tradingCmds[sub]) {
|
|
1512
|
-
throw new NansenError(`Unknown trade subcommand: ${sub}. Available: quote, execute, bridge-status`, ErrorCode.UNKNOWN);
|
|
1556
|
+
throw new NansenError(`Unknown trade subcommand: ${sub}. Available: quote, execute, bridge-status, limit-order`, ErrorCode.UNKNOWN);
|
|
1513
1557
|
}
|
|
1514
1558
|
return tradingCmds[sub](args.slice(1), apiInstance, flags, options);
|
|
1515
1559
|
};
|
package/src/keychain.js
CHANGED