nansen-cli 1.41.0 → 1.42.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 +47 -0
- package/README.md +33 -7
- package/package.json +1 -1
- package/scripts/postinstall.js +3 -3
- package/skills/nansen-wallet-manager/SKILL.md +5 -5
- package/src/api.js +11 -5
- package/src/bridge.js +791 -55
- package/src/cli.js +68 -41
- package/src/commands/agent.js +4 -0
- package/src/commands/mcp.js +373 -0
- package/src/doctor.js +16 -7
- package/src/limit-order.js +16 -2
- package/src/mcp-verify.js +292 -0
- package/src/privy.js +12 -2
- package/src/schema.json +55 -0
- package/src/swap-simulation.js +6 -0
- package/src/trade-validation.js +185 -37
- package/src/trading.js +208 -31
- package/src/wallet.js +20 -14
- package/src/x402-svm.js +9 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,52 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.42.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#508](https://github.com/nansen-ai/nansen-cli/pull/508) [`3fc6e6b`](https://github.com/nansen-ai/nansen-cli/commit/3fc6e6b3083d3a8e0ab738c800bbcaf24dc00bef) Thanks [@gulshngill](https://github.com/gulshngill)! - Add `nansen mcp verify` to verify the hosted Nansen MCP setup with an authenticated data-path check.
|
|
8
|
+
|
|
9
|
+
- [#487](https://github.com/nansen-ai/nansen-cli/pull/487) [`bb3f33e`](https://github.com/nansen-ai/nansen-cli/commit/bb3f33ea28642effbda911012dec8810adc8d40c) Thanks [@gulshngill](https://github.com/gulshngill)! - Add `nansen mcp install <client>` / `nansen mcp uninstall <client>` for one-step setup of the hosted Nansen MCP server (https://mcp.nansen.ai/ra/mcp) in Claude Code, Claude Desktop, and Cursor. Writes are merge-only and atomic (existing servers preserved, `.bak` backup on install and uninstall, refuses unparseable configs), use the API key from `nansen login` / `NANSEN_API_KEY`, never print the key, and support `--dry-run`.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#536](https://github.com/nansen-ai/nansen-cli/pull/536) [`f5e48df`](https://github.com/nansen-ai/nansen-cli/commit/f5e48dfddc9f063225847f54ed4b20334cadc6ae) Thanks [@kome12](https://github.com/kome12)! - `bridge quote` now prints a notice when a Hyperliquid USDC amount is floored to the 6-decimal precision the bridge signs, instead of adjusting the amount silently. The adjustment is unchanged (it's what keeps the persisted amount matching what gets signed); it's just no longer hidden.
|
|
14
|
+
|
|
15
|
+
- [#533](https://github.com/nansen-ai/nansen-cli/pull/533) [`a96418d`](https://github.com/nansen-ai/nansen-cli/commit/a96418d4c7af5d8f8874f7ccb27d1d59ce797098) Thanks [@kome12](https://github.com/kome12)! - Bridge withdrawals now verify the Hyperliquid action's type, amount, network, and source token/routing fields against your request before signing, so a tampered quote cannot inflate a withdrawal, swap in a different token, or authorize on another account. The deposit action's EIP-712 primary type and exact ordered field list are now pinned too — not just the shared signing domain — so a quote can no longer pass every value check yet have the wallet sign a differently shaped Hyperliquid action (e.g. an agent approval) that the amount cap doesn't bound. The relayer authorization step is likewise pinned exactly to its real EIP-712 domain, field shape, and signing wallet, and its signature can only ever be submitted to the relayer's own fixed authorize endpoint — closing a gap where a malicious quote could have requested a signature over unrelated typed data and relayed it elsewhere. All of a withdrawal's steps are verified against this before any of them are signed or posted, so a bad step later in a multi-step quote (e.g. the real [authorize, sendAsset] order) can no longer let an earlier, valid-looking step reach the relayer or Hyperliquid first.
|
|
16
|
+
|
|
17
|
+
Also fixes a false rejection: Hyperliquid withdrawals whose `--amount` was given in base units (the default, no `--amount-unit`) and whose last two digits weren't zero were rejected at execute time as an amount mismatch, because the amount wasn't floored to the 6-decimal precision the bridge actually sends. Base-unit amounts are now floored the same way `--amount-unit` amounts already were, so these withdrawals execute.
|
|
18
|
+
|
|
19
|
+
- [#530](https://github.com/nansen-ai/nansen-cli/pull/530) [`4312b50`](https://github.com/nansen-ai/nansen-cli/commit/4312b5004e0644f0bfcdac2e5e3eda7128958d92) Thanks [@kome12](https://github.com/kome12)! - Trade safety: tolerate a bounded native-token fee on cross-chain bridge swaps. The pre-signing swap-outcome check rejected any non-input token leaving the wallet, which could reject a legitimate bridge that pays its network fee in the native token on a token-input route. The tolerance is capped and applies only to the native token on bridges; every other token, and all same-chain swaps, stay strict.
|
|
20
|
+
|
|
21
|
+
- [#537](https://github.com/nansen-ai/nansen-cli/pull/537) [`2d630d5`](https://github.com/nansen-ai/nansen-cli/commit/2d630d545161d656b41867d7b439e02c0786a01f) Thanks [@kome12](https://github.com/kome12)! - Fix `nansen mcp verify` routing after merging MCP install commands.
|
|
22
|
+
|
|
23
|
+
- [#538](https://github.com/nansen-ai/nansen-cli/pull/538) [`853c48a`](https://github.com/nansen-ai/nansen-cli/commit/853c48ac1779e42507513c7c47a8f57bbffd540d) Thanks [@kome12](https://github.com/kome12)! - Harden the Hyperliquid bridge deposit leg: EVM approvals are now re-scoped to the requested amount (never unlimited) and the deposit target contract/method is pinned, so a tampered quote can't drain the wallet.
|
|
24
|
+
|
|
25
|
+
- [#534](https://github.com/nansen-ai/nansen-cli/pull/534) [`e23af5c`](https://github.com/nansen-ai/nansen-cli/commit/e23af5cd111eb596dda9f3b6c88b32ffa3e5e756) Thanks [@gulshngill](https://github.com/gulshngill)! - Credential hygiene: `nansen login` verification failures cannot relay the API
|
|
26
|
+
key, invalid-key remediation points at key management, and login guidance leads
|
|
27
|
+
with paths that avoid shell history. Every request that carries a credential —
|
|
28
|
+
API key, agent, limit-order JWT/X-API-Key, MCP verify, and Privy auth — now
|
|
29
|
+
refuses to follow HTTP redirects, so a credential can't be relayed to a redirect
|
|
30
|
+
target. Interactive password and API-key prompts stay masked (no cleartext echo)
|
|
31
|
+
even when stdout is redirected.
|
|
32
|
+
|
|
33
|
+
- [#529](https://github.com/nansen-ai/nansen-cli/pull/529) [`45b8584`](https://github.com/nansen-ai/nansen-cli/commit/45b8584ba8e2a3859612d8702dd78f117911cf87) Thanks [@gulshngill](https://github.com/gulshngill)! - Docs: stop pointing at the retired Cursor install deep link, pin the
|
|
34
|
+
`mcp-remote` bridge to the version `mcp install` writes, and correct the
|
|
35
|
+
header-formatting note (whitespace after the colon is trimmed; the key belongs
|
|
36
|
+
in `env`, not in the argument list).
|
|
37
|
+
|
|
38
|
+
- [#531](https://github.com/nansen-ai/nansen-cli/pull/531) [`9bb44a7`](https://github.com/nansen-ai/nansen-cli/commit/9bb44a7339e80bba30d9ec2e499b5d3e306ceb66) Thanks [@crazywriter1](https://github.com/crazywriter1)! - Honor the original HTTP method on x402 paid retries so GET/DELETE/PATCH requests are not resent as POST after payment.
|
|
39
|
+
|
|
40
|
+
## 1.41.1
|
|
41
|
+
|
|
42
|
+
### Patch Changes
|
|
43
|
+
|
|
44
|
+
- [#527](https://github.com/nansen-ai/nansen-cli/pull/527) [`02efb6d`](https://github.com/nansen-ai/nansen-cli/commit/02efb6d1f40453c03135eb68cf493486a5b6133a) Thanks [@kome12](https://github.com/kome12)! - Cross-chain (bridge) swaps now run swap-outcome verification instead of skipping it entirely. The output-arrival check is still skipped (the output settles on the destination chain), but the input-outflow cap and no-sibling-drain checks now run on the source-chain leg, closing a gap where a compromised quote's bridge instructions could move more than the declared input. Bridges also now enforce an intent-relative lower bound on the source-chain input outflow (an exactIn bridge must spend ~the requested input, so a large fee-only or partial no-op no longer verifies) and still validate the quote's output-amount integrity, and the native-SOL bridge log no longer contradicts itself about whether the output check ran. Note the lower bound relaxes by a native-SOL fee/rent allowance (~0.013 SOL), so on a small native-SOL leg at or below that allowance the floor effectively collapses to a bare "outflow > 0" — the tightest bound possible for a native leg whose fees are indistinguishable from the transfer. `--swap-mode` is now validated against `exactIn`/`exactOut` at the CLI, and both the swap-outcome verifier and the pre-signing request-intent completeness checks fail closed on an unrecognized mode in a persisted quote so a garbage value cannot bypass the exactIn input floor — even when outcome verification is skipped or degraded.
|
|
45
|
+
|
|
46
|
+
Because bridges now go through the simulation, a bridge quote that **reverts in simulation** returns `proceed: false` and is dropped (the signing loop falls through to the next quote); only a simulation that cannot run at all (`NO_SIM_RPC` / `SIM_RPC_ERROR` / `NOT_SIM_CAPABLE`) degrades to proceed-without-verification, matching same-chain swaps. This is a new, fail-closed outcome for bridges specifically.
|
|
47
|
+
|
|
48
|
+
- [#513](https://github.com/nansen-ai/nansen-cli/pull/513) [`55eb953`](https://github.com/nansen-ai/nansen-cli/commit/55eb953cc15fe21aa441d1700e05ef053c643a58) Thanks [@kome12](https://github.com/kome12)! - Fix `trade execute` crashing on Solana-source bridge quotes from the Relay aggregator, which return raw uncompiled instructions instead of a ready-to-sign transaction. These are now compiled client-side before signing.
|
|
49
|
+
|
|
3
50
|
## 1.41.0
|
|
4
51
|
|
|
5
52
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -20,17 +20,27 @@ Three options — pick whichever fits your setup:
|
|
|
20
20
|
|
|
21
21
|
1. **API key** (subscription):
|
|
22
22
|
```bash
|
|
23
|
-
nansen login --
|
|
24
|
-
nansen login
|
|
25
|
-
|
|
26
|
-
nansen logout # remove saved key
|
|
23
|
+
nansen login --human # interactive prompt; saves to ~/.nansen/config.json
|
|
24
|
+
nansen login # uses NANSEN_API_KEY when already set
|
|
25
|
+
nansen logout # remove saved key
|
|
27
26
|
```
|
|
27
|
+
For automation, inject `NANSEN_API_KEY` through your environment or secret manager.
|
|
28
28
|
Get your API key at [app.nansen.ai/auth/agent-setup](https://app.nansen.ai/auth/agent-setup).
|
|
29
29
|
|
|
30
30
|
2. **x402 micropayment** (no key needed): `nansen wallet create`, fund with USDC on Base or Solana, or USDT0 on X Layer, then call any endpoint — the CLI signs `Payment-Signature` headers automatically on 402 responses. See [Wallet](#wallet).
|
|
31
31
|
|
|
32
32
|
3. **MPP via tempo** (no key needed): install the [tempo CLI](https://docs.tempo.xyz) separately, run `tempo wallet login` to set up, then call the Nansen API through `tempo request`. The Nansen API selects the MPP rail when it sees `Authorization: Payment ...`. See [MPP / Tempo](#mpp--tempo) below.
|
|
33
33
|
|
|
34
|
+
## Verify your MCP setup
|
|
35
|
+
|
|
36
|
+
For the hosted Nansen MCP server, verify server reachability and the supplied API key on the paid data path with:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx -y nansen-cli mcp verify # uses the saved key or NANSEN_API_KEY
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The check calls `tools/list` for reachability, then calls the paid `nansen_score_top_tokens` canary tool. A successful canary costs about 1 credit; tool listings and free tools alone do not prove that a key works. The CLI cannot inspect the key inside your MCP client, so make sure this same key is in the client's `NANSEN-API-KEY` header. For the final client-config check, ask your client: “Use the `nansen_score_top_tokens` tool.”
|
|
43
|
+
|
|
34
44
|
## Commands
|
|
35
45
|
|
|
36
46
|
```
|
|
@@ -40,6 +50,7 @@ nansen agent "<question>" --expert # deeper analysis (750 credits, Pro)
|
|
|
40
50
|
nansen trade quote --chain solana --from SOL --to USDC --amount 1000000000
|
|
41
51
|
nansen trade execute --quote <quoteId>
|
|
42
52
|
nansen wallet <subcommand> [options]
|
|
53
|
+
nansen mcp install <client> # add the Nansen MCP server to Claude Code/Desktop or Cursor
|
|
43
54
|
nansen schema [command] [--pretty] # full command reference (no API key needed)
|
|
44
55
|
```
|
|
45
56
|
|
|
@@ -59,7 +70,19 @@ Connect any MCP client to Nansen's streamable HTTP server:
|
|
|
59
70
|
- **Authentication:** `NANSEN-API-KEY` header
|
|
60
71
|
- **API key:** [app.nansen.ai/auth/agent-setup](https://app.nansen.ai/auth/agent-setup)
|
|
61
72
|
|
|
62
|
-
|
|
73
|
+
One-step install of the hosted [Nansen MCP server](https://docs.nansen.ai/mcp/overview) (`https://mcp.nansen.ai/ra/mcp`) into a local MCP client:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
nansen mcp install claude-code # ~/.claude.json (user scope)
|
|
77
|
+
nansen mcp install claude-desktop # macOS/Windows only; bridges via pinned mcp-remote
|
|
78
|
+
nansen mcp install cursor # ~/.cursor/mcp.json
|
|
79
|
+
nansen mcp install cursor --dry-run # print what would be written (key redacted)
|
|
80
|
+
nansen mcp uninstall <client> # remove the entry (add --dry-run to preview)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Uses the API key from `nansen login` / `NANSEN_API_KEY`; re-run `install` after rotating your key. Writes are merge-only and atomic: existing servers and settings are preserved, a `.bak` copy is written before every install or uninstall, and the CLI refuses to touch a config it can't parse. Note the client config stores the API key in plaintext — new files are created with `0600` permissions. Restart the client after installing.
|
|
84
|
+
|
|
85
|
+
**Manual setup**, for other clients or if you would rather not use the CLI — the paths below, and the connection docs at [docs.nansen.ai/mcp/connecting](https://docs.nansen.ai/mcp/connecting).
|
|
63
86
|
|
|
64
87
|
**One-command (Claude Code):**
|
|
65
88
|
|
|
@@ -82,7 +105,7 @@ claude mcp add --transport http nansen https://mcp.nansen.ai/ra/mcp --header "NA
|
|
|
82
105
|
}
|
|
83
106
|
```
|
|
84
107
|
|
|
85
|
-
**Manual (stdio-only clients):** use `mcp-remote` as a bridge. Keep the header
|
|
108
|
+
**Manual (stdio-only clients):** use `mcp-remote` as a bridge. Keep the header name and value in a single `args` entry, and keep the key in `env` rather than in the argument list — `mcp-remote` substitutes `${NANSEN_API_KEY}` from the environment:
|
|
86
109
|
|
|
87
110
|
```json
|
|
88
111
|
{
|
|
@@ -91,7 +114,7 @@ claude mcp add --transport http nansen https://mcp.nansen.ai/ra/mcp --header "NA
|
|
|
91
114
|
"command": "npx",
|
|
92
115
|
"args": [
|
|
93
116
|
"-y",
|
|
94
|
-
"mcp-remote@
|
|
117
|
+
"mcp-remote@0.2.1",
|
|
95
118
|
"https://mcp.nansen.ai/ra/mcp",
|
|
96
119
|
"--header",
|
|
97
120
|
"NANSEN-API-KEY:${NANSEN_API_KEY}"
|
|
@@ -104,6 +127,8 @@ claude mcp add --transport http nansen https://mcp.nansen.ai/ra/mcp --header "NA
|
|
|
104
127
|
}
|
|
105
128
|
```
|
|
106
129
|
|
|
130
|
+
`mcp-remote` is pinned to an exact version rather than `@latest` because the bridge handles your API key on every request, and `npx` would otherwise pull a new release automatically. `0.2.1` is the current release and the version this config is tested against; bumping it is safe — review the release and update the pin.
|
|
131
|
+
|
|
107
132
|
**Claude Tag (Claude in Slack):** an admin must attach a plugin whose `.mcp.json` points at `https://mcp.nansen.ai/ra/mcp` and add a custom credential allowing the host `mcp.nansen.ai`. See the [Claude Tag custom-connections documentation](https://claude.com/docs/claude-tag/admins/connections/custom). Per-user fallback: use Claude Code or Claude Desktop.
|
|
108
133
|
|
|
109
134
|
## Trading
|
|
@@ -294,6 +319,7 @@ Any field may be absent or `null`, meaning unknown — never assume zero. A low-
|
|
|
294
319
|
| `command not found` | `npm install -g nansen-cli` |
|
|
295
320
|
| Global install reports an older version | `npm i -g nansen-cli@latest --registry=https://registry.npmjs.org/ --prefer-online`, then check `which -a nansen` for stale binaries |
|
|
296
321
|
| `UNAUTHORIZED` after login | `nansen auth status` shows which key is active and where it comes from; re-run `nansen login` or set `NANSEN_API_KEY` |
|
|
322
|
+
| MCP client lists tools but paid calls fail | Run `npx -y nansen-cli mcp verify` with the saved key or `NANSEN_API_KEY`, and ensure that same key is in the client's `NANSEN-API-KEY` header |
|
|
297
323
|
| Anything else misbehaving | `nansen doctor` checks your whole setup (auth, wallets, caches, connectivity) with a fix per finding |
|
|
298
324
|
| Empty perp _research_ results | Use `--symbol BTC`, not `--token`. Perps are Hyperliquid-only. |
|
|
299
325
|
| `perp` _trading_ prints the usage banner | Trading needs `--coin BTC` (`--symbol` also works); see the Perpetuals section. |
|
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -132,7 +132,7 @@ async function installSkill() {
|
|
|
132
132
|
async function testQuery() {
|
|
133
133
|
if (!isLoggedIn()) {
|
|
134
134
|
log();
|
|
135
|
-
log(`Not logged in yet. Run ${CYAN}nansen login --
|
|
135
|
+
log(`Not logged in yet. Run ${CYAN}nansen login --human${RESET} to authenticate.`);
|
|
136
136
|
log(`Get your API key at: ${CYAN}https://app.nansen.ai/auth/agent-setup${RESET}`);
|
|
137
137
|
return;
|
|
138
138
|
}
|
|
@@ -156,7 +156,7 @@ async function testQuery() {
|
|
|
156
156
|
log(`${GREEN}✓${RESET} All set! Run ${CYAN}nansen help${RESET} to see all available commands.`);
|
|
157
157
|
} else {
|
|
158
158
|
log();
|
|
159
|
-
log(`${YELLOW}Query failed. Check your API key with: nansen
|
|
159
|
+
log(`${YELLOW}Query failed. Check your API key with: nansen auth status${RESET}`);
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
|
|
@@ -172,7 +172,7 @@ async function main() {
|
|
|
172
172
|
log(`${BOLD}Nansen CLI installed!${RESET}`);
|
|
173
173
|
log();
|
|
174
174
|
log(`Tip: Run '${CYAN}npx skills add ${SKILL_REPO}${RESET}' to install the Nansen AI coding skill.`);
|
|
175
|
-
log(`Tip: Run '${CYAN}nansen login --
|
|
175
|
+
log(`Tip: Run '${CYAN}nansen login --human${RESET}' to authenticate.`);
|
|
176
176
|
log(`Tip: To trade, first create a wallet with '${CYAN}nansen wallet create${RESET}', then quote with '${CYAN}nansen trade quote --chain solana --from SOL --to USDC --amount 1000000000${RESET}' and execute with '${CYAN}nansen trade execute --quote <id>${RESET}'.`);
|
|
177
177
|
return;
|
|
178
178
|
}
|
|
@@ -21,10 +21,10 @@ allowed-tools: Bash(nansen:*)
|
|
|
21
21
|
## Auth Setup
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
# Save API key
|
|
25
|
-
nansen login --
|
|
26
|
-
# Or
|
|
27
|
-
|
|
24
|
+
# Save API key interactively
|
|
25
|
+
nansen login --human
|
|
26
|
+
# Or use NANSEN_API_KEY after provisioning it through your environment/secret manager
|
|
27
|
+
nansen login
|
|
28
28
|
|
|
29
29
|
# Verify
|
|
30
30
|
nansen research profiler labels --address 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --chain ethereum
|
|
@@ -190,7 +190,7 @@ For detailed migration steps (from `~/.nansen/.env`, `.credentials`, or env-var-
|
|
|
190
190
|
| Var | Purpose |
|
|
191
191
|
|-----|---------|
|
|
192
192
|
| `NANSEN_WALLET_PASSWORD` | Wallet encryption password — only needed for initial `wallet create`. After that, the OS keychain handles it. |
|
|
193
|
-
| `NANSEN_API_KEY` | API key (also
|
|
193
|
+
| `NANSEN_API_KEY` | API key (can also be saved via `nansen login --human`) |
|
|
194
194
|
| `PRIVY_APP_ID` | Privy application ID (required for `--provider privy`) |
|
|
195
195
|
| `PRIVY_APP_SECRET` | Privy application secret (required for `--provider privy`) |
|
|
196
196
|
| `NANSEN_WALLET_PROVIDER` | Default provider for wallet create — `local` or `privy` |
|
package/src/api.js
CHANGED
|
@@ -538,7 +538,7 @@ export class NansenAPI {
|
|
|
538
538
|
* @param {string|null} network - x402 network string for balance check, e.g. "eip155:8453"
|
|
539
539
|
* @param {string} url - Request URL
|
|
540
540
|
* @param {object} body - Request body (will be cleaned)
|
|
541
|
-
* @param {object} [options={}] - Request options (may include .headers)
|
|
541
|
+
* @param {object} [options={}] - Request options (may include .method, .headers)
|
|
542
542
|
* @returns {Promise<object|null>} Parsed JSON on success, null if rejected
|
|
543
543
|
*
|
|
544
544
|
* TODO: full fix — extract the entire x402 provider dispatch from request() into
|
|
@@ -546,10 +546,15 @@ export class NansenAPI {
|
|
|
546
546
|
* touching that one method, not hunting inside the retry loop.
|
|
547
547
|
*/
|
|
548
548
|
async _x402Retry(signature, walletLabel, network, url, body, options = {}, asset = null) {
|
|
549
|
+
// Mirror request(): paid retries must use the original method. Hardcoding
|
|
550
|
+
// POST burned a payment signature then hit the wrong route for GET/DELETE/PATCH.
|
|
551
|
+
const method = options.method || 'POST';
|
|
552
|
+
const isGet = method === 'GET';
|
|
549
553
|
const paidResponse = await fetch(url, {
|
|
550
|
-
method
|
|
554
|
+
method,
|
|
555
|
+
redirect: 'error',
|
|
551
556
|
headers: {
|
|
552
|
-
'Content-Type': 'application/json',
|
|
557
|
+
...(!isGet && { 'Content-Type': 'application/json' }),
|
|
553
558
|
'X-Client-Type': 'nansen-cli',
|
|
554
559
|
'X-Client-Version': packageVersion,
|
|
555
560
|
...telemetryHeaders(),
|
|
@@ -557,7 +562,7 @@ export class NansenAPI {
|
|
|
557
562
|
...this.defaultHeaders,
|
|
558
563
|
...options.headers,
|
|
559
564
|
},
|
|
560
|
-
body: JSON.stringify(NansenAPI.cleanBody(body)),
|
|
565
|
+
...(!isGet && method !== 'DELETE' && { body: JSON.stringify(NansenAPI.cleanBody(body)) }),
|
|
561
566
|
});
|
|
562
567
|
if (!paidResponse.ok) return null;
|
|
563
568
|
if (walletLabel) {
|
|
@@ -605,6 +610,7 @@ export class NansenAPI {
|
|
|
605
610
|
const isGet = method === 'GET';
|
|
606
611
|
response = await fetch(url, {
|
|
607
612
|
method,
|
|
613
|
+
redirect: 'error',
|
|
608
614
|
headers: {
|
|
609
615
|
...(!isGet && { 'Content-Type': 'application/json' }),
|
|
610
616
|
'X-Client-Type': 'nansen-cli',
|
|
@@ -747,7 +753,7 @@ export class NansenAPI {
|
|
|
747
753
|
} catch (x402Err) {
|
|
748
754
|
if (!this.apiKey) {
|
|
749
755
|
message = 'No API key configured. Three ways to authenticate:\n' +
|
|
750
|
-
' 1. API key: nansen login --
|
|
756
|
+
' 1. API key: run `nansen login --human` or set NANSEN_API_KEY (get key at https://app.nansen.ai/auth/agent-setup)\n' +
|
|
751
757
|
' 2. x402 micropayment: nansen wallet create + fund with USDC on Base/Solana or USDT0 on X Layer (no API key needed)\n' +
|
|
752
758
|
' 3. MPP via tempo: install tempo CLI, run `tempo wallet login`, then call the API with `tempo request` (see skills/nansen-mpp-payment)';
|
|
753
759
|
} else {
|