# Changelog

## 1.44.2

### Patch Changes

- [#604](https://github.com/nansen-ai/nansen-cli/pull/604) [`9d541d7`](https://github.com/nansen-ai/nansen-cli/commit/9d541d7d6aef232b0761846f6e716222f67798c4) Thanks [@kome12](https://github.com/kome12)! - Bind limit-order deposits to the trusted vault destination: reject any deposit whose wallet-sourced transfer (SPL token or native SOL) does not land in a token account this same transaction creates via CreateAccountWithSeed seeded off the user's vault. Covers both the SPL-token and native-SOL deposit paths.

- [#600](https://github.com/nansen-ai/nansen-cli/pull/600) [`c86af55`](https://github.com/nansen-ai/nansen-cli/commit/c86af55dff3fa71c61726650ec66060b61d1918e) Thanks [@kome12](https://github.com/kome12)! - Isolate the response cache by credential and request context so cached
  responses can no longer be shared across different API keys or API origins that
  use the same cache directory. Cache keys now include the base URL, HTTP method,
  and a hashed form of the effective credentials, and use SHA-256.

- [#612](https://github.com/nansen-ai/nansen-cli/pull/612) [`492b441`](https://github.com/nansen-ai/nansen-cli/commit/492b441d49df6e256b3e63645e16644bdec3a56c) Thanks [@gulshngill](https://github.com/gulshngill)! - Reject hard-linked `.credentials` files in the wallet-password fallback write, so the credential write cannot chmod, truncate, or overwrite an unrelated file

- [#611](https://github.com/nansen-ai/nansen-cli/pull/611) [`959225c`](https://github.com/nansen-ai/nansen-cli/commit/959225c1527540359763bb55a90f12fc4ffb14ea) Thanks [@gulshngill](https://github.com/gulshngill)! - Report `from_cache` telemetry from the API instance so it survives command handlers that rebuild their result, and pass it on the `alerts list --table` path, which previously never reported the field at all

- [#609](https://github.com/nansen-ai/nansen-cli/pull/609) [`288f566`](https://github.com/nansen-ai/nansen-cli/commit/288f566b674f8b550b19b26b4721e3fe68cc54f6) Thanks [@gulshngill](https://github.com/gulshngill)! - Fix `from_cache` telemetry always reporting `false` on cache hits

- [#586](https://github.com/nansen-ai/nansen-cli/pull/586) [`b254240`](https://github.com/nansen-ai/nansen-cli/commit/b25424008fe0202972ac706913721a3433f30d59) Thanks [@Kewe63](https://github.com/Kewe63)! - Tighten POSIX permissions when rewriting the fallback wallet credentials file and refuse non-regular credential paths.

- [#615](https://github.com/nansen-ai/nansen-cli/pull/615) [`9166884`](https://github.com/nansen-ai/nansen-cli/commit/916688496c2c83dee17e81a9b6c753a94b8ff0be) Thanks [@teyrebaz33](https://github.com/teyrebaz33)! - Fix `nansen transfer`/`nansen trade execute` with `--wallet walletconnect` using any connected EVM account instead of verifying the WalletConnect session is actually approved for the chain being signed/broadcast on.

  `getWalletConnectAddress('evm')` matched any account whose CAIP-2 chain tag started with `eip155:`, regardless of which specific chain it was approved for. Because EVM addresses are identical across chains, a session connected only to Ethereum mainnet would be silently used to sign a transaction destined for Base (or vice versa) -- nothing downstream (including the quote/request-intent binding checks) could catch this, since they only compare addresses, not chains.

  `getWalletConnectAddress` now accepts an optional `chainId`, and when given, only returns an account the session has approved for that exact chain (mirroring the mainnet-only exact match already used for Solana in the same function). Every place that resolves a WalletConnect EVM address before signing or broadcasting a real transaction now passes the target chain ID and fails closed with a clear error instead of proceeding with a wrong-chain session: `nansen transfer`'s `sendTokensViaWalletConnect`, and `nansen trade execute`'s quote-building, pre-execute wallet-match check, and immediate pre-signing check for its EVM WalletConnect swap path.

## 1.44.1

### Patch Changes

- [#588](https://github.com/nansen-ai/nansen-cli/pull/588) [`0db1c74`](https://github.com/nansen-ai/nansen-cli/commit/0db1c745b4cdfd05b47bd261159bace7b60f0854) Thanks [@Kewe63](https://github.com/Kewe63)! - Prevent duplicate alert creation after ambiguous network failures and keep Smart Alert mutations out of the response cache.

- [#595](https://github.com/nansen-ai/nansen-cli/pull/595) [`1e3fadb`](https://github.com/nansen-ai/nansen-cli/commit/1e3fadb346be2219e8d91ba417806ae7f5b9bcd9) Thanks [@devorun](https://github.com/devorun)! - Fix `--cache` reshaping a cached array response into an object. Endpoints that return a top-level JSON array were object-spread on a cache hit, so `[a, b]` came back as `{ 0: a, 1: b }` and every `Array.isArray()` branch downstream stopped matching — the first call printed rows and the second printed nothing. Cached arrays now stay arrays, and primitive response bodies are returned untouched instead of being exploded into character maps.

- [#589](https://github.com/nansen-ai/nansen-cli/pull/589) [`0cc4c18`](https://github.com/nansen-ai/nansen-cli/commit/0cc4c180e5525b6bf8a777d04401ac60b7c926a8) Thanks [@ygd58](https://github.com/ygd58)! - Fix `nansen alerts list --limit`/`--offset` silently misbehaving on invalid or edge-case input. `--limit 0` and `--offset 0` were treated as "not set" (falsy check) and silently ignored instead of honored; a non-numeric value like `--limit abc` silently returned zero results (`Array.prototype.slice` coerces `NaN` to `0`) instead of erroring; and a negative `--offset` was silently accepted by `slice()`, which treats negative indices as "from the end" — returning the wrong records instead of rejecting the input. Both flags are now validated as non-negative integers, matching the strict-validation convention already used elsewhere in the CLI (e.g. `--slippage`), and throw a clear `INVALID_PARAMS` error otherwise.

- [#577](https://github.com/nansen-ai/nansen-cli/pull/577) [`3c214a1`](https://github.com/nansen-ai/nansen-cli/commit/3c214a179a3f2c78a8b4b17e2c6b1177828bf2c6) Thanks [@batuhankocyigit](https://github.com/batuhankocyigit)! - Fix `nansen alerts create`/`update` silently dropping numeric range filters (`--usd-min/max`, `--market-cap-min/max`, `--fdv-min/max`, `--token-amount-min/max`, `--token-age-min/max`, and the `--inflow/outflow/netflow-*-min/max` flags) instead of rejecting bad input. These flags were converted with plain `Number(val)`, so a typo or garbage value (e.g. `--usd-min abc`) became `NaN`, which `JSON.stringify` silently turns into `null` in the request body — the alert would get created without the filter the user thought they'd set, with no error at any point. `--*-min`/`--*-max` now reject non-numeric input with a clear `Invalid --<flag> "<value>": must be a number` error; valid negative values (e.g. `--netflow-1h-min -5000` for a net-outflow filter) are unaffected.

- [#605](https://github.com/nansen-ai/nansen-cli/pull/605) [`9656d08`](https://github.com/nansen-ai/nansen-cli/commit/9656d08e2df3562ac650d299a5fc6b92bf00d8ad) Thanks [@kome12](https://github.com/kome12)! - Keep non-JSON 4xx responses from trade execute reusable instead of treating them as ambiguous broadcast failures.

- [#602](https://github.com/nansen-ai/nansen-cli/pull/602) [`9c72189`](https://github.com/nansen-ai/nansen-cli/commit/9c72189c6760c119784b3534a6777bd1a2e3ce11) Thanks [@kome12](https://github.com/kome12)! - trade limit-order cancel: give distinct, actionable errors when the refund can't be verified — a fully-filled order now says so plainly ("nothing left to refund") instead of sharing the same generic message as unparseable order metadata.

- [#598](https://github.com/nansen-ai/nansen-cli/pull/598) [`1450b66`](https://github.com/nansen-ai/nansen-cli/commit/1450b66ffab26d0d9fbe570c90de79916f405ffb) Thanks [@kome12](https://github.com/kome12)! - Close two dust-refund gaps in limit-order cancel verification: a native-SOL refund at or below the fee/rent slack could be "cancelled" by returning a single lamport while the rest of the escrow was rerouted, and a cancel now fails closed when the order is found but its remaining refund amount can't be computed instead of silently downgrading to a bare positive-inflow check.

- [#598](https://github.com/nansen-ai/nansen-cli/pull/598) [`b6d5baf`](https://github.com/nansen-ai/nansen-cli/commit/b6d5baf1b14ebd53287744eb23a1f9c4b7ac20a3) Thanks [@kome12](https://github.com/kome12)! - Limit-order create and cancel now verify the API-provided Solana transaction's simulated balance effect against the requested operation before signing, refusing to sign a deposit that would move unexpected funds out of the wallet or a cancel that fails to return the order's own deposited asset to it. The cancel check binds to the full expected remaining refund, not just a positive inflow, so a withdrawal that reroutes most of the escrow and returns only a dust amount of the right asset is refused. Also closes a gap where a cancel could pass on an inflow of any asset (not just the deposited one), and a tiny native-SOL deposit could pass on a fee-only outflow. The pre-cancel order lookup now paginates the active-order list, so an order beyond the first page can still be cancelled.

- [#582](https://github.com/nansen-ai/nansen-cli/pull/582) [`8e674c2`](https://github.com/nansen-ai/nansen-cli/commit/8e674c24c6c9340b2c658e511199ac546064fe9b) Thanks [@devorun](https://github.com/devorun)! - Telemetry now creates `~/.nansen` with mode 0700 and writes its id/session files with mode 0600, matching every other module that writes to that directory. Previously these were the only writes there that used default permissions, so when they were the first to create the directory (for example when authenticating with `NANSEN_API_KEY` instead of `nansen login`) it was left group- and world-readable.

- [#594](https://github.com/nansen-ai/nansen-cli/pull/594) [`95bdde1`](https://github.com/nansen-ai/nansen-cli/commit/95bdde151057b0bdc6b0bdc5efd67cc3420a9c44) Thanks [@Kewe63](https://github.com/Kewe63)! - Reject invalid cache TTL values before constructing the API client.

- [#593](https://github.com/nansen-ai/nansen-cli/pull/593) [`dfc908a`](https://github.com/nansen-ai/nansen-cli/commit/dfc908a74ebc9a6341629c43bea4d98df1219ccc) Thanks [@Kewe63](https://github.com/Kewe63)! - Reject invalid retry counts before constructing the API client.

- [#599](https://github.com/nansen-ai/nansen-cli/pull/599) [`bdbdcb2`](https://github.com/nansen-ai/nansen-cli/commit/bdbdcb222ae2f3a4f3b88c8832e7375c46559d79) Thanks [@kome12](https://github.com/kome12)! - x402 auto-pay now signs only for supported schemes and recognized payment networks (exact Solana mainnet CAIP-2 binding), and derives the EIP-712 chain id from the validated network. The EIP-712 domain version is now required across all signing backends (local, WalletConnect, Privy) so a missing version can no longer be silently defaulted to a wrong value, while a null/empty remote chain id is treated as unspecified rather than a conflict.

## 1.44.0

### Minor Changes

- [#563](https://github.com/nansen-ai/nansen-cli/pull/563) [`3b3e11b`](https://github.com/nansen-ai/nansen-cli/commit/3b3e11b5d346662bf352cbe2e3f66e54b22213b0) Thanks [@hulk-linus](https://github.com/apps/hulk-linus)! - Emit privacy-preserving per-leg Hyperliquid attribution through the canonical trade-perps outcome events.

- [#580](https://github.com/nansen-ai/nansen-cli/pull/580) [`c5085c5`](https://github.com/nansen-ai/nansen-cli/commit/c5085c5d062d848604402949a3e03c87d8b013bd) Thanks [@gulshngill](https://github.com/gulshngill)! - Add `nansen completion <bash|zsh|fish>`, which prints a shell completion script generated from the CLI's own command schema. Completions cover nested subcommands, per-command flags, global flags, and the enum values a flag accepts.

- [#597](https://github.com/nansen-ai/nansen-cli/pull/597) [`8453355`](https://github.com/nansen-ai/nansen-cli/commit/845335501837956db2f7a899bf251048bbd706d9) Thanks [@kome12](https://github.com/kome12)! - Security: `nansen mcp verify` no longer sends a saved API key (from `nansen login` / `NANSEN_API_KEY` / config) to a custom `--url` without explicit consent. Forwarding a saved key to a non-default URL now requires `--send-api-key`, and no key is ever sent over plain HTTP to a non-loopback host. An inline `--api-key` is unaffected.

  Note: verifying a custom `--url` with a saved key now errors unless `--send-api-key` is passed (previously it warned and proceeded).

- [#557](https://github.com/nansen-ai/nansen-cli/pull/557) [`5a73b43`](https://github.com/nansen-ai/nansen-cli/commit/5a73b43e4f2fc753c435babcea648b156f7a99a9) Thanks [@gulshngill](https://github.com/gulshngill)! - Add the `nansen research address-premium-labels` command.

- [#555](https://github.com/nansen-ai/nansen-cli/pull/555) [`4285d7f`](https://github.com/nansen-ai/nansen-cli/commit/4285d7fc22fde5bacb5b67eb3bcb6e94bb6a680e) Thanks [@gulshngill](https://github.com/gulshngill)! - Add the `nansen research chain-rank` command.

- [#561](https://github.com/nansen-ai/nansen-cli/pull/561) [`dd8035c`](https://github.com/nansen-ai/nansen-cli/commit/dd8035c09f5c99c08247686c621c5c14c30607cc) Thanks [@gulshngill](https://github.com/gulshngill)! - Add the `nansen research historical-token-ohlcv` command.

- [#560](https://github.com/nansen-ai/nansen-cli/pull/560) [`52f2f09`](https://github.com/nansen-ai/nansen-cli/commit/52f2f095baeaa48c43d5b0f3b1a3b036166266b5) Thanks [@gulshngill](https://github.com/gulshngill)! - Add the `nansen research perp-pnl-summary` command.

- [#559](https://github.com/nansen-ai/nansen-cli/pull/559) [`ed2d7a5`](https://github.com/nansen-ai/nansen-cli/commit/ed2d7a5ac00b51240f5a2d0fb7828131dc5074c8) Thanks [@gulshngill](https://github.com/gulshngill)! - Add the `nansen research position-intelligence` command.

- [#558](https://github.com/nansen-ai/nansen-cli/pull/558) [`e273152`](https://github.com/nansen-ai/nansen-cli/commit/e273152358792203435191a0f30dd307699721aa) Thanks [@gulshngill](https://github.com/gulshngill)! - Add the `nansen research smart-money-pnl-leaderboard` command.

- [#556](https://github.com/nansen-ai/nansen-cli/pull/556) [`3c14359`](https://github.com/nansen-ai/nansen-cli/commit/3c143596b6d7e624338f8d9b1a0972bcbe4d7ad7) Thanks [@gulshngill](https://github.com/gulshngill)! - Add the `nansen research token-sectors` command.

- [#562](https://github.com/nansen-ai/nansen-cli/pull/562) [`0d0f5e6`](https://github.com/nansen-ai/nansen-cli/commit/0d0f5e6b83ae91f0215eac3ad2e9216897e6666c) Thanks [@gulshngill](https://github.com/gulshngill)! - Add the `nansen research transaction-with-token-transfer-lookup` command.

- [#581](https://github.com/nansen-ai/nansen-cli/pull/581) [`8726a23`](https://github.com/nansen-ai/nansen-cli/commit/8726a23c0e6028c98f941ee9a638dffa50e01ab1) Thanks [@gulshngill](https://github.com/gulshngill)! - Every command option in `nansen schema` now carries a type and a description (140 research and `wallet send` options had neither), and the `research points` group is described. `research token ohlcv --timeframe` documents its real default (`1d`), and `wallet send --chain`, `research search --type`, and the prediction-market `--neg-risk` filters declare the values they accept, so `--help` and shell completion offer them. Fixed `--neg-risk true` on the prediction-market screeners, which was sent to the API as `neg_risk: false` because the parsed boolean was compared against the string `'true'`. `nansen mcp install` and `nansen mcp uninstall` declare their positional client in the schema, and `nansen completion` scripts now complete it (`claude-code`, `claude-desktop`, `cursor`) in bash, zsh, and fish.

### Patch Changes

- [#575](https://github.com/nansen-ai/nansen-cli/pull/575) [`927ffea`](https://github.com/nansen-ai/nansen-cli/commit/927ffea1762e7de78160a209aa3cc72298b42c24) Thanks [@kome12](https://github.com/kome12)! - Fail closed on an ambiguous broadcast failure in swap and bridge execute. When
  `/execute` (swap) returns any 5xx (regardless of body shape — a structured 504
  `UPSTREAM_TIMEOUT` is treated the same as a bare 502) or any other
  uninterpretable response — or the POST, or reading its body, throws a network
  error — after the signed tx was sent, or a bridge broadcast fails ambiguously,
  the tx may already be live. The quote is now marked spent and the
  run aborts — rather than trying the next candidate quote or leaving the quote
  reusable — so a re-execute (or agent auto-retry) can't double-broadcast. Gasless
  (Relay solver-paid) swaps additionally do not retry the `/execute` POST: the
  signed authorization is broadcast by Relay's own wrapping tx, so a re-POST can't
  be node-deduped and could trigger a second solve — a single attempt fails closed
  instead. A bridge send is kept reusable only when the node's error proves the tx never
  entered the mempool (a pre-broadcast validation rejection such as insufficient
  funds); in-flight txpool states like "already known" or "nonce too low" fail
  closed.

- [#572](https://github.com/nansen-ai/nansen-cli/pull/572) [`2ba5c15`](https://github.com/nansen-ai/nansen-cli/commit/2ba5c15a68f6cc2045dcfb928d65eecdb4083292) Thanks [@teyrebaz33](https://github.com/teyrebaz33)! - Fix `nansen changelog --since <version>` silently returning "No changelog entries found" for a version missing its patch number (e.g. `--since 1.43` instead of `--since 1.43.0`), even when matching entries exist. The comparison compared the missing component against `undefined`, and `>` is always `false` against `undefined` in both directions, so a version that matched on major.minor always came out "less than" the since-value. A missing component is now treated as `0`, and a `--since` value that isn't a valid version (e.g. `--since abc`) now prints a clear error instead of silently matching nothing.

  The version-comparison logic is now shared (`src/semver.js`) between `nansen changelog --since` and the update-notifier's `isNewer` check, which had the identical bug in its own separate parser. `isNewer` couldn't misfire in practice (both versions it compares are always fully-qualified x.y.z today), but it's the same defect class, so it's fixed the same way rather than left in place.

- [#569](https://github.com/nansen-ai/nansen-cli/pull/569) [`04932c7`](https://github.com/nansen-ai/nansen-cli/commit/04932c7fb26fb2c4c4f9b14eddcd43a8e3060aa4) Thanks [@memosr](https://github.com/memosr)! - Refuse to re-execute a swap quote that has already been broadcast, mirroring the single-use guard `nansen bridge execute` already had. `nansen trade execute` now marks the quote as spent (`executedAt`) the instant a transaction is broadcast — before waiting for its receipt — so a `RECEIPT_TIMEOUT` (the tx is on-chain but the command exits non-zero) no longer leaves the quote replayable. Retrying the same `--quote <id>` after such a failure previously re-signed and re-broadcast the swap under a fresh nonce instead of being refused.

- [#592](https://github.com/nansen-ai/nansen-cli/pull/592) [`60bd2ef`](https://github.com/nansen-ai/nansen-cli/commit/60bd2ef64f5eebe89112bfa3366c013981f365aa) Thanks [@ygd58](https://github.com/ygd58)! - Fix the x402 auto-payment fallback in `src/api.js` generating multiple payment authorizations for the same request after an ambiguous outcome (issue #583). After a signed `Payment-Signature` was transmitted, `_x402Retry` previously collapsed every non-ok response — a clean rejection, a 5xx, an unreadable body — and every transport failure into a single `null`, and callers treated any `null` as "safe to try the next payment option/provider". That meant a 5xx, a timeout, or an unparseable response (any of which could mean the server already received and settled the payment) triggered signing and transmitting a _second_ independent payment for the same logical request. Separately, a genuine successful response whose JSON body happened to be `null` was indistinguishable from a rejection, risking a second payment for an already-settled call.

  `_x402Retry` now returns a dedicated `X402_PAYMENT_REJECTED` sentinel only for a provably clean rejection (a non-5xx status with a readable body), and throws `NansenError` with the new `PAYMENT_AMBIGUOUS` code for anything else — a transport failure, a 5xx, or an unreadable body on either a rejection or a success. All three fallback call sites (Privy, local wallet, WalletConnect) now check against the sentinel instead of `null`, and re-throw a `PAYMENT_AMBIGUOUS` error immediately instead of silently moving on to the next provider.

- [#524](https://github.com/nansen-ai/nansen-cli/pull/524) [`3e8dcc2`](https://github.com/nansen-ai/nansen-cli/commit/3e8dcc233598383556004da7aaa0a64275beee3f) Thanks [@dolmaciabdullah-byte](https://github.com/dolmaciabdullah-byte)! - Use BigInt for EVM balance in `checkX402Balance` to avoid precision loss on 18-decimal tokens (BSC stablecoins): `parseInt(hex, 16)` loses integer precision once the raw wei value exceeds `Number.MAX_SAFE_INTEGER` (~9.0e15 wei, i.e. ~0.009 tokens at 18 decimals), skewing the low-balance warning.

- [#568](https://github.com/nansen-ai/nansen-cli/pull/568) [`9a45fc4`](https://github.com/nansen-ai/nansen-cli/commit/9a45fc494b3bcc0ebeb37f867902aecc075ee92f) Thanks [@Kewe63](https://github.com/Kewe63)! - Reject non-finite limit-order trigger prices and expiry values before wallet or API activity.

- [#567](https://github.com/nansen-ai/nansen-cli/pull/567) [`c0fe57b`](https://github.com/nansen-ai/nansen-cli/commit/c0fe57b6f881aa7338a16f6aa2fd33d5e6d42757) Thanks [@Kewe63](https://github.com/Kewe63)! - Keep `research perp` analytics-only instead of routing trading subcommands through the top-level perp dispatcher.

- [#558](https://github.com/nansen-ai/nansen-cli/pull/558) [`002921e`](https://github.com/nansen-ai/nansen-cli/commit/002921e5d72e7e54de26f241cb4b409e408b8bf9) Thanks [@gulshngill](https://github.com/gulshngill)! - Reject non-integer or non-positive `--limit` values with an actionable error instead of forwarding them to the API.

## 1.43.1

### Patch Changes

- [#526](https://github.com/nansen-ai/nansen-cli/pull/526) [`a7ab05c`](https://github.com/nansen-ai/nansen-cli/commit/a7ab05c592bddd1e0ca33c08586ef325bcc19277) Thanks [@dolmaciabdullah-byte](https://github.com/dolmaciabdullah-byte)! - Fix `formatValue` displaying `1000.00K` instead of `1.00M` when a value like 999999.995 rounds up at the K/M boundary.

- [#548](https://github.com/nansen-ai/nansen-cli/pull/548) [`000d01a`](https://github.com/nansen-ai/nansen-cli/commit/000d01a8530de7e5bb6af8a637ba1b4fe406b732) Thanks [@Sertug17](https://github.com/Sertug17)! - Fix `parseAmount` silently producing wrong values for negative decimal inputs. Negative amounts are now rejected with a clear error.

- [#551](https://github.com/nansen-ai/nansen-cli/pull/551) [`092535a`](https://github.com/nansen-ai/nansen-cli/commit/092535aa32bedb8c11a6ee624936bffca247d2d5) Thanks [@kome12](https://github.com/kome12)! - Harden `parseAmount` input validation: reject negative amounts wrapped in whitespace (previously silently miscalculated), and reject non-numeric or malformed inputs (e.g. `abc`, empty string, `1.`, `.5`) with a clear error instead of throwing a raw error or silently returning `0`.

- [#433](https://github.com/nansen-ai/nansen-cli/pull/433) [`977fbc5`](https://github.com/nansen-ai/nansen-cli/commit/977fbc51a75ef4a0764db161b4bbee26d1ebc3ae) Thanks [@aikido-autofix](https://github.com/apps/aikido-autofix)! - Validate the wallet name before the Privy pre-read in `wallet delete` and `wallet send`, routing both reads through `getWalletFile()` so the path stays confined to the wallets directory.

- [#545](https://github.com/nansen-ai/nansen-cli/pull/545) [`642eb20`](https://github.com/nansen-ai/nansen-cli/commit/642eb20a48fe1ff5a9ba17fcbeac4604c7172698) Thanks [@kome12](https://github.com/kome12)! - Update Noble crypto dependencies to the patched 2.4.x releases.

## 1.43.0

### Minor Changes

- [#539](https://github.com/nansen-ai/nansen-cli/pull/539) [`2ba6c40`](https://github.com/nansen-ai/nansen-cli/commit/2ba6c40376b5c1cc4d7105592cd63d47b5130f02) Thanks [@kome12](https://github.com/kome12)! - x402 auto-payment now refuses to sign payments for unknown tokens/networks and enforces a configurable per-payment USD cap (NANSEN_X402_MAX_AMOUNT, default $1.00) before signing.

### Patch Changes

- [#535](https://github.com/nansen-ai/nansen-cli/pull/535) [`863ef23`](https://github.com/nansen-ai/nansen-cli/commit/863ef2372dd042eb37d198f16513eedf5df97dab) Thanks [@crazywriter1](https://github.com/crazywriter1)! - Fix EVM swap execution when quotes omit gas limits: WalletConnect and local wallet paths now fall back to eth_estimateGas (×1.5) and then 210000, matching the Privy path.

- [#541](https://github.com/nansen-ai/nansen-cli/pull/541) [`7492bbe`](https://github.com/nansen-ai/nansen-cli/commit/7492bbe6a86cd848168b400ba7c8a53c403d264c) Thanks [@kome12](https://github.com/kome12)! - Refuse x402 auto-payments whose payment requirement is missing a payTo/pay_to recipient, matching the existing missing-amount check. Previously this fell through to the per-signing-path field validation inconsistently, and the WalletConnect path had no check at all.

## 1.42.0

### Minor Changes

- [#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.

- [#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`.

### Patch Changes

- [#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.

- [#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.

  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.

- [#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.

- [#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.

- [#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.

- [#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
  key, invalid-key remediation points at key management, and login guidance leads
  with paths that avoid shell history. Every request that carries a credential —
  API key, agent, limit-order JWT/X-API-Key, MCP verify, and Privy auth — now
  refuses to follow HTTP redirects, so a credential can't be relayed to a redirect
  target. Interactive password and API-key prompts stay masked (no cleartext echo)
  even when stdout is redirected.

- [#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
  `mcp-remote` bridge to the version `mcp install` writes, and correct the
  header-formatting note (whitespace after the colon is trimmed; the key belongs
  in `env`, not in the argument list).

- [#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.

## 1.41.1

### Patch Changes

- [#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.

  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.

- [#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.

## 1.41.0

### Minor Changes

- [#512](https://github.com/nansen-ai/nansen-cli/pull/512) [`ba42a9c`](https://github.com/nansen-ai/nansen-cli/commit/ba42a9c51d75b0cf909c1f14a8e509d7a4ca77ad) Thanks [@kome12](https://github.com/kome12)! - Validate Solana swap quotes against the original request before signing (local, Privy, and WalletConnect wallets). The CLI now checks that a quote's chain, token pair, amounts, and target wallet match what was requested at quote time and refuses to sign when they don't, bringing Solana in line with the existing EVM checks. `--swap-mode exactOut` now also requires `--max-input` on Solana (previously EVM-only), so the maximum spend is bounded by a value you supply rather than one taken from the quote itself.

- [#514](https://github.com/nansen-ai/nansen-cli/pull/514) [`1bc7337`](https://github.com/nansen-ai/nansen-cli/commit/1bc73378db87fed5c362e04b52ae8da8c69fbff7) Thanks [@kome12](https://github.com/kome12)! - `trade execute` and `trade limit-order` on Solana now statically check the aggregator's compiled instructions before signing, and reject a transaction that grants a token delegate, changes a token account's authority, closes an account with its rent redirected to a stranger, or sets an excessive compute-budget priority fee — closing a class of drain vector a balance-delta simulation alone can't see.

- [#522](https://github.com/nansen-ai/nansen-cli/pull/522) [`820bf05`](https://github.com/nansen-ai/nansen-cli/commit/820bf058de615a818fa099c8bf527a94339c8f9e) Thanks [@kome12](https://github.com/kome12)! - Verify a Solana swap's simulated on-chain outcome before signing (local, Privy, and WalletConnect wallets), mirroring the existing EVM balance-delta check. The CLI simulates the aggregator's transaction and confirms the wallet's balance changes match the quote — input spent within your max, expected output received, no other asset drained — refusing to sign on a mismatch or an in-simulation revert. Covered by the existing `--no-verify-outcome` flag; degrades with a warning (and still signs) when no simulation-capable RPC is available, so an RPC outage never blocks a trade. New env var: `NANSEN_SOLANA_SIM_RPC`.

### Patch Changes

- [#519](https://github.com/nansen-ai/nansen-cli/pull/519) [`55ab7db`](https://github.com/nansen-ai/nansen-cli/commit/55ab7dbdc46ff7181b303d421146691b6eb7c9a7) Thanks [@kome12](https://github.com/kome12)! - trade execute: confirm EVM transactions against the hash derived locally from
  the signed bytes instead of trusting the broadcaster's reported hash, and fail
  closed if they disagree. Once a transaction has been broadcast, every uncertain
  outcome now aborts the whole execute instead of silently trying the next quote
  (which could broadcast a second transaction): a hash mismatch, a signed
  transaction we cannot re-derive a hash for, and a receipt-confirmation timeout
  (distinguished from a genuine on-chain revert) are all fatal across the swap,
  approval, and revoke paths. Broadcaster hashes are also compared
  prefix-insensitively, so a bare (0x-less) hash is no longer a false mismatch.

- [#521](https://github.com/nansen-ai/nansen-cli/pull/521) [`977e326`](https://github.com/nansen-ai/nansen-cli/commit/977e3269246cc1c25d03e837c9ce4ac03c5d70b9) Thanks [@aikido-autofix](https://github.com/apps/aikido-autofix)! - Fix potential path traversal in safeQuotesPath by rejecting absolute relative paths (Windows cross-drive escape).

- [#497](https://github.com/nansen-ai/nansen-cli/pull/497) [`223a9d5`](https://github.com/nansen-ai/nansen-cli/commit/223a9d501c0e624f3986a547ace3adf621c00896) Thanks [@crazywriter1](https://github.com/crazywriter1)! - Reject `--oid` values above 2^53-1 on `perp cancel`: large Hyperliquid uint64 order IDs would be silently rounded by JS Number, potentially cancelling the wrong order.

## 1.40.1

### Patch Changes

- [#516](https://github.com/nansen-ai/nansen-cli/pull/516) [`48722ef`](https://github.com/nansen-ai/nansen-cli/commit/48722ef0c7e6c0a7ce8c4c026245afb6e6f47e79) Thanks [@kome12](https://github.com/kome12)! - Fix cross-chain bridges into native SOL being refused at execute time. The quote/intent binding compared the wrapped-SOL mint (how `--to SOL` resolves) against the System Program address that aggregators use as the native-SOL sentinel and rejected them as different tokens. Both spellings are now treated as the same asset.

## 1.40.0

### Minor Changes

- [#509](https://github.com/nansen-ai/nansen-cli/pull/509) [`430c300`](https://github.com/nansen-ai/nansen-cli/commit/430c3003d28a44bd1bfb123eef9290a7350a7e1e) Thanks [@kome12](https://github.com/kome12)! - `trade execute` now revokes an existing on-chain ERC-20 allowance before
  re-approving when it is more than 10x the current trade's scoped amount, such
  as a legacy unlimited approval or an allowance granted by another app. Most
  trades are unaffected. Opt out with `--no-revoke-excessive-allowance`.

  After each revoke or reapproval, the CLI reads the resulting allowance back
  on-chain and fails closed (instead of proceeding to the swap) if it doesn't
  match what was expected or can't be read.

### Patch Changes

- [#498](https://github.com/nansen-ai/nansen-cli/pull/498) [`a964dd1`](https://github.com/nansen-ai/nansen-cli/commit/a964dd19c826f5231d2651547212d8169a74e7fe) Thanks [@crazywriter1](https://github.com/crazywriter1)! - Use `pending` nonce block tag for EVM sends: back-to-back transfers no longer risk reusing the same nonce when mempool transactions are queued.

- [#493](https://github.com/nansen-ai/nansen-cli/pull/493) [`bc89fef`](https://github.com/nansen-ai/nansen-cli/commit/bc89fef74489da3df32a12079effbdfa899373fd) Thanks [@crazywriter1](https://github.com/crazywriter1)! - Validate `--slippage-bps` on `limit-order create`: values outside 0-10000 now fail with a clear error before any auth/API call.

## 1.39.0

### Minor Changes

- [#495](https://github.com/nansen-ai/nansen-cli/pull/495) [`3306897`](https://github.com/nansen-ai/nansen-cli/commit/3306897c1aaae594f4401fd4656b2451ab375d78) Thanks [@kome12](https://github.com/kome12)! - Add EVM swap-outcome verification to `trade execute`. Before broadcasting a swap on an EVM chain (Base), the CLI now simulates the transaction and confirms the wallet's balance changes match the quote — the input is spent within your maximum, at least the expected output is received, and no other token or NFT leaves the wallet — refusing to sign when they don't. This runs on top of the existing pre-broadcast checks and needs a simulation-capable RPC (`NANSEN_BASE_SIM_RPC`); when none is available it degrades with a warning rather than blocking the trade. Skip it with `--no-verify-outcome`. Solana is unaffected.

### Patch Changes

- [#495](https://github.com/nansen-ai/nansen-cli/pull/495) [`e8cf217`](https://github.com/nansen-ai/nansen-cli/commit/e8cf217feaa9e7c8f68f4f3c3c2a49adcda07101) Thanks [@kome12](https://github.com/kome12)! - Harden swap-outcome verification error handling: a revert reported by the simulation endpoint as a top-level JSON-RPC error (rather than a per-call status) now fails closed (blocks the swap) instead of degrading, and a non-2xx simulation response (e.g. HTTP 401 "Invalid API key") now degrades with the real status and message instead of a misleading "returned no call result" warning.

- [#499](https://github.com/nansen-ai/nansen-cli/pull/499) [`de0bcc5`](https://github.com/nansen-ai/nansen-cli/commit/de0bcc562bcd20a80edd3ab2f486870b80629c83) Thanks [@gulshngill](https://github.com/gulshngill)! - Fix `profiler labels`: call `/api/v1/profiler/address/labels` with its v1 request body — the beta endpoint previously used was removed from the Nansen API. `profiler batch --include labels` now returns the label array itself instead of the raw `{pagination, data}` envelope.

- [#506](https://github.com/nansen-ai/nansen-cli/pull/506) [`f407edb`](https://github.com/nansen-ai/nansen-cli/commit/f407edb19444d6b5a1a631d29b4c4fb9bd280708) Thanks [@gulshngill](https://github.com/gulshngill)! - Add a canonical MCP setup section to the README — endpoint `https://mcp.nansen.ai/ra/mcp`, `NANSEN-API-KEY` auth, per-client setup paths for Claude Code, Claude Tag, and generic or stdio-only clients, plus a pointer to the connection docs for Claude Desktop and Cursor — and point the out-of-credits and low-credit warnings at the credits tab of the billing page, `app.nansen.ai/api?tab=api`, instead of the bare `app.nansen.ai/api`.

- [#500](https://github.com/nansen-ai/nansen-cli/pull/500) [`9ccf8a2`](https://github.com/nansen-ai/nansen-cli/commit/9ccf8a20841a9ca01a2627ccf5de2575bf016a46) Thanks [@gulshngill](https://github.com/gulshngill)! - Document global pagination options in `nansen schema`.

## 1.38.0

### Minor Changes

- [#486](https://github.com/nansen-ai/nansen-cli/pull/486) [`b752d81`](https://github.com/nansen-ai/nansen-cli/commit/b752d81336a5d9bda3ad85e62a4d42d98c069e58) Thanks [@gulshngill](https://github.com/gulshngill)! - Add `nansen auth status` and `nansen doctor`. `auth status` is fully offline: it reports whether an API key is configured and where it comes from (env var vs config file, masked), the active base URL, x402 wallet readiness, and OS keychain availability. `doctor` runs health checks over the whole setup — Node version, config file validity and permissions, wallet storage and password hygiene (flags the insecure `.credentials` file), keychain availability, Privy env credentials, caches, and telemetry — with an actionable fix per finding, plus a safe unauthenticated connectivity probe (no credits consumed; skip it with `--offline`). `--json` returns machine-readable checks.

- [#494](https://github.com/nansen-ai/nansen-cli/pull/494) [`67027e6`](https://github.com/nansen-ai/nansen-cli/commit/67027e6a0faefcc797ec9407f199bc985dbbfc56) Thanks [@kome12](https://github.com/kome12)! - Harden EVM swap signing: scope ERC-20 approvals to the trade amount instead of granting an unlimited allowance, and validate the swap target before signing (reject an empty/zero address, a non-contract target, or a target equal to the token being sold). As a result, ERC-20 sells on Base now include a per-swap approval transaction. Native ETH swaps and all Solana swaps are unaffected. Note: this scopes approvals granted from now on; a pre-existing unlimited approval from an earlier version is not automatically reduced.

  Also tightens the input validation on the quote a swap is signed from. Every approval-signing path (local, Privy, WalletConnect) now shares one encoder that requires a well-formed 20-byte spender, keeps the approved amount bounded (never unlimited) and within the request cap, and produces fixed-width approval calldata. EVM execution now requires complete request intent persisted by the quote command and revalidates each quote against it (chain, wallet, token pair, mode, and amount), so the signed transaction remains bound to what was requested. A same-chain swap whose transaction is a bare ERC-20 transfer/approve rather than a routed swap is refused (bridge routes excluded).

  The swap-target contract check now fails closed: it retries and, if it still can't confirm the target carries contract code, refuses to sign rather than proceeding on an unverified target.

  EVM (Base) exactOut swaps now require an explicit maximum input (spend ceiling) via `--max-input` in base units of the sell token. The quote persists that `maxInputAmount`, and the execute path refuses to sign, approve, or broadcast any quote whose input exceeds it, for native and ERC-20 swaps across all three EVM signing paths. Solana exactOut is unaffected and does not require the flag (there is no ERC-20 approval to scope on that path). Quotes already above the cap are dropped at quote time (and, when none fit, a clear `MAX_INPUT_EXCEEDED` error is returned) rather than saved and rejected only at execute. Relatedly, a quote missing a field the request-intent check needs (sell/buy token address or the bound amount) is now rejected rather than skipped, and the exactOut output binding accepts more-than-requested output (only a shortfall is rejected, since the input is independently capped).

  The execute path also binds the signer to the wallet the quote was built for: it now refuses to sign a quote whose persisted wallet doesn't match the current signer (e.g. the default wallet changed between quote and execute), since the quoted transaction is constructed for a specific sender.

### Patch Changes

- [#494](https://github.com/nansen-ai/nansen-cli/pull/494) [`54b9d41`](https://github.com/nansen-ai/nansen-cli/commit/54b9d41fc9f99cd68bce416b95a129fe9e858981) Thanks [@kome12](https://github.com/kome12)! - Fix exactOut `--max-input` so it bounds the slippage-buffered approval, not the bare quote input. Previously an exactOut ERC-20 quote whose raw input equalled the cap (e.g. 1,000,000 at 3% slippage) passed the max-input filter and was saved, but execution scoped a larger approval (1,030,000) that the approval encoder then rejected for exceeding the cap — bricking the trade across local, Privy, and WalletConnect flows. Both the quote-time filter and the execute-time spend check now measure the same buffered amount the approval encoder does, so a quote that clears the cap can always be signed.

## 1.37.0

### Minor Changes

- [#481](https://github.com/nansen-ai/nansen-cli/pull/481) [`ccaa40b`](https://github.com/nansen-ai/nansen-cli/commit/ccaa40beb570c2a6df5917ded308c3bb1722eb70) Thanks [@kome12](https://github.com/kome12)! - Add `research profiler first-funder` command to look up the first wallet that funded an EVM address. The funder is the earliest address to send native gas, resolved across chains, returned with its Nansen label and the funding transaction.

- [#485](https://github.com/nansen-ai/nansen-cli/pull/485) [`b49c758`](https://github.com/nansen-ai/nansen-cli/commit/b49c75866379421c0738032e1f98a4a74b3fb5b4) Thanks [@MarcLlopart](https://github.com/MarcLlopart)! - `nansen perp order` and `perp close` now print the Hyperliquid order id (`oid`) and fill (size @ avg price) returned by the exchange, plus a ready-to-run `nansen perp cancel` command for any resting order — mirroring how spot trading surfaces its quote id. TP/SL bracket legs are labelled (parent / take-profit / stop-loss). Order ids are uint64; an id beyond JavaScript's safe integer range (2^53) is detected and its exact value and cancel hint are withheld rather than shown rounded, so a wrong id is never presented as actionable.

### Patch Changes

- [#483](https://github.com/nansen-ai/nansen-cli/pull/483) [`d0d10a2`](https://github.com/nansen-ai/nansen-cli/commit/d0d10a266e32aa086a8934acaa8e1d0b9ddff2e2) Thanks [@kome12](https://github.com/kome12)! - Unknown-command errors now detect when a whole multi-word command was passed as a single argument (a common shell-quoting mistake, e.g. `nansen "trade --help"` or an unquoted variable under zsh) and point at the likely cause instead of a bare "Unknown command".

- [#484](https://github.com/nansen-ai/nansen-cli/pull/484) [`bc5f774`](https://github.com/nansen-ai/nansen-cli/commit/bc5f774165df7103eff9ba5cfcdc660bcec5d752) Thanks [@kome12](https://github.com/kome12)! - Write the cost-map and update-check cache files atomically (temp file + rename) so concurrent `nansen` processes can no longer observe an empty or truncated cache.

- [#465](https://github.com/nansen-ai/nansen-cli/pull/465) [`4105193`](https://github.com/nansen-ai/nansen-cli/commit/41051932236a37121819e0d1bf47c8fb34422ec8) Thanks [@dobbydobap](https://github.com/dobbydobap)! - Fix `nansen quote --help`, `nansen trade quote --help`, and `nansen execute --help` to print the trade usage and exit with code 0 instead of erroring with exit code 1.

- [#485](https://github.com/nansen-ai/nansen-cli/pull/485) [`c9aaf58`](https://github.com/nansen-ai/nansen-cli/commit/c9aaf58923819c014588cb2c068600ad9872276e) Thanks [@MarcLlopart](https://github.com/MarcLlopart)! - `nansen perp order` / `perp close` now emit an anonymous `perp_order_completed` telemetry event after the Hyperliquid `/exchange` response is parsed. Perp orders bypass the Nansen API on submit (the CLI signs and posts straight to Hyperliquid), so this client-side event is the only signal that an order was placed. The payload is deliberately minimal — only the trade side and the Hyperliquid order id (omitted when it exceeded JS safe-integer precision); no asset, price, size, or fill detail is sent. The telemetry disclosure (CLI help footer and module docs) names exactly these fields. Honours the existing `DO_NOT_TRACK` / `NANSEN_NO_TELEMETRY` opt-out; order rejections remain covered by `cli_command_failed`.

- [#478](https://github.com/nansen-ai/nansen-cli/pull/478) [`758ce13`](https://github.com/nansen-ai/nansen-cli/commit/758ce13b7c65a5a88d20378ae1ad5cc7bba7d7ba) Thanks [@boleklebovski](https://github.com/boleklebovski)! - Document the missing `trade quote` and `trade execute` options in `src/schema.json`: `--swap-mode`, `--slippage`, `--auto-slippage`, `--max-auto-slippage`, `--quote`, `--quote-index` and `--no-simulate`. These options are already implemented and documented for humans, but were absent from the machine-readable schema.

- [#488](https://github.com/nansen-ai/nansen-cli/pull/488) [`f653b37`](https://github.com/nansen-ai/nansen-cli/commit/f653b3761a4abc8e8a45d3ff42cedf0241a8ff20) Thanks [@gulshngill](https://github.com/gulshngill)! - Warn on logout when `NANSEN_API_KEY` remains active in the environment.

## 1.36.2

### Patch Changes

- [#479](https://github.com/nansen-ai/nansen-cli/pull/479) [`e2590ed`](https://github.com/nansen-ai/nansen-cli/commit/e2590ed5caf0461b43f6e726ec62d87f70d391fd) Thanks [@gulshngill](https://github.com/gulshngill)! - Surface richer API response metadata: the `X-Nansen-Credits-Cost` header now drives credit reporting (a concise `Credits: N (this call)` stderr line after each data command, falling back to the cached spec estimate when the header is absent), `requestId` is hoisted to the top level of the JSON error envelope (including `nansen agent` failures, which previously dropped it), and error codes now come from the API's stable `code` field when present — known codes map onto the existing error code enum, unknown ones pass through verbatim instead of being flattened. stdout JSON is unchanged; all new reporting goes to stderr.

## 1.36.1

### Patch Changes

- [#476](https://github.com/nansen-ai/nansen-cli/pull/476) [`f480a49`](https://github.com/nansen-ai/nansen-cli/commit/f480a492a2ea142894a49f7a6e551d38e8aa4312) Thanks [@kome12](https://github.com/kome12)! - Add troubleshooting guidance for stale global installs.

## 1.36.0

### Minor Changes

- [#467](https://github.com/nansen-ai/nansen-cli/pull/467) [`54386c0`](https://github.com/nansen-ai/nansen-cli/commit/54386c0f3280fcc06c8bb7a5d18956d45b2d3d63) Thanks [@kome12](https://github.com/kome12)! - **Output shape change:** every command failure now serializes through the same error envelope — `{success: false, error, code, status, details}`. Previously a `CommandError` printed its structured payload at the top level instead, so errors from `trade`, `limit-order` and the API-key flows (`NOT_A_TTY`, `API_KEY_REQUIRED`, `INVALID_API_KEY`, `VERIFICATION_FAILED`) came back in a different shape from everything else.

  Nothing is lost — the previous top-level payload is preserved verbatim under `details` — but anything parsing those errors positionally needs to read `details` instead of the root object. The new `perp` and `bridge` commands raise `CommandError` throughout, so without this they would have been the third distinct error shape in the CLI.

  One deliberate exception: a missing-argument usage banner (`MISSING_PARAM`, `MISSING_ARGS`) prints as plain text when stdout is an interactive terminal and no output format was requested, because those messages are multi-line help written to be read and serializing them renders every newline as a literal `\n`. Piped output, and any run with `--pretty`, `--table`, `--format csv` or `--stream`, still gets the envelope — so nothing consuming the CLI programmatically sees a different shape.

### Patch Changes

- [#467](https://github.com/nansen-ai/nansen-cli/pull/467) [`8ab8bb4`](https://github.com/nansen-ai/nansen-cli/commit/8ab8bb41a1fc89b7dfa804f5c2d601e6ae38c89b) Thanks [@kome12](https://github.com/kome12)! - `bridge execute` now re-screens the wallet against the compliance blocklist immediately before signing, and fails closed if the check can't be completed — matching what the perp commands already did. Bridge quotes stay valid for an hour and the EVM deposit leg broadcasts straight to a public RPC, so previously nothing re-checked the wallet between the quote and the transaction that moves funds.

  It also refuses to execute a quote with a wallet other than the one the quote was created for. Previously the signing wallet was resolved from `--wallet` or the current default independently of the quote, so a changed default (or an explicit `--wallet`) could sign with a different wallet than the one screened.

- [#467](https://github.com/nansen-ai/nansen-cli/pull/467) [`44805e2`](https://github.com/nansen-ai/nansen-cli/commit/44805e2cd0a002b38b32bd2818da89548c4974f0) Thanks [@kome12](https://github.com/kome12)! - `nansen schema` now describes the `bridge` command group — its three subcommands, their options, and the supported routes — so agents driving the CLI off the schema can discover it.

  The mutating `perp` subcommands (`order`, `cancel`, `close`, `leverage`, `transfer`, `approve-builder-fee`) now declare `submitsTo: "https://api.hyperliquid.xyz/exchange"` in place of an `endpoint`, which is where they actually send a signed action, alongside an `apiEndpoints` list of the Nansen routes each one reads for compliance screening, market metadata and builder-fee status. Read-only subcommands keep their `endpoint` unchanged.

- [#467](https://github.com/nansen-ai/nansen-cli/pull/467) [`7185359`](https://github.com/nansen-ai/nansen-cli/commit/7185359d3ce657df849c371b34f6d045a4dac653) Thanks [@kome12](https://github.com/kome12)! - `nansen bridge` supports `base -> hyperliquid` for deposits, and `hyperliquid -> base`, `hyperliquid -> ethereum`, `hyperliquid -> arbitrum` for withdrawals. Any other combination is rejected at quote time with the supported routes listed.

  The route set is asymmetric because the two directions need different things from the client: a deposit broadcasts an EVM transaction and so needs a locally signable origin chain, while a withdrawal signs a Hyperliquid action and never touches the destination chain.

- [#467](https://github.com/nansen-ai/nansen-cli/pull/467) [`19738dd`](https://github.com/nansen-ai/nansen-cli/commit/19738dd252dca12ce0e41d40fe4023ac96ff0213) Thanks [@kome12](https://github.com/kome12)! - EVM transactions are now signed as EIP-1559 (type 2) when the quote supplies fee caps, instead of being flattened into a legacy (type 0) transaction with a single gas price.

  A legacy transaction pays exactly its `gasPrice`, so once the base fee rises above that value it is not merely slow — it can never be included at that nonce. A type-2 transaction pays base fee plus priority up to its cap, so it tolerates the fee moving between signing and inclusion. This affects `trade execute` and `bridge execute`, which share the signer.

  `bridge execute` also stops discarding the fee fields the bridge quote provides. It previously overwrote them with a bare `eth_gasPrice` reading, producing a transaction priced at roughly the current base fee with almost no priority fee — which is what it takes to sit unmined on Base. Quoted fees are now kept, with the priority fee raised to a floor that Base will actually schedule and the cap lifted to cover both that and base-fee movement.

  Two related robustness changes: signing now refuses outright when a quote carries no gas information at all, rather than falling back to a 1 wei gas price that produces a permanently unmineable transaction; and the receipt wait is longer, because by the time it runs the transaction is already broadcast, so giving up early reports a failure without undoing anything.

- [#467](https://github.com/nansen-ai/nansen-cli/pull/467) [`f649eea`](https://github.com/nansen-ai/nansen-cli/commit/f649eeaf90b5666d51bc623aafdeaf4087bfe9f8) Thanks [@kome12](https://github.com/kome12)! - Add a client-side Hyperliquid action builder (`src/hl-action.js`), the groundwork for submitting perp trades straight to Hyperliquid instead of round-tripping through the Nansen backend to build them.

  - msgpack encoder that reproduces the reference `msgpack.packb` output byte-for-byte (insertion-ordered maps, smallest-width ints, utf-8 strings), so an action's `connectionId` hash matches the known-good path.
  - `actionHash` + `l1Eip712` reproduce the phantom-agent EIP-712 payload (Exchange domain, mainnet `source: "a"`) that the existing signer already knows how to sign.
  - Order-wire assembly for market/limit orders, cancels, closes and leverage updates, including TP/SL (`normalTpsl`) grouping and the builder-code attachment.
  - Price/size rounding (`roundPrice`/`roundSize`) ported with Python-parity banker's rounding, so over-precise values that Hyperliquid would reject are rounded identically to the server path.
  - `approveBuilderFee` and `usdClassTransfer` user-signed payload builders.

  Pinned against the live prepare endpoints with golden-vector tests that assert both the built action and its `connectionId` match byte-for-byte.

- [#467](https://github.com/nansen-ai/nansen-cli/pull/467) [`3bd3909`](https://github.com/nansen-ai/nansen-cli/commit/3bd3909155d89b926ceabd506aaea44858d905f6) Thanks [@kome12](https://github.com/kome12)! - Add `src/hl-client.js`, the single direct-to-Hyperliquid submission path: `submitExchange()` POSTs a signed action straight to `api.hyperliquid.xyz/exchange` from the user's machine instead of routing it through the Nansen backend. Reads and market-data stay on the proxy.

  It reproduces the backend proxy's failure handling that it replaces — throwing on a top-level `status: "err"` and on a per-action error nested in `response.data.statuses[].error` (a rejected order that Hyperliquid otherwise reports under a top-level `"ok"`) — so a rejected order can never be mistaken for a fill. The submit is deliberately not retried, since each carries a unique nonce and is not idempotent. The HL base URL is overridable via `NANSEN_HL_API_URL` (for testnet / tests).

- [#467](https://github.com/nansen-ai/nansen-cli/pull/467) [`b5d6946`](https://github.com/nansen-ai/nansen-cli/commit/b5d6946b0380b30d5dc1a4bcc33dcbc18ad0f8ad) Thanks [@kome12](https://github.com/kome12)! - Harden perp, swap, and bridge command safety:

  - `perp order`/`close` now reject an invalid `--side` instead of silently opening the opposite direction, and `perp leverage` rejects an invalid `--margin-type` instead of silently switching to isolated.
  - Perp numeric args (`--size`, `--price`, `--leverage`, `--oid`) are validated as positive numbers, with specific error messages instead of a generic usage banner.
  - Perp commands now require an EVM wallet, with a clear error instead of querying for an `"undefined"` address.
  - `trade quote` validates `--quote-index`, `--slippage`, and `--max-auto-slippage`, rejecting out-of-range values (e.g. a percent-vs-decimal slippage mix-up).
  - `bridge quote` now validates `--slippage` client-side (whole basis points in `[0, 10000]`), rejecting non-numeric or out-of-range values with a clear message instead of forwarding them to an opaque backend 422 (matching how `perp` validates `--slippage`).
  - `perp order`/`close` warn before signing when `--size` (or `--price` for `order`) is finer than the asset's Hyperliquid precision, which the exchange silently rounds.
  - `perp order`/`close` now report the size and price the order actually executes at (post-rounding, slippage-adjusted for market orders) instead of echoing the raw input, so the printed values match the fill.
  - `limit-order list` no longer aborts the whole render when one order has a non-integer amount.
  - Quote loaders reject a cross-type quote (a bridge quote sent to `trade execute`, or a swap quote sent to `bridge execute`).
  - `bridge execute` now refuses a quote that has already been executed, preventing an accidental double-bridge on retry.
  - `bridge quote` accepts human amounts via `--amount-unit token|usd` (default stays base units), resolving token decimals per chain so the same `5` isn't 100x off between chains (USDC is 6 decimals on EVM, 8 on Hyperliquid). Hyperliquid USDC is floored to the bridge's 6-decimal precision to avoid a round-up-past-balance rejection.
  - `perp meta` supports `--all` and `--filter <text>` so assets past the first 20 (e.g. HYPE) are listable.
  - Deprecated top-level aliases now print a deprecation notice on stderr when run, not only in `--help`.
  - `limit-order` rejects a zero-duration or past expiry instead of creating an order that expires immediately.
  - A password with leading/trailing whitespace is no longer mangled when read back from the OS keychain.
  - Nested backend error messages containing an apostrophe are no longer truncated.

- [#467](https://github.com/nansen-ai/nansen-cli/pull/467) [`b577954`](https://github.com/nansen-ai/nansen-cli/commit/b5779543c5a5bb714a3428bb80e3d8f5e3eb865e) Thanks [@kome12](https://github.com/kome12)! - `perp` and `bridge` no longer serve any API response from the `--cache` store, and `bridge execute` no longer retries its submission.

  - **Compliance screening** is always a live check. Every mutating command re-screens the signing wallet immediately before signing; with `--cache` that verdict could previously come from a cache written up to five minutes earlier, which is exactly the window the check exists to close.
  - **`bridge execute`** sets `retry: false`. It proxies to Relay's `/authorize` and Hyperliquid's `/exchange`, neither of which is idempotent, so an automatic re-send on a 500 or 502 could submit the same signed action twice.
  - **Bridge status polling** now observes progress under `--cache`. The cache key is endpoint plus body, so every poll for a given request id hit the same key and the loop would re-read one stale verdict for the whole TTL.
  - **Perp reads** (`positions`, `orders`, `account`, `meta`) and **bridge quotes** bypass the cache too: they either report live balances to the user or feed a signing decision — `close` sizes its order from the positions read, and asset ids come from `meta`.

  `bridge execute` also refuses to sign a step whose EIP-712 type definition is missing or whose `primaryType` matches no entry in it. With an empty field list the digest is still well-formed but commits to none of the action's contents, so it would have produced a valid-looking signature over nothing.

- [#467](https://github.com/nansen-ai/nansen-cli/pull/467) [`4c1d3aa`](https://github.com/nansen-ai/nansen-cli/commit/4c1d3aa16874b2d994ba0e57f52131fdc2dd0748) Thanks [@kome12](https://github.com/kome12)! - Close three residual safety gaps on the perp/bridge signing paths:

  - `perp order` now rejects a take-profit or stop-loss price that rounds to zero at the asset's precision, instead of encoding a `triggerPx` of `0` and resting a dead protective order while the parent position opens unprotected. This extends the existing zero-price/size guard (which only covered the parent leg) to the TP/SL trigger legs.
  - The Privy bridge signing path now refuses to sign an EIP-712 action whose primary type has no field definitions, matching the guard the local signing path already had. An empty type list produces a valid-looking signature that commits to none of the action's contents.
  - The EVM bridge deposit leg resolves its nonce from the signing wallet's own address rather than the server-returned `txData.from`. The transaction is signed with the local key regardless of `from`, so the nonce must come from that account — and this stays correct even if a quote omits `from`.

## 1.35.0

### Minor Changes

- [#469](https://github.com/nansen-ai/nansen-cli/pull/469) [`85b1934`](https://github.com/nansen-ai/nansen-cli/commit/85b1934ae25ed02d1726de8ebe92ea41a98f4454) Thanks [@gulshngill](https://github.com/gulshngill)! - Surface the API's credit and rate-limit response headers.

  Failed calls now report quota state in their error details: an out-of-credits error carries your actual remaining balance, and a rate-limited error carries the limit, what is left, and how long the window needs to drain. Previously the only credit figure the CLI could show was the static per-endpoint estimate published in the API reference — a quote, not what you were charged.

  A warning goes to stderr when your balance will not cover another call of the size just made, so it never interferes with the JSON on stdout.

  Successful responses carry the same numbers under an exported `RESPONSE_META` symbol, and the client exposes `lastResponseMeta`. Both are additive: the JSON each command prints is unchanged.

- [#470](https://github.com/nansen-ai/nansen-cli/pull/470) [`8159300`](https://github.com/nansen-ai/nansen-cli/commit/81593008f829cc83f1d4a6ee9e5c1a10237a9553) Thanks [@gulshngill](https://github.com/gulshngill)! - Surface the API's request id.

  Failed calls now carry `details.requestId` — the value that identifies the call end to end. Quote it when reporting a problem; previously nothing identifying a failed request ever reached the user, which made server errors effectively unreportable. Successful responses expose it alongside the credit and rate-limit figures under the `RESPONSE_META` symbol.

  Absent on deployments that do not send the header yet, in which case the field is simply omitted.

## 1.34.0

### Minor Changes

- [#459](https://github.com/nansen-ai/nansen-cli/pull/459) [`37e6725`](https://github.com/nansen-ai/nansen-cli/commit/37e6725aeeb3b83eb29c4650908b8dbb522ed316) Thanks [@dependabot](https://github.com/apps/dependabot)! - Drop support for Node.js 18 (EOL since April 2025). The minimum supported version is now Node.js 20, matching our test toolchain (vitest 4.x requires Node 20+).

- [#460](https://github.com/nansen-ai/nansen-cli/pull/460) [`aac4bbe`](https://github.com/nansen-ai/nansen-cli/commit/aac4bbe18312edb48c91df60ab555f9c1d8334ce) Thanks [@gulshngill](https://github.com/gulshngill)! - Add trader_type, sectors_filter, sm_label_filter, and trader_label_filter filters to `nansen research perp screener` (ECINT-6680).

  New CLI options:

  - `--trader-type <type>` — filter by trader type: all, sm, whale, public_figure, high_winrate_hl_perps_trader
  - `--sectors-filter <sectors>` — comma-separated sector:subcategory pairs, e.g. "Crypto:AI,TradFi:Stocks"
  - `--sm-label-filter <labels>` — comma-separated Nansen SM labels (applies when trader-type is all or sm)
  - `--trader-label-filter <labels>` — comma-separated HL perps trader labels (applies when trader-type is all or sm)

## 1.33.0

### Minor Changes

- [#457](https://github.com/nansen-ai/nansen-cli/pull/457) [`8149564`](https://github.com/nansen-ai/nansen-cli/commit/8149564f181dc7bfc9c66488ba2373df6f1aab5d) Thanks [@gulshngill](https://github.com/gulshngill)! - x402 on BNB Smart Chain: support all four stablecoins the API now advertises (U, USD1, USDT, USDC) and add Permit2 payment signing. Payments route on the 402's `extra.assetTransferMethod` — `eip3009` keeps the existing gasless flow (U, USD1), while `permit2-exact` (USDT, USDC on BSC) signs a Permit2 `PermitWitnessTransferFrom` against the spender contract advertised in the 402. Permit2 entries are skipped with an actionable message when the wallet hasn't made the one-time `approve(Permit2, …)` for the token. Post-payment balance warnings now check the exact token paid with (per-token decimals) instead of one hardcoded token per network.

## 1.32.1

### Patch Changes

- [#455](https://github.com/nansen-ai/nansen-cli/pull/455) [`875fabb`](https://github.com/nansen-ai/nansen-cli/commit/875fabb3f86736b03c874904e27a898315ef4bfa) Thanks [@gulshngill](https://github.com/gulshngill)! - Support x402 payments with USDT on BNB Smart Chain (`eip155:56`), which the Nansen API now advertises as a payment option. Payment signing already handled any EVM network generically; this adds BSC to the post-payment balance check with the correct token contract and 18-decimal precision (Base USDC and X Layer USDT0 use 6), plus a `bsc` entry in the shared RPC registry with a `NANSEN_BSC_RPC` override.

## 1.32.0

### Minor Changes

- [#451](https://github.com/nansen-ai/nansen-cli/pull/451) [`73600d9`](https://github.com/nansen-ai/nansen-cli/commit/73600d9cd13248a265332ec0728c602b16f44868) Thanks [@kome12](https://github.com/kome12)! - Add `nansen research profiler dex-trades` command for DEX trade history

## 1.31.1

### Patch Changes

- [#443](https://github.com/nansen-ai/nansen-cli/pull/443) [`0ee84db`](https://github.com/nansen-ai/nansen-cli/commit/0ee84db6cdab06054c6ae79c6d871bae0b4f3edb) Thanks [@araa47](https://github.com/araa47)! - Skip native gas pre-check for trades >= $10 USD, where gasless/solver-paid routes (e.g. Relay) are viable. When gas is insufficient on smaller trades, the error now also suggests increasing the trade value as an alternative to topping up gas.

## 1.31.0

### Minor Changes

- [#437](https://github.com/nansen-ai/nansen-cli/pull/437) [`5ec7bd3`](https://github.com/nansen-ai/nansen-cli/commit/5ec7bd33f173cd712f9f592599e32b2a0d28fe0f) Thanks [@gulshngill](https://github.com/gulshngill)! - Add `nansen research` command with 11 subcommands for historical/point-in-time analytics: dex-trades, pnl-leaderboard, token-flow-summary, token-quant-scores, top-holders, who-bought-sold, smart-money-balances, token-screener, wallet-balances, tx-lookup, wallet-transactions. Labels and metrics resolve at the requested date rather than current state — useful for backtesting and historical research.

### Patch Changes

- [#440](https://github.com/nansen-ai/nansen-cli/pull/440) [`701dad4`](https://github.com/nansen-ai/nansen-cli/commit/701dad49f54323cf2b455376b1af3b012e2e0b71) Thanks [@kome12](https://github.com/kome12)! - Fix `research historical-token-screener` schema to mark `--to-date` as required (matching CLI and API behavior)

- [#442](https://github.com/nansen-ai/nansen-cli/pull/442) [`6edbb68`](https://github.com/nansen-ai/nansen-cli/commit/6edbb686b52e00b8725470a3f4409ff15f2ccb95) Thanks [@kome12](https://github.com/kome12)! - `research historical-token-flow-summary` now errors immediately when `--page` or `--limit` are passed (the endpoint returns a single aggregated row and does not support pagination). `research historical-smart-money-balances` now errors when `--sort` or `--order-by` are passed (the endpoint does not support ordering). Previously both flags were silently dropped.

## 1.30.2

### Patch Changes

- [#431](https://github.com/nansen-ai/nansen-cli/pull/431) [`c2c033b`](https://github.com/nansen-ai/nansen-cli/commit/c2c033b86f9dab59df9497ce971ef6f267ee3669) Thanks [@MarcLlopart](https://github.com/MarcLlopart)! - Pass backend quoteId in execute requests for BI correlation

## 1.30.1

### Patch Changes

- [#411](https://github.com/nansen-ai/nansen-cli/pull/411) [`26cd863`](https://github.com/nansen-ai/nansen-cli/commit/26cd863de0604f2d50750ff6742c46772f0b661e) Thanks [@gulshngill](https://github.com/gulshngill)! - Add the `nansen-limit-orders` skill. The skill teaches agents to use the native `nansen trade limit-order create|list|cancel|update` commands for Solana price-triggered orders, and documents the alert-based settlement-signal fallback (`common-token-transfer` smart alert on the settlement wallet) for chains without native limit-order support. Builds on the `trade limit-order` command surface added by #328.

- [#429](https://github.com/nansen-ai/nansen-cli/pull/429) [`511e795`](https://github.com/nansen-ai/nansen-cli/commit/511e7959d735d38e1ee44d2aa29ce19df55b9336) Thanks [@gulshngill](https://github.com/gulshngill)! - Improve discovery of `nansen trade` in package metadata, help output, install tips, and agent-facing docs.

## 1.30.0

### Minor Changes

- [#422](https://github.com/nansen-ai/nansen-cli/pull/422) [`10da2f0`](https://github.com/nansen-ai/nansen-cli/commit/10da2f03284a501d94c433f543b9f1866005d3fc) Thanks [@gulshngill](https://github.com/gulshngill)! - Add x402 support for paying with USDT0 on X Layer alongside Base USDC and Solana SPL USDC. The CLI auto-signs the payment using whatever the API advertises in the 402 `accepts` list — no client-side allowlist, since `src/x402-evm.js` already reads `extra.name`, `extra.version`, and `asset` generically. New `NANSEN_XLAYER_RPC` env var overrides the default X Layer RPC, and `checkX402Balance()` now picks the right token + RPC based on the requirement's `network` field.

### Patch Changes

- [#422](https://github.com/nansen-ai/nansen-cli/pull/422) [`dc9d1c1`](https://github.com/nansen-ai/nansen-cli/commit/dc9d1c1d740128a8667e79a7a4afb3ff31ed1cc5) Thanks [@gulshngill](https://github.com/gulshngill)! - Document MPP (Tempo) as a third paid-access rail alongside API key and x402. Adds a `nansen-mpp-payment` skill, a README section explaining when to reach for the separate `tempo` CLI, and updates the no-API-key 402 error to mention tempo as a third option.

- [#422](https://github.com/nansen-ai/nansen-cli/pull/422) [`93e6a6d`](https://github.com/nansen-ai/nansen-cli/commit/93e6a6d6655380d311739e5f814dda2876b0206a) Thanks [@gulshngill](https://github.com/gulshngill)! - Fix x402 low-balance warning to use the actual stablecoin symbol (USDC or USDT0) returned by `checkX402Balance()` instead of hardcoding "USDC".

- [#422](https://github.com/nansen-ai/nansen-cli/pull/422) [`8f9397f`](https://github.com/nansen-ai/nansen-cli/commit/8f9397f2e1940a7a501cd450eae58a3b243b4782) Thanks [@gulshngill](https://github.com/gulshngill)! - Fix x402 payment header decoding and WalletConnect payment payload encoding to use UTF-8 instead of Latin-1. Previously the `Payment-Required` header was decoded with `atob()`, which corrupted multi-byte UTF-8 chars in fields like `extra.name = 'USD₮0'`. The corrupted name then signed the wrong EIP-712 domain and the server rejected with `invalid_exact_evm_signature`. X Layer USDT0 payments now sign correctly; Base USDC was unaffected because `'USD Coin'` is pure ASCII.

## 1.29.0

### Minor Changes

- [#423](https://github.com/nansen-ai/nansen-cli/pull/423) [`d10aa57`](https://github.com/nansen-ai/nansen-cli/commit/d10aa575c31f7702241ad114276fa5234f2bdf59) Thanks [@imhta](https://github.com/imhta)! - Add Relay aggregator support for Base↔Solana cross-chain swaps. Users now see Relay quotes alongside Li.Fi in `nansen trade quote --to-chain ...`, can execute them through `trade execute`, and optionally use Relay's gasless path with `--gasless` (local/Privy wallets only — not WalletConnect). `trade bridge-status` auto-detects which aggregator produced a tx (via a local tx record) and polls the right backend.

## 1.28.0

### Minor Changes

- [#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.

- [#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.

## 1.27.1

### Patch Changes

- [#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.

## 1.27.0

### Minor Changes

- [#403](https://github.com/nansen-ai/nansen-cli/pull/403) [`fe53dbe`](https://github.com/nansen-ai/nansen-cli/commit/fe53dbe8cf743b970e145e7ad7a00470f16f28df) Thanks [@marius-reed](https://github.com/marius-reed)! - Add prediction market filtering (order_by, volume/liquidity/OI/trader/price/date filters, neg_risk, tags) and address-summary endpoint

### Patch Changes

- [#402](https://github.com/nansen-ai/nansen-cli/pull/402) [`cfd94ce`](https://github.com/nansen-ai/nansen-cli/commit/cfd94ce1e1880e36fb0c97d0ecfe37e614898006) Thanks [@TimNooren](https://github.com/TimNooren)! - Enforce USDC or native token on one side of every swap

## 1.26.1

### Patch Changes

- [#392](https://github.com/nansen-ai/nansen-cli/pull/392) [`025993d`](https://github.com/nansen-ai/nansen-cli/commit/025993df798ddb406340511e0dada1f9a962be56) Thanks [@TimNooren](https://github.com/TimNooren)! - Add gas balance validation: rejects trades when the wallet lacks sufficient native token for gas fees.

## 1.26.0

### Minor Changes

- [#380](https://github.com/nansen-ai/nansen-cli/pull/380) [`12e4e25`](https://github.com/nansen-ai/nansen-cli/commit/12e4e25d50f50ff1ebbae160ba1016abd1cdbb4d) Thanks [@TimNooren](https://github.com/TimNooren)! - Add `--amount-unit percent` to trade commands, allowing trades as a percentage of wallet balance (e.g. `--amount 100 --amount-unit percent` to sell all)

### Patch Changes

- [#382](https://github.com/nansen-ai/nansen-cli/pull/382) [`d9c87ef`](https://github.com/nansen-ai/nansen-cli/commit/d9c87ef9df51a3e9c53ea59674ad9efe9aa33fb7) Thanks [@kome12](https://github.com/kome12)! - fix: default `profiler balance` chain to `'all'` instead of `'ethereum'`

  Previously, `nansen profiler balance --address <addr>` without `--chain` defaulted to `ethereum`, returning empty results for wallets with no ETH mainnet holdings (e.g. Base-only or Solana-only wallets). Now defaults to `'all'`, letting the API auto-route based on address format.

## 1.25.1

### Patch Changes

- [#367](https://github.com/nansen-ai/nansen-cli/pull/367) [`9fea10a`](https://github.com/nansen-ai/nansen-cli/commit/9fea10a844acbaccf37a348dfd4efd5c32f76a4a) Thanks [@kome12](https://github.com/kome12)! - add --premium-labels flag to tgm/holders, tgm/pnl-leaderboard, tgm/perp-pnl-leaderboard, and perp-leaderboard endpoints

## 1.25.0

### Minor Changes

- [#363](https://github.com/nansen-ai/nansen-cli/pull/363) [`6ae402e`](https://github.com/nansen-ai/nansen-cli/commit/6ae402ef1e5bdeacf83fe04bcf6e8e0c9f9c91b7) Thanks [@TimNooren](https://github.com/TimNooren)! - Add `--amount-unit usd` to trade commands — specify swap amounts in USD

### Patch Changes

- [#374](https://github.com/nansen-ai/nansen-cli/pull/374) [`0f14803`](https://github.com/nansen-ai/nansen-cli/commit/0f148031ef7590f3405c1dba9f31ad83768a7141) Thanks [@TimNooren](https://github.com/TimNooren)! - Fix cross-chain quote display: show adaptive precision for sub-cent bridge fees, "< 1 min" for fast bridges, and echo --to-wallet address in output

- [#366](https://github.com/nansen-ai/nansen-cli/pull/366) [`f358fff`](https://github.com/nansen-ai/nansen-cli/commit/f358fffcc80136c4e609f2e056f2c5ffb052d626) Thanks [@kome12](https://github.com/kome12)! - fix(token): replace dead `--days` param with working `--timeframe` for `token flow-intelligence`

  The `--days` option was accepted but never sent to the API, resulting in always fetching `1d` data. This replaces it with `--timeframe` (enum: `1h | 6h | 12h | 1d | 7d`, default `1d`) which maps correctly to the API parameter.

## 1.24.0

### Minor Changes

- [#333](https://github.com/nansen-ai/nansen-cli/pull/333) [`c8fe79c`](https://github.com/nansen-ai/nansen-cli/commit/c8fe79c4ec5e1ba6acf2498d9bfbe14c726a913c) Thanks [@imhta](https://github.com/imhta)! - Add cross-chain swap support between Solana and Base via Li.Fi bridge.

  `nansen trade quote --chain base --to-chain solana --from ETH --to SOL --amount 0.01 --amount-unit token`
  `nansen trade execute --quote <id>`

  Bridge status can be checked with `nansen trade bridge-status`.

### Patch Changes

- [#365](https://github.com/nansen-ai/nansen-cli/pull/365) [`56335af`](https://github.com/nansen-ai/nansen-cli/commit/56335af600e51436b30ad2fc1530aa754bac2a2f) Thanks [@TimNooren](https://github.com/TimNooren)! - Add balance pre-check before quote API calls. Validates sell token balance, auto-adjusts near-full-balance trades (≤2% over), and reserves gas fees for native token swaps (SOL/ETH).

## 1.23.1

### Patch Changes

- [#361](https://github.com/nansen-ai/nansen-cli/pull/361) [`ff22da3`](https://github.com/nansen-ai/nansen-cli/commit/ff22da376c1072ef06e84054f6ee31c058e6e08c) Thanks [@TimNooren](https://github.com/TimNooren)! - fix(alerts): error when --webhook-secret is passed without --webhook

  Previously, passing --webhook-secret with a non-webhook channel (e.g. --telegram)
  silently discarded the secret with no warning. The alert was created successfully
  but without any signing, giving the false impression that the secret was active.

  Now throws an actionable error: "--webhook-secret requires --webhook".

- [#358](https://github.com/nansen-ai/nansen-cli/pull/358) [`70ee712`](https://github.com/nansen-ai/nansen-cli/commit/70ee71205343fb2d003eb5f50144e266bdc6109e) Thanks [@TimNooren](https://github.com/TimNooren)! - Add pre-quote trade input validation: rejects same-token swaps, invalid address formats, and non-positive amounts before any network call.

## 1.23.0

### Minor Changes

- [#341](https://github.com/nansen-ai/nansen-cli/pull/341) [`4b60056`](https://github.com/nansen-ai/nansen-cli/commit/4b6005697d52b5d432b9b32bcd1d36422f9166cc) Thanks [@gulshngill](https://github.com/gulshngill)! - Add `--webhook <url>` and `--webhook-secret <secret>` flags to `alerts create` and `alerts update`.

  Allows alerts to be delivered to any HTTP/HTTPS endpoint via POST, alongside
  the existing `--telegram`, `--slack`, and `--discord` channels. The optional
  `--webhook-secret` enables HMAC payload signing for verification.

### Patch Changes

- [#344](https://github.com/nansen-ai/nansen-cli/pull/344) [`3dc09cc`](https://github.com/nansen-ai/nansen-cli/commit/3dc09cc8aa38cd4da4ae305f83e9599efb3b9ff9) Thanks [@0xlaveen](https://github.com/0xlaveen)! - Add nansen-agent-guide skill — routing guide for when to use `nansen agent` vs direct CLI data commands

- [#347](https://github.com/nansen-ai/nansen-cli/pull/347) [`a243c7a`](https://github.com/nansen-ai/nansen-cli/commit/a243c7a33f28057949d2060c732083642422eb18) Thanks [@kome12](https://github.com/kome12)! - Add --buy-or-sell option to `token who-bought-sold` command — allows filtering by buy or sell side (BUY | SELL, defaults to BUY)

## 1.22.0

### Minor Changes

- [#336](https://github.com/nansen-ai/nansen-cli/pull/336) [`c3b1fbd`](https://github.com/nansen-ai/nansen-cli/commit/c3b1fbdee46c15326a1656bf27a314f6c55dddf8) Thanks [@kome12](https://github.com/kome12)! - Add --label option to `token flows` command to filter by holder segment (top_100_holders, smart_money, public_figure, whale, exchange).

- [#334](https://github.com/nansen-ai/nansen-cli/pull/334) [`83244c6`](https://github.com/nansen-ai/nansen-cli/commit/83244c658d4ece2072dea0c6ed405a088c98aa4f) Thanks [@kome12](https://github.com/kome12)! - Add `--include-stablecoins` flag to `token screener` command. Pass `--include-stablecoins false` to exclude stablecoins from screener results (API default is `true`). Supports combined usage with `--smart-money`.

- [#339](https://github.com/nansen-ai/nansen-cli/pull/339) [`27ebcfc`](https://github.com/nansen-ai/nansen-cli/commit/27ebcfc2a3afd836db595df6d5a2a5f9242b624c) Thanks [@TimNooren](https://github.com/TimNooren)! - Add --amount-unit token flag to trade quote for human-readable amounts

## 1.21.0

### Minor Changes

- [#315](https://github.com/nansen-ai/nansen-cli/pull/315) [`908fa0c`](https://github.com/nansen-ai/nansen-cli/commit/908fa0ccdf18cb79b7efb58b9b31f66e0afedff6) Thanks [@TimNooren](https://github.com/TimNooren)! - Add `nansen agent` command for the Nansen AI research agent with fast/expert modes, SSE streaming, conversation continuation, and JSON output.

### Patch Changes

- [#326](https://github.com/nansen-ai/nansen-cli/pull/326) [`1532ba4`](https://github.com/nansen-ai/nansen-cli/commit/1532ba420174ed7635a42641f0c1a2802077fdc0) Thanks [@TimNooren](https://github.com/TimNooren)! - Show API credit cost in research subcommand help text (fetched from OpenAPI spec, cached 24h).

- [#330](https://github.com/nansen-ai/nansen-cli/pull/330) [`a6b9b8f`](https://github.com/nansen-ai/nansen-cli/commit/a6b9b8fc7d291ee7375941bb275c224939338161) Thanks [@0xlaveen](https://github.com/0xlaveen)! - Suppress misleading PASSWORD_REQUIRED error when `--provider privy` is specified. Privy wallets don't need a password — only the Privy-specific credentials error is now shown when PRIVY_APP_ID/PRIVY_APP_SECRET are missing.

- [#329](https://github.com/nansen-ai/nansen-cli/pull/329) [`f047833`](https://github.com/nansen-ai/nansen-cli/commit/f047833c7e6fb55cb713e0b69f82282fe87d4566) Thanks [@TimNooren](https://github.com/TimNooren)! - Limit deprecation warnings and update notices to help output only, keeping stdout/stderr clean for programmatic usage.

- [#332](https://github.com/nansen-ai/nansen-cli/pull/332) [`e9b6de1`](https://github.com/nansen-ai/nansen-cli/commit/e9b6de17fdba3f46733dff026c2495c095bfbf35) Thanks [@0xlaveen](https://github.com/0xlaveen)! - docs: add trading examples and Privy wallet setup to README

## 1.20.0

### Minor Changes

- [#302](https://github.com/nansen-ai/nansen-cli/pull/302) [`3f0a5ab`](https://github.com/nansen-ai/nansen-cli/commit/3f0a5abad463c0386122efbe746809913aa823ba) Thanks [@arein](https://github.com/arein)! - Add post-install onboarding that interactively offers to install the Nansen AI coding skill and run a test query after `npm install -g nansen-cli`. Non-interactive environments (CI, piped stdin) receive a one-liner tip and are never blocked.

### Patch Changes

- [#313](https://github.com/nansen-ai/nansen-cli/pull/313) [`bb4d9e4`](https://github.com/nansen-ai/nansen-cli/commit/bb4d9e475158147645cae9b8bdd2555568a1e515) Thanks [@0xlaveen](https://github.com/0xlaveen)! - Update API key setup URL from app.nansen.ai/api to app.nansen.ai/auth/agent-setup across CLI help text, error messages, README, and postinstall script.

## 1.19.0

### Minor Changes

- [#306](https://github.com/nansen-ai/nansen-cli/pull/306) [`f685eb8`](https://github.com/nansen-ai/nansen-cli/commit/f685eb8b87d2915a7a94e8c1a3d92f84e4802e4a) Thanks [@0xlaveen](https://github.com/0xlaveen)! - Rename 30 skills for clarity and clawhub slug uniqueness. Abbreviations expanded (`pm` → `polymarket`, `sm` prefix added where relevant), ambiguous names made specific (`nansen-wallet` → `nansen-wallet-manager`, `nansen-profiler` → `nansen-wallet-profiler`, `nansen-search` → `nansen-general-search`, `nansen-trade` → `nansen-trading`, etc.).

### Patch Changes

- [#308](https://github.com/nansen-ai/nansen-cli/pull/308) [`569d7d4`](https://github.com/nansen-ai/nansen-cli/commit/569d7d43e428732d3c10b4e57368cb12ef0086c3) Thanks [@kome12](https://github.com/kome12)! - fix: include src subdirectories in npm package

  The `files` field in package.json used `src/*.js` which only matched files directly in `src/`, causing `src/commands/` to be missing from the 1.18.0 publish. Changed to `src/**/*.js` to include all subdirectories recursively, and added `!src/__tests__/**` to exclude test files from the package.

## 1.18.0

### Minor Changes

- [#265](https://github.com/nansen-ai/nansen-cli/pull/265) [`c3de691`](https://github.com/nansen-ai/nansen-cli/commit/c3de6914dcdd29f54d027f0cc415c23dd646c003) Thanks [@TimNooren](https://github.com/TimNooren)! - Add `nansen alerts` command for managing smart alerts (list, create, update, toggle, delete).

  Supports three alert types: `sm-token-flows`, `common-token-transfer`, and `smart-contract-call`.
  Named flags (`--inflow-1h-min`, `--chains`, `--telegram`, etc.) let you build alerts without raw JSON;
  a `--data` escape hatch is available for full config overrides.

  Also adds a `nansen-alerts` skill for agent integration.

- [#295](https://github.com/nansen-ai/nansen-cli/pull/295) [`3ddcbde`](https://github.com/nansen-ai/nansen-cli/commit/3ddcbdec50d55e4477cd3f53c5064126dbd8580a) Thanks [@kome12](https://github.com/kome12)! - feat: add `nansen web search` and `nansen web fetch` commands (ECINT-6393)

  - `nansen web search <query> [query...]` — search the web for one or more queries in parallel via `/api/v1/search/web-search`
  - `nansen web fetch <url> [url...] --question <q>` — fetch and analyze URL content with AI via `/api/v1/search/web-fetch`

### Patch Changes

- [#293](https://github.com/nansen-ai/nansen-cli/pull/293) [`bcd95a8`](https://github.com/nansen-ai/nansen-cli/commit/bcd95a88942e96018337ae6b7de9f2abdbdc3464) Thanks [@TimNooren](https://github.com/TimNooren)! - Add default values for all required alert data fields to match backend schema

- [#265](https://github.com/nansen-ai/nansen-cli/pull/265) [`c3de691`](https://github.com/nansen-ai/nansen-cli/commit/c3de6914dcdd29f54d027f0cc415c23dd646c003) Thanks [@TimNooren](https://github.com/TimNooren)! - Fix `alerts list` filtering (`--type`, `--enabled`, `--disabled`, `--chain`, `--token-address`, `--limit`, `--offset`).

  Filters were sent as query params but silently ignored by the API. Now applied client-side after fetching all alerts.

- [#301](https://github.com/nansen-ai/nansen-cli/pull/301) [`cda6796`](https://github.com/nansen-ai/nansen-cli/commit/cda6796642c588965111c53c583af2b21444d30b) Thanks [@kome12](https://github.com/kome12)! - fix: add missing openclaw metadata to 19 skills

- [#294](https://github.com/nansen-ai/nansen-cli/pull/294) [`8a1cc7b`](https://github.com/nansen-ai/nansen-cli/commit/8a1cc7bdfbd9597860384dfd40fd28705e5c947c) Thanks [@yodablocks](https://github.com/yodablocks)! - fix: include skills/ directory in published npm package

## 1.17.0

### Minor Changes

- [#279](https://github.com/nansen-ai/nansen-cli/pull/279) [`174a3d6`](https://github.com/nansen-ai/nansen-cli/commit/174a3d612b3f198c5e5b979c269d896f9d906704) Thanks [@kome12](https://github.com/kome12)! - Add `nansen account` command to verify API key and check credit balance

  Users can now run `nansen account` to confirm their API key is valid and see
  their current plan and remaining credits — without consuming any credits.

  This calls the new `GET /api/v1/account` endpoint (ECINT-6365).

- [#234](https://github.com/nansen-ai/nansen-cli/pull/234) [`10a5ced`](https://github.com/nansen-ai/nansen-cli/commit/10a5ced9f1f751666d034cecfc431e335183741c) Thanks [@kome12](https://github.com/kome12)! - Reduced schema.json to a minimal format (~66% smaller).

### Patch Changes

- [#272](https://github.com/nansen-ai/nansen-cli/pull/272) [`50213c1`](https://github.com/nansen-ai/nansen-cli/commit/50213c1d82375a153aa1bad3a53bbd7059cd9f5b) Thanks [@TimNooren](https://github.com/TimNooren)! - fix: show human-readable error when trade fails due to insufficient ETH

  When a wallet has no ETH and a trade is attempted, the raw Ethereum RPC
  error ("insufficient funds for gas \* price + value: ... have 0 want
  400000000000000 (supplied gas 600000000)") is now translated into a
  user-friendly message showing amounts in ETH with a funding hint, e.g.
  "Insufficient ETH: wallet has 0.000000 ETH but this trade needs ~0.000400
  ETH (amount + gas). Send ETH to 0x... before trading."

## 1.16.1

### Patch Changes

- [#249](https://github.com/nansen-ai/nansen-cli/pull/249) [`0c17437`](https://github.com/nansen-ai/nansen-cli/commit/0c17437cf65d8b4f0516ede386adefec57d8ab3d) Thanks [@0xlaveen](https://github.com/0xlaveen)! - Add `pm` to top-level COMMAND_ALIASES so `nansen pm <subcommand>` works (previously only `nansen research pm <subcommand>` resolved the alias)

- [#244](https://github.com/nansen-ai/nansen-cli/pull/244) [`6427a9f`](https://github.com/nansen-ai/nansen-cli/commit/6427a9fdb7295dee94d7aed10cdb0164c46c7d73) Thanks [@Nicolai1205](https://github.com/Nicolai1205)! - Add 7 new agent skills: nansen-token-search, nansen-sm-trend, nansen-wallet-cluster, nansen-wallet-compare, nansen-token-indicators, nansen-cross-chain-flow, nansen-batch-wallet. All validated against live API.

## 1.16.0

### Minor Changes

- [#196](https://github.com/nansen-ai/nansen-cli/pull/196) [`0c286c2`](https://github.com/nansen-ai/nansen-cli/commit/0c286c2d75f977894da8ff18a105aaf21f55f9f2) Thanks [@arein](https://github.com/arein)! - Add Solana WalletConnect support for trading (quote and execute). Solana wallets like Phantom and Solflare can now sign DEX swap transactions via WalletConnect v2.

## 1.15.0

### Minor Changes

- [#216](https://github.com/nansen-ai/nansen-cli/pull/216) [`5b88241`](https://github.com/nansen-ai/nansen-cli/commit/5b882411134efc5ece44d640adc105c8dd8c5771) Thanks [@TimNooren](https://github.com/TimNooren)! - Unified wallet abstraction: Privy server wallets are first-class citizens.

  - `wallet create --provider privy` creates EVM + Solana wallets via Privy and stores a local reference
  - All wallet commands (list, show, delete, default, send) work by name regardless of provider
  - Trading (quote + execute) supports Privy wallets with sign-only + Trading API broadcast
  - x402 auto-payment routes through Privy when credentials are configured

### Patch Changes

- [#232](https://github.com/nansen-ai/nansen-cli/pull/232) [`443aaad`](https://github.com/nansen-ai/nansen-cli/commit/443aaad15da051ac65e0999b4c4b09436050d0fe) Thanks [@kome12](https://github.com/kome12)! - Remove unsupported chains (zksync, unichain) from CLI

## 1.14.0

### Minor Changes

- [#231](https://github.com/nansen-ai/nansen-cli/pull/231) [`c3968da`](https://github.com/nansen-ai/nansen-cli/commit/c3968dacb52521235ad6502321650148ac825d01) Thanks [@araa47](https://github.com/araa47)! - Agent-first secure wallet flow — OS keychain persistence, no interactive prompts

  - **New `src/keychain.js`**: Password persistence via OS keychain (macOS Keychain / Linux secret-tool), with base64-encoded `.credentials` file fallback for containers/CI. Zero npm dependencies.
  - **Non-interactive by default**: All readline prompts removed. Agents get structured JSON errors (`PASSWORD_REQUIRED`, `API_KEY_REQUIRED`) with actionable instructions. `--human` flag re-enables interactive mode.
  - **Two-step wallet creation**: Agent asks user for password, runs `NANSEN_WALLET_PASSWORD=<pw> nansen wallet create`. Password auto-persists to keychain — all future operations are passwordless.
  - **New commands**: `wallet secure` (migrate to keychain), `wallet forget-password` (clear from all stores).
  - **Bug fixes**: Clear `passwordHash` on last wallet delete, verify password before keychain writes, exit non-zero when keychain migration fails, source-aware error messages.
  - **New skill**: `nansen-wallet-migration` for migrating from old `~/.nansen/.env` storage to keychain.

## 1.13.1

### Patch Changes

- [#225](https://github.com/nansen-ai/nansen-cli/pull/225) [`051e4a3`](https://github.com/nansen-ai/nansen-cli/commit/051e4a353641d000facd2133810c059981b9ac7f) Thanks [@TimNooren](https://github.com/TimNooren)! - Remove "recommended, lower fees" label from Base network in wallet create output

## 1.13.0

### Minor Changes

- [#107](https://github.com/nansen-ai/nansen-cli/pull/107) [`5877c06`](https://github.com/nansen-ai/nansen-cli/commit/5877c06061c1d32998fa3ce011c16f4352fc22dc) Thanks [@marius-reed](https://github.com/marius-reed)! - Add 11 prediction market (Polymarket) endpoints under `nansen research pm`. Includes OHLCV, orderbook, top holders, trades, screeners, PnL, position detail, and categories. Supports `--market-id`, `--address`, `--sort-by`, `--query`, `--status` flags with pagination, sorting, and table output.

## 1.12.0

### Minor Changes

- [#207](https://github.com/nansen-ai/nansen-cli/pull/207) [`73ca500`](https://github.com/nansen-ai/nansen-cli/commit/73ca5009c03ad541673165ca6b50f33ff4cc1673) Thanks [@TimNooren](https://github.com/TimNooren)! - Add --unsafe-no-password flag to wallet create for agent-friendly passwordless wallets.

### Patch Changes

- [#212](https://github.com/nansen-ai/nansen-cli/pull/212) [`726c29d`](https://github.com/nansen-ai/nansen-cli/commit/726c29d2676c8a37772299c6237b44890493dfa5) Thanks [@0xlaveen](https://github.com/0xlaveen)! - Clarify empty input handling in parseAddressList with explicit early return

- [#218](https://github.com/nansen-ai/nansen-cli/pull/218) [`8c4dd71`](https://github.com/nansen-ai/nansen-cli/commit/8c4dd71ce215026e149a6b097540c46622f13d3a) Thanks [@TimNooren](https://github.com/TimNooren)! - fix: `nansen changelog --since <version>` now correctly filters changeset-format entries (## x.y.z) in addition to Keep a Changelog entries (## [x.y.z])

- [#209](https://github.com/nansen-ai/nansen-cli/pull/209) [`a6dc1ed`](https://github.com/nansen-ai/nansen-cli/commit/a6dc1ed9dc40ad3506e7debe09746d463a70c14d) Thanks [@0xlaveen](https://github.com/0xlaveen)! - fix: prevent --help from executing destructive commands (logout, schema, cache)

## 1.11.2

### Patch Changes

- [#205](https://github.com/nansen-ai/nansen-cli/pull/205) [`dba24aa`](https://github.com/nansen-ai/nansen-cli/commit/dba24aaa64b2083fdbaa85a002758bfe21d9f4a0) Thanks [@TimNooren](https://github.com/TimNooren)! - Add hot wallet and password handling warnings to wallet create output

## 1.11.1

### Patch Changes

- [#194](https://github.com/nansen-ai/nansen-cli/pull/194) [`89225f5`](https://github.com/nansen-ai/nansen-cli/commit/89225f5d5b566f7eda77b1876c77545c2feb6a1c) Thanks [@TimNooren](https://github.com/TimNooren)! - fix: --help on trade subcommands and wallet subcommands now shows full help identical to the no-args case

- [#199](https://github.com/nansen-ai/nansen-cli/pull/199) [`9ae981e`](https://github.com/nansen-ai/nansen-cli/commit/9ae981e6dcf7fa663e47a3608afab7f12e0a9463) Thanks [@TimNooren](https://github.com/TimNooren)! - fix: replace misleading `walletconnect connect` command reference in x402 payment error with actionable guidance mentioning both local wallet (`nansen wallet create`) and external WalletConnect CLI options

## 1.11.0

### Minor Changes

- [#186](https://github.com/nansen-ai/nansen-cli/pull/186) [`feecc50`](https://github.com/nansen-ai/nansen-cli/commit/feecc5080254b55aaef0addb646279d52a468063) Thanks [@TimNooren](https://github.com/TimNooren)! - Trade commands output to stdout instead of stderr; wallet send prints human-readable text instead of JSON

### Patch Changes

- [#166](https://github.com/nansen-ai/nansen-cli/pull/166) [`c1034db`](https://github.com/nansen-ai/nansen-cli/commit/c1034dbb4bf2fc173f377cbc0adbbbe3e67873aa) Thanks [@0xlaveen](https://github.com/0xlaveen)! - fix: pass --page parameter correctly in smart-money, profiler, token, perp, and points commands

- [#137](https://github.com/nansen-ai/nansen-cli/pull/137) [`1214767`](https://github.com/nansen-ai/nansen-cli/commit/12147675aadfd0bd97627cb2f41f1dcc5205b0d7) Thanks [@0xlaveen](https://github.com/0xlaveen)! - Add missing sort/filters options to profiler schema and fix pnl sort/filters forwarding

## 1.10.1

### Patch Changes

- [#133](https://github.com/nansen-ai/nansen-cli/pull/133) [`4cbeb65`](https://github.com/nansen-ai/nansen-cli/commit/4cbeb6510c286660f611117d2d8b0508f2340e31) Thanks [@0xlaveen](https://github.com/0xlaveen)! - fix: correct profiler pagination parameter from `recordsPerPage` to `per_page`; remove unsupported pagination from pnl-summary; add --limit to labels, historical-balances, counterparties schema

- [#164](https://github.com/nansen-ai/nansen-cli/pull/164) [`ec6ab78`](https://github.com/nansen-ai/nansen-cli/commit/ec6ab78d604a177c3459833091531de3fc07add1) Thanks [@DMagowan](https://github.com/DMagowan)! - fix: correct `--date` option marked as `required: true` when it is optional

  The schema incorrectly marked `--date` as `required: true` for three commands:

  - `research token flows`
  - `research token who-bought-sold`
  - `research profiler transactions`

  All three use `parseDateOption` with a `days` fallback, so `--date` is optional — omitting it defaults to a rolling window based on `--days`. An agent following the schema strictly would unnecessarily refuse to run these commands without a date.

- [#162](https://github.com/nansen-ai/nansen-cli/pull/162) [`4dbe181`](https://github.com/nansen-ai/nansen-cli/commit/4dbe181d3b4973881bcb7fb445cf6559819006b6) Thanks [@DMagowan](https://github.com/DMagowan)! - fix: surface wallet prerequisite in `trade quote` help text and schema

  `nansen trade quote` requires a configured wallet (the trading API builds a transaction specific to the sender address), but this was not communicated until the command failed. Adds a PREREQUISITE section to the usage text and a `prerequisites` field to the schema so agents can discover this requirement before running the command.

- [#165](https://github.com/nansen-ai/nansen-cli/pull/165) [`92f37ea`](https://github.com/nansen-ai/nansen-cli/commit/92f37eaa8655ae1a39b9200aafaf4771a0859229) Thanks [@0xlaveen](https://github.com/0xlaveen)! - Fix trading docs and config to reflect actual supported chains (Base and Solana only)

## 1.10.0

### Minor Changes

- [#125](https://github.com/nansen-ai/nansen-cli/pull/125) [`5a5a80a`](https://github.com/nansen-ai/nansen-cli/commit/5a5a80af9c2c5b93efcc707925b004f077e13c36) Thanks [@0xlaveen](https://github.com/0xlaveen)! - Add modular skills/ directory with 7 agent-optimised SKILL.md files (nansen-token, nansen-smart-money, nansen-profiler, nansen-trade, nansen-wallet, nansen-perp, nansen-search) following the linear-cli pattern. Each skill has scoped frontmatter, agent routing descriptions, bash examples, and exit codes. Add skills nudge to `nansen --help` output.

### Patch Changes

- [#122](https://github.com/nansen-ai/nansen-cli/pull/122) [`9a1ada8`](https://github.com/nansen-ai/nansen-cli/commit/9a1ada8543cd6fdbcc10d2d5004fe2e2e1a88928) Thanks [@TimNooren](https://github.com/TimNooren)! - `nansen research <unknown>` and `nansen trade <unknown>` now exit with code 1 and return `{"success":false,...}` instead of silently exiting 0.

- [#138](https://github.com/nansen-ai/nansen-cli/pull/138) [`c61881f`](https://github.com/nansen-ai/nansen-cli/commit/c61881f5455b9fff7fb97841652a72af58ab8e0b) Thanks [@TimNooren](https://github.com/TimNooren)! - Fix `nansen login --help` to show usage instead of erroring. Previously, `--help` was silently ignored on TTY (showing the interactive prompt) and caused an error on non-TTY. Also fixes the post-login suggested command to use the non-deprecated `nansen research token screener` path.

- [#129](https://github.com/nansen-ai/nansen-cli/pull/129) [`eeabf89`](https://github.com/nansen-ai/nansen-cli/commit/eeabf8988dafc7fb1964fd2eef629f03c6a4420a) Thanks [@araa47](https://github.com/araa47)! - Fix `token ohlcv` sending unsupported pagination/limit params that caused 422 errors

- [#139](https://github.com/nansen-ai/nansen-cli/pull/139) [`e86dc68`](https://github.com/nansen-ai/nansen-cli/commit/e86dc6869f524d3dc59da4c7c04cb1ace1b7246b) Thanks [@TimNooren](https://github.com/TimNooren)! - Fix API key prompt masking: each keystroke was showing the real character followed by `*` (e.g. `f*o*o*`) because the readline interface was active alongside raw mode, causing double output. Moving readline creation into the non-hidden branch eliminates the double-echo and also fixes backspace incorrectly clearing the prompt label.

- [#129](https://github.com/nansen-ai/nansen-cli/pull/129) [`eeabf89`](https://github.com/nansen-ai/nansen-cli/commit/eeabf8988dafc7fb1964fd2eef629f03c6a4420a) Thanks [@araa47](https://github.com/araa47)! - Fix `trade quote` crash when no wallet exists — now shows actionable error instead of uncaught exception

- [#126](https://github.com/nansen-ai/nansen-cli/pull/126) [`f3b87e7`](https://github.com/nansen-ai/nansen-cli/commit/f3b87e7491d03d052d5d72fcc991de0c33caf51f) Thanks [@araa47](https://github.com/araa47)! - Remove root SKILL.md so `npx skills add nansen-ai/nansen-cli` correctly discovers all 7 skills in `skills/` instead of treating the repo as a single skill.

## 1.9.3

### Patch Changes

- [#118](https://github.com/nansen-ai/nansen-cli/pull/118) [`0bd4c3c`](https://github.com/nansen-ai/nansen-cli/commit/0bd4c3c1946e575e2c2db5e02d17f266e79752a4) Thanks [@TimNooren](https://github.com/TimNooren)! - Show warning when trade quote price impact exceeds 5%, and show pin command to avoid fallback to worse quotes

## 1.9.2

### Patch Changes

- [#116](https://github.com/nansen-ai/nansen-cli/pull/116) [`7a2b729`](https://github.com/nansen-ai/nansen-cli/commit/7a2b7293c2e731ae1d5375b15df9c05c5611a9cb) Thanks [@TimNooren](https://github.com/TimNooren)! - Fix usage examples for `nansen trade quote` to show correct command name instead of deprecated `nansen quote`

- [#114](https://github.com/nansen-ai/nansen-cli/pull/114) [`37d8c0b`](https://github.com/nansen-ai/nansen-cli/commit/37d8c0b87797145a15b087caa5eb474673217580) Thanks [@TimNooren](https://github.com/TimNooren)! - Show API key URL in non-interactive login error message

- [#117](https://github.com/nansen-ai/nansen-cli/pull/117) [`55ad922`](https://github.com/nansen-ai/nansen-cli/commit/55ad922826a7a2411889edeede42fbfc7b70d7a5) Thanks [@TimNooren](https://github.com/TimNooren)! - Add --wallet and WalletConnect documentation to `nansen trade help` output

## 1.9.1

### Patch Changes

- [#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.

## 1.9.0

### Minor Changes

- [#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.

- [#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)

### Patch Changes

- [#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.

- [#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).

- [#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

## 1.8.0

### Minor Changes

- [#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

  - Added CHANGELOG.md following Keep a Changelog format with history back to v1.5.0
  - Added `nansen changelog` command with `--since <version>` filtering
  - Added one-time upgrade notice on first run after version update (prints to stderr)

- [#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

- [#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

  - Commands reorganized: `smart-money`, `profiler`, `token`, `portfolio` now live under `nansen research`
  - New `nansen trade` namespace for `quote` and `execute`
  - New `nansen wallet` namespace for wallet management
  - Old top-level commands still work with deprecation warnings

- [#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.

All notable changes to the Nansen CLI will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/).

## [1.7.0] - 2026-02-24

### Added

- **Trading commands** — `quote` and `execute` for DEX swaps (EVM + Solana)
- **Wallet management** — `wallet create`, `list`, `show`, `export`, `default`, `delete`
- **Wallet send** — transfer tokens on EVM and Solana (`wallet send`)
- **x402 auto-payment** — automatic payment via Base USDC or Solana SPL USDC
- Explorer links in transaction output
- `--dry-run` flag for `wallet send`
- x402 low balance warning
- AI Agent Access setup docs and improved onboarding flow

### Fixed

- Solana execute crash with OKX quotes
- x402 auto-pay retry path (3 reference errors)
- Gas estimation — use API `quote.gas` as floor
- Pre-flight simulation moved after approval (industry standard)
- EVM signing edge cases with pure JS ECDSA
- Wallet send crashes on amount parsing and silent success
- Solana confirmation and SPL token transfer account ordering
- Suppress duplicate JSON output from quote/execute
- Suppress approval warning for native ETH swaps

### Changed

- Pricing clarity — from $0.01/call, min $0.05 balance
- Consolidated crypto primitives into shared module

## [1.6.0] - 2026-02-14

### Added

- `token indicators` endpoint
- `profiler search` — general entity search command
- `--x402-payment-signature` flag for pre-signed payment headers
- `X-Client-Type` and `X-Client-Version` tracking headers on all API requests

### Fixed

- Error JSON now outputs to stdout (not stderr) for consistent agent parsing
- Config loading — environment variables correctly override file config

## [1.5.1] - 2026-02-07

### Added

- Allow API requests without API key when using x402 payment flow

## [1.5.0] - 2026-01-31

_Baseline version. Changes above are relative to this release._
