-
#667
8dad3b9Thanks @gulshngill! -trade executeandbridge executenow take--dry-runand--yes.--dry-runruns the sign-free preflight available from the cached quote, its public signer address, and read-only RPC calls; prints the trade or transfer that would be sent (chain, tokens, amounts, recipient, approvals, fees — plus the current allowance and revert simulation on EVM); and stops before wallet credentials or signing: no wallet password needed, the quote is not consumed, exit code 0. Real execution still resolves and revalidates the live signer. When stdin is an interactive terminal, both commands now print that plan and askBroadcast this transaction? [y/N]before broadcasting; declining exits 1 with nothing signed.--yes(-y) orNANSEN_YES=1skips the prompt. Non-interactive callers — agents, CI, pipes — are unchanged: they proceed without prompting, and--yesis accepted there as a no-op. -
#501
5a79f9dThanks @gulshngill! - Guardwallet exportagainst accidental plaintext key disclosure. The default output is now redacted (addresses only — no decryption, no password needed). Printing private keys to stdout requires explicit acknowledgement via--reveal(which also warns on stderr when stdout is an interactive terminal), and the new--file <path>writes keys to a file created with 0600 permissions (refusing to overwrite) while keeping stdout clean. Scripts that parsedwallet exportoutput must add--revealor switch to--file.--filefailures carry machine-readable codes:FILE_EXISTSwhen the path already exists,FILE_WRITE_FAILEDfor any other create/write error.This safety hardening is intentionally classified as a minor change rather than a major release: it changes an unsafe default to prevent accidental private-key disclosure while preserving explicit export through
--revealand--file. -
#669
b821104Thanks @gulshngill! - Show the real subcommand help fornansen research perp screener --helpandnansen research perp leaderboard --help. Becauseperpis also a top-level trading command, the help lookup stopped at the trading command's subcommand list and fell back to printing the category listing — "Use: nansen research perp --help", the command that had just been run — so the parameters, credit cost and example were unreachable.nansen perp screener --helpnow resolves to the same help, with an example pointing at theresearchpath. Boolean options now accept--flag=falseand reject invalid or repeated values instead of silently falling back to the server default; value-taking options also accept the conventional--key=valuespelling, while valueless switches reject inline values instead of creating unusable stale flags. Invalidchangelog --sincevalues now return a structured error and a non-zero exit status.The stricter validation intentionally rejects invalid, previously undocumented inputs that only appeared to succeed while being ignored; relying on that quiet fallback was relying on a bug, so this is classified as a minor change rather than a major breaking release.
-
#682
3e172f2Thanks @Bruce039! -alerts updateno longer resends a PATCH through the retry loop after a transient failure, matchingalerts create -
#649
66152afThanks @kriss39! -research profiler compareno longer turns failed API requests into an empty comparison. When every request fails the command errors with the underlying code (for exampleUNAUTHORIZEDorRATE_LIMITED); when some fail the result carriesincomplete: true, anerrorslist, andnullfor the fields that could not be computed. Shared tokens are now matched on the token address when both wallets report one, falling back to the symbol when either side omits it, so two different contracts with the same symbol are no longer reported as shared. -
#674
ad178dbThanks @0xShadowX! - A repeated list option whose values are themselves comma-separated (--tags defi,nft --tags sports) is now flattened todefi, nft, sports. Previously the first value was kept as the literaldefi,nft, so the same list was read differently depending on whether it was passed once or as repeated flags. -
#652
d0433d4Thanks @Bruce039! - Resolve ENS names when the profiler chain isall. The profiler commands default--chaintoall, but the resolver only accepted explicit EVM chains, soresearch profiler labels --address vitalik.eth(and every other profiler subcommand exceptfirst-funder) failed withENS names can only be resolved on EVM chains, not allunless--chain ethereumwas passed. -
#654
0aad196Thanks @Bruce039! ---fieldsnow supports dotted paths.--fields data.results.addressselects that field at that position only (array elements do not add a segment), while a bare name such as--fields addresskeeps matching at any depth. Dotted paths were mentioned in the code but matched nothing, so--fields data.resultsreturned an empty object. -
#672
b10dc31Thanks @0xShadowX! ---filtersis validated as a JSON object before the request is sent. A value such as--filters '[]',--filters abcor a repeated--filtersflag used to be forwarded to the API as-is and only failed there with a 422; it now fails with anINVALID_PARAMSerror that shows the expected form. -
#660
42db750Thanks @Ahmett101! - Parse SSEdata:fields with or without the optional space after the colon so standards-compliant agent streams do not produce an empty response. -
#651
ab784a3Thanks @kriss39! - Respect the server'sRetry-Afterheader when retrying rate-limited (429) requests. The wait was capped at the local backoff ceiling (30s), so aRetry-After: 60led to a retry after 30s that could only hit the limiter again. The client now waits at least as long as the header asks, and if the server asks for more thanmaxRetryAfterMs(default 120s) it fails immediately with theretryAfterMsin the error details instead of retrying too early. ARetry-Afteron a 5xx response is still treated as advisory and capped at the backoff ceiling as before. -
#663
bc4ecc8Thanks @gulshngill! - Option values that spell a JSON keyword (--sort true,--search false,--label null) are now kept as the literal stringstrue/false/nullinstead of being converted to a boolean or null, so string options no longer crash or silently drop the value;--filters '{}'and--order-by '[...]'still parse as JSON, and--sortnow rejects a repeated or non-text value with--sort must be "field" or "field:direction". -
#671
8a4e98fThanks @0xShadowX! - Keep the body of a non-JSON error response (gateway HTML, plain text) in the error details instead of reportingbody: null, and apply the same retry policy to it as to a JSON error: a plain-text429is now retried, with itsRetry-Afterrespected, instead of failing on the first attempt. -
#676
0112fa1Thanks @0xShadowX! - Refuse to sign EVM approval, revoke, and Privy swap transactions when the quote carries no gas price, instead of defaulting to an unmineable 0.001 gwei fee that left the wallet's nonce stuck -
#681
c82492dThanks @kriss39! -wallet sendandtrade limit-order createreject an amount of zero, or one that truncates to zero base units at the token's precision, instead of broadcasting a transfer of nothing or creating a limit order withinputAmount: "0" -
#650
d4b4925Thanks @kriss39! -research token screener --searchnow honours--page. The search filter runs client-side, and previously every page returned the same first slice of matches; the candidate fetch is now widened to cover the requested page and the filtered list is sliced at the page offset. -
#661
fe5b294Thanks @gulshngill! - Recognise the API's full set of structured error codes. A 401unauthenticatedresponse once again showsNot logged in. Run: nansen login,insufficient_creditsgets its do-not-retry hint, and codes that previously leaked through as raw server strings now surface as CLI codes, including the newPLAN_UPGRADE_REQUIRED,GEO_BLOCKED,QUERY_TOO_LARGE,PAYLOAD_TOO_LARGE,METHOD_NOT_ALLOWED, andCONFLICT. Retry behaviour is unchanged: it stays keyed on the HTTP status. -
#679
5c8d22bThanks @0xShadowX! - Fail with an actionable error when a Solana RPC cannot return an SPL mint's decimals, instead of silently assuming 9 and building a transfer or limit order with a mis-scaled amount -
#675
938a011Thanks @kome12! - Reject malformed or negative profiler--delayand tokentop-tokens --limitvalues instead of partially parsing them. -
#646
3290e3cThanks @gulshngill! ---tableand--format csverror output now includes the errorcode, HTTPstatus, anddetailsinstead of only the message. CSV errors are emitted as a header row plus one record; table errors keep the leadingError:line and add onekey: valueline per field. -
#662
7fd923fThanks @gulshngill! - Sync thechainslist reported bynansen schema(and mirrored in--helpand the README) with the chains the Nansen API actually accepts. Dropsscrollandronin, which no endpoint serves any more, and adds the chains that were missing:algorand,aptos,arc,bitcoin,bitlayer,chiliz,citrea,gravity,hyperliquid,injective,mantra,near,robinhood,stacks,starknet,stellar,sui,ton,tron,viction. Not every chain is served by every endpoint; the API still validates--chainper endpoint. -
#664
d034ae1Thanks @gulshngill! -trade quoteandtrade executenow screen the signing wallet (and any distinct--to-walletdestination) against the compliance blocklist before requesting a quote or signing — the same fail-closed checkbridgeandperpalready run — so a flagged address, or a screening call that fails, aborts the command before anything is signed or broadcast. Both commands now require API access for this check; authenticate withnansen loginorNANSEN_API_KEYbefore trading. -
#653
337271dThanks @Bruce039! ---sortnow rejects a direction other thanasc/descand an empty field name with anINVALID_PARAMSerror. Previously--sort pnl_usd:sidewayswas uppercased and sent to the API asdirection: SIDEWAYS, which only failed later with an upstream 422. -
#648
0514c76Thanks @kriss39! - Validatetoken screener --searchandtoken who-bought-sold --buy-or-sellbefore the request is sent, so a JSON array/object or a repeated flag (--search '[]',--buy-or-sell '{}') and values outside theBUY/SELLenum produce an actionableINVALID_PARAMSerror instead of a raw.toLowerCase()/.toUpperCase()TypeError. -
#666
6539558Thanks @gulshngill! - Make every wallet subcommand discoverable from the places agents look first.nansen --helpnow listssend,forget-passwordandsecureon the wallet line (previously only seven of the nine were shown) and the full perp subcommand set (transfer,approve-builder-fee,orders,account,meta,screenerandleaderboardwere missing). It also stops describing the combined top-levelperpcommand as a deprecated analytics alias. README lists the same wallet set, andnansen schema walletnow documentsforget-passwordandsecurewith descriptions plus an example for every wallet subcommand. Help text, README, runtime command help and schema are pinned together by a new drift-guard test. -
#677
b91e108Thanks @0xShadowX! - Read a pretty-printed WalletConnectsign-typed-dataresult on the x402 payment path instead of failing after the user has already approved the payment in their wallet -
#673
05a2056Thanks @0xShadowX! -web search --num-resultsnow rejects a malformed value (5abc,2.5,abc, a repeated or valueless flag) withINVALID_PARAMS. Previously5abcwas silently truncated to 5,2.5to 2, and a non-numeric value fell back to the API default instead of reporting the mistake.
- #624
8bd2f00Thanks @gulshngill! - Addnansen research profiler counterparties-batch— top counterparties for up to 10 wallets in a single request. Takes--addresses "0xabc,0xdef"(comma-separated or a JSON array) or--file, validates the 10-address and 90-day limits client-side, and returns rows tagged with thewallet_addressthey belong to (results are not aggregated across wallets).--chaindefaults toall, which auto-detects the ecosystem; one ecosystem per request, as EVM and Solana addresses cannot be mixed.
-
#643
b459772Thanks @Codier! - Ignore failed and malformed OpenAPI responses when refreshing the credit-cost cache. A non-2xx response that still returned JSON replaced the cached cost map with an empty one and stamped it fresh, so credit estimates went missing for up to 24 hours and the next refresh was suppressed. -
#634
a5a3b27Thanks @Bruce039! - Avoid caching failed or malformed update-check responses as fresh results, so transient registry errors are retried instead of suppressing checks for 24 hours. -
#637
a0f889dThanks @gulshngill! - Fix the--chainallowlist onnansen research profiler counterparties-batch. It was built from the CLI's internal EVM chain list, which disagreed with the endpoint in both directions:scrollandroninwere accepted and always 422'd upstream, while every non-EVM chain the profiler serves (bitcoin,tron,sui,ton,near,injective,mantra,robinhood,arc,starknet) was rejected client-side. The allowlist is now the endpoint's ownProfilerChainenum, and--chain bscis accepted and sent asbnb. Addresses on a chain whose format the CLI cannot check are still required to be address-shaped, so a newline--filecannot post arbitrary lines as wallet addresses; TON accepts both friendly and raw (0:/-1:plus 64 hex) addresses. -
#645
dda318eThanks @gulshngill! - Declare theDELETE /api/v1/smart-alert/{alertId}route thealerts deletecommand already calls insrc/schema.json. This was the last route in the parity checker's schema-drift list; the sibling routes (list/create/update/toggle/account/web/agent) were declared in #549. -
#640
60961cfThanks @hulk-linus! - FixparseArgstreating an explicit empty-string option value (--flag "") as a boolean flag and leaking the""into positional arguments.nansen web fetch <url> --question ""now reports the blank-question error instead ofInvalid URL: "".Register
--all,--max,--gasless,--auto-slippage, and--unsafe-no-passwordas valueless flags. They are read only as booleans, so a following token such asnansen perp meta --allplus an asset name was parsed as their value and the switch went dead.Reject a blank
nansen mcp verify --url ""instead of falling back to the default Nansen endpoint, which reported the default URL as verified when the caller passed an unset shell variable.Reject a blank
--slippageor--max-auto-slippageonnansen trade quote. An empty string became0in the range check, satisfied the rule that--swap-mode exactOut --auto-slippageneeds an explicit cap, and was then dropped when the request was built, so the ERC-20 approval was scoped by a cap that never reached the server.Reject a blank
nansen web fetch --url ""instead of dropping it and fetching only the positional URLs. -
#644
14bbd9bThanks @hulk-linus! - Reject explicitly blank quote options, execute and limit-order wallet selectors, limit-order expiry and list options, wallet creation names and send options, and research chain/timeframe, days, buy-or-sell, and profiler batch/trace tuning options with an actionable error instead of selecting defaults. Preserve numeric zero slippage caps in programmatic quote requests. -
#542
055488aThanks @gulshngill! - Stop calling the removed points leaderboard API route. Bothpoints leaderboardandresearch points leaderboardnow return a structured unavailable error and exit with a failure status, without suggesting the other unavailable command as a replacement. -
#549
28714c6Thanks @gulshngill! - Declare the API routesalerts,account,webandagentalready call insrc/schema.json. The schema is what shell completions,--helpand docs tooling read, so eight routes the code requests were invisible to them (and to the API/MCP/CLI parity check). -
#647
2b84502Thanks @kome12! - Reject invalid profiler trace width values instead of returning an empty-looking trace. -
#642
b6c928fThanks @kome12! - Validatenansen alertsstring/array options (--chains,--token/--exclude-token,--subject/--counterparty/--caller/--contractand their--exclude-*variants,--events,--signature-hash,--token-sector/--exclude-token-sector, andalerts list --token-address/--chain) so JSON primitives (e.g.--chains true) produce actionableINVALID_PARAMSerrors instead of a rawTypeErrorcrash or being silently dropped/passed through into the alert payload. -
#630
7cb8bb2Thanks @kriss39! - Validate supported analytics--daysvalues as non-negative integers with a representable date range instead of truncating malformed inputs or forwardingNaN. -
#639
17e4f64Thanks @kome12! - Validate more CLI string options (profiler batch --include,perp screener --sectors-filter/--sm-label-filter/--trader-label-filter,prediction-market market-screener/event-screener --tags, and--fields) so JSON primitives produce actionableINVALID_PARAMSerrors instead of raw.split()/.trim()TypeErrors. -
#632
d9c7e6eThanks @Bruce039! - Reject malformed or valueless--dateinputs instead of silently falling back to the rolling--daysrange. -
#631
17cbed5Thanks @Bruce039! - Reject malformed and non-finite prediction-market screener numeric filters before they can be serialized asnullor silently ignored. -
#629
b802bcaThanks @kriss39! - Reject malformed, fractional, non-finite, repeated, or valuelessprofiler trace --depthinputs while preserving the existing 1-5 clamping behavior for valid integers. -
#633
901f63eThanks @Bruce039! - Validate web--queryand--questionoption types so JSON primitives produce actionable CLI errors instead of raw.trim()TypeErrors.
-
#621
6ece0a1Thanks @kome12! - Validate alerts list pagination flags before fetching alerts. -
#620
bf8f40fThanks @Radovenchyk! - Fixnansen agentthrowing a rawAbortErrorinstead of aNansenError(TIMEOUT)when the request timeout fires while reading the SSE response body (as opposed to during the initial connection). Both streaming and--jsonoutput modes now report a consistent timeout error regardless of which phase of the request the abort happened in. -
#618
1e08a15Thanks @Radovenchyk! - FixconsumeSSEStreamsilently dropping the final SSE event when the stream closes without a trailing blank line (e.g. afinishevent carryingconversation_id, or a trailingdeltachunk). -
#623
9ae1dc2Thanks @kome12! - Improve Solana raw-instruction bridge error handling for RPC failures and malformed instruction data. -
#622
d86aae9Thanks @kome12! - Tolerate small refunded native input amounts during bridge outcome verification. -
#617
d048c0fThanks @teyrebaz33! - Fix x402 auto-payment via WalletConnect signing a payment authorization from any connected EVM account instead of verifying the WalletConnect session is actually approved for the payment's chain.handleX402Paymentresolved its signer with its owncheckWalletConnection()helper and tookwallet.accounts[0]?.addresswith no chain filtering at all -- the same defect class fixed ingetWalletConnectAddressfornansen transfer/nansen trade execute(see the WalletConnect chain-scoped signing fix), just left unguarded here because this path never reused that helper. Because EVM addresses are identical across chains, a WalletConnect session approved only for, say, Base could be silently used to authorize an x402 payment on BNB Smart Chain or X Layer -- the other two EVM networks Nansen's x402 payments support.handleX402Paymentnow resolves its signer viagetWalletConnectAddress('evm', chainId), scoped to the exact chain of the selected payment requirement, and refuses to pay with a clear error when no WalletConnect session is approved for that chain. The now-unused, duplicatecheckWalletConnectionhelper was removed.
-
#604
9d541d7Thanks @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
c86af55Thanks @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
492b441Thanks @gulshngill! - Reject hard-linked.credentialsfiles in the wallet-password fallback write, so the credential write cannot chmod, truncate, or overwrite an unrelated file -
#611
959225cThanks @gulshngill! - Reportfrom_cachetelemetry from the API instance so it survives command handlers that rebuild their result, and pass it on thealerts list --tablepath, which previously never reported the field at all -
#609
288f566Thanks @gulshngill! - Fixfrom_cachetelemetry always reportingfalseon cache hits -
#586
b254240Thanks @Kewe63! - Tighten POSIX permissions when rewriting the fallback wallet credentials file and refuse non-regular credential paths. -
#615
9166884Thanks @teyrebaz33! - Fixnansen transfer/nansen trade executewith--wallet walletconnectusing 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 witheip155:, 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.getWalletConnectAddressnow accepts an optionalchainId, 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'ssendTokensViaWalletConnect, andnansen trade execute's quote-building, pre-execute wallet-match check, and immediate pre-signing check for its EVM WalletConnect swap path.
-
#588
0db1c74Thanks @Kewe63! - Prevent duplicate alert creation after ambiguous network failures and keep Smart Alert mutations out of the response cache. -
#595
1e3fadbThanks @devorun! - Fix--cachereshaping 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 everyArray.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
0cc4c18Thanks @ygd58! - Fixnansen alerts list --limit/--offsetsilently misbehaving on invalid or edge-case input.--limit 0and--offset 0were treated as "not set" (falsy check) and silently ignored instead of honored; a non-numeric value like--limit abcsilently returned zero results (Array.prototype.slicecoercesNaNto0) instead of erroring; and a negative--offsetwas silently accepted byslice(), 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 clearINVALID_PARAMSerror otherwise. -
#577
3c214a1Thanks @batuhankocyigit! - Fixnansen alerts create/updatesilently 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/maxflags) instead of rejecting bad input. These flags were converted with plainNumber(val), so a typo or garbage value (e.g.--usd-min abc) becameNaN, whichJSON.stringifysilently turns intonullin the request body — the alert would get created without the filter the user thought they'd set, with no error at any point.--*-min/--*-maxnow reject non-numeric input with a clearInvalid --<flag> "<value>": must be a numbererror; valid negative values (e.g.--netflow-1h-min -5000for a net-outflow filter) are unaffected. -
#605
9656d08Thanks @kome12! - Keep non-JSON 4xx responses from trade execute reusable instead of treating them as ambiguous broadcast failures. -
#602
9c72189Thanks @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
1450b66Thanks @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
b6d5bafThanks @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
8e674c2Thanks @devorun! - Telemetry now creates~/.nansenwith 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 withNANSEN_API_KEYinstead ofnansen login) it was left group- and world-readable. -
#594
95bdde1Thanks @Kewe63! - Reject invalid cache TTL values before constructing the API client. -
#593
dfc908aThanks @Kewe63! - Reject invalid retry counts before constructing the API client. -
#599
bdbdcb2Thanks @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.
-
#563
3b3e11bThanks @hulk-linus! - Emit privacy-preserving per-leg Hyperliquid attribution through the canonical trade-perps outcome events. -
#580
c5085c5Thanks @gulshngill! - Addnansen 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
8453355Thanks @kome12! - Security:nansen mcp verifyno longer sends a saved API key (fromnansen login/NANSEN_API_KEY/ config) to a custom--urlwithout 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-keyis unaffected.Note: verifying a custom
--urlwith a saved key now errors unless--send-api-keyis passed (previously it warned and proceeded). -
#557
5a73b43Thanks @gulshngill! - Add thenansen research address-premium-labelscommand. -
#555
4285d7fThanks @gulshngill! - Add thenansen research chain-rankcommand. -
#561
dd8035cThanks @gulshngill! - Add thenansen research historical-token-ohlcvcommand. -
#560
52f2f09Thanks @gulshngill! - Add thenansen research perp-pnl-summarycommand. -
#559
ed2d7a5Thanks @gulshngill! - Add thenansen research position-intelligencecommand. -
#558
e273152Thanks @gulshngill! - Add thenansen research smart-money-pnl-leaderboardcommand. -
#556
3c14359Thanks @gulshngill! - Add thenansen research token-sectorscommand. -
#562
0d0f5e6Thanks @gulshngill! - Add thenansen research transaction-with-token-transfer-lookupcommand. -
#581
8726a23Thanks @gulshngill! - Every command option innansen schemanow carries a type and a description (140 research andwallet sendoptions had neither), and theresearch pointsgroup is described.research token ohlcv --timeframedocuments its real default (1d), andwallet send --chain,research search --type, and the prediction-market--neg-riskfilters declare the values they accept, so--helpand shell completion offer them. Fixed--neg-risk trueon the prediction-market screeners, which was sent to the API asneg_risk: falsebecause the parsed boolean was compared against the string'true'.nansen mcp installandnansen mcp uninstalldeclare their positional client in the schema, andnansen completionscripts now complete it (claude-code,claude-desktop,cursor) in bash, zsh, and fish.
-
#575
927ffeaThanks @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 504UPSTREAM_TIMEOUTis 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/executePOST: 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
2ba5c15Thanks @teyrebaz33! - Fixnansen changelog --since <version>silently returning "No changelog entries found" for a version missing its patch number (e.g.--since 1.43instead of--since 1.43.0), even when matching entries exist. The comparison compared the missing component againstundefined, and>is alwaysfalseagainstundefinedin both directions, so a version that matched on major.minor always came out "less than" the since-value. A missing component is now treated as0, and a--sincevalue 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) betweennansen changelog --sinceand the update-notifier'sisNewercheck, which had the identical bug in its own separate parser.isNewercouldn'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
04932c7Thanks @memosr! - Refuse to re-execute a swap quote that has already been broadcast, mirroring the single-use guardnansen bridge executealready had.nansen trade executenow marks the quote as spent (executedAt) the instant a transaction is broadcast — before waiting for its receipt — so aRECEIPT_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
60bd2efThanks @ygd58! - Fix the x402 auto-payment fallback insrc/api.jsgenerating multiple payment authorizations for the same request after an ambiguous outcome (issue #583). After a signedPayment-Signaturewas transmitted,_x402Retrypreviously collapsed every non-ok response — a clean rejection, a 5xx, an unreadable body — and every transport failure into a singlenull, and callers treated anynullas "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 benullwas indistinguishable from a rejection, risking a second payment for an already-settled call._x402Retrynow returns a dedicatedX402_PAYMENT_REJECTEDsentinel only for a provably clean rejection (a non-5xx status with a readable body), and throwsNansenErrorwith the newPAYMENT_AMBIGUOUScode 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 ofnull, and re-throw aPAYMENT_AMBIGUOUSerror immediately instead of silently moving on to the next provider. -
#524
3e8dcc2Thanks @dolmaciabdullah-byte! - Use BigInt for EVM balance incheckX402Balanceto avoid precision loss on 18-decimal tokens (BSC stablecoins):parseInt(hex, 16)loses integer precision once the raw wei value exceedsNumber.MAX_SAFE_INTEGER(~9.0e15 wei, i.e. ~0.009 tokens at 18 decimals), skewing the low-balance warning. -
#568
9a45fc4Thanks @Kewe63! - Reject non-finite limit-order trigger prices and expiry values before wallet or API activity. -
#567
c0fe57bThanks @Kewe63! - Keepresearch perpanalytics-only instead of routing trading subcommands through the top-level perp dispatcher. -
#558
002921eThanks @gulshngill! - Reject non-integer or non-positive--limitvalues with an actionable error instead of forwarding them to the API.
-
#526
a7ab05cThanks @dolmaciabdullah-byte! - FixformatValuedisplaying1000.00Kinstead of1.00Mwhen a value like 999999.995 rounds up at the K/M boundary. -
#548
000d01aThanks @Sertug17! - FixparseAmountsilently producing wrong values for negative decimal inputs. Negative amounts are now rejected with a clear error. -
#551
092535aThanks @kome12! - HardenparseAmountinput 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 returning0. -
#433
977fbc5Thanks @aikido-autofix! - Validate the wallet name before the Privy pre-read inwallet deleteandwallet send, routing both reads throughgetWalletFile()so the path stays confined to the wallets directory. -
#545
642eb20Thanks @kome12! - Update Noble crypto dependencies to the patched 2.4.x releases.
- #539
2ba6c40Thanks @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.
-
#535
863ef23Thanks @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
7492bbeThanks @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.
-
#508
3fc6e6bThanks @gulshngill! - Addnansen mcp verifyto verify the hosted Nansen MCP setup with an authenticated data-path check. -
#487
bb3f33eThanks @gulshngill! - Addnansen 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,.bakbackup on install and uninstall, refuses unparseable configs), use the API key fromnansen login/NANSEN_API_KEY, never print the key, and support--dry-run.
-
#536
f5e48dfThanks @kome12! -bridge quotenow 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
a96418dThanks @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
--amountwas 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-unitamounts already were, so these withdrawals execute. -
#530
4312b50Thanks @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
2d630d5Thanks @kome12! - Fixnansen mcp verifyrouting after merging MCP install commands. -
#538
853c48aThanks @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
e23af5cThanks @gulshngill! - Credential hygiene:nansen loginverification 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
45b8584Thanks @gulshngill! - Docs: stop pointing at the retired Cursor install deep link, pin themcp-remotebridge to the versionmcp installwrites, and correct the header-formatting note (whitespace after the colon is trimmed; the key belongs inenv, not in the argument list). -
#531
9bb44a7Thanks @crazywriter1! - Honor the original HTTP method on x402 paid retries so GET/DELETE/PATCH requests are not resent as POST after payment.
-
#527
02efb6dThanks @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-modeis now validated againstexactIn/exactOutat 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: falseand 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
55eb953Thanks @kome12! - Fixtrade executecrashing 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.
-
#512
ba42a9cThanks @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 exactOutnow also requires--max-inputon Solana (previously EVM-only), so the maximum spend is bounded by a value you supply rather than one taken from the quote itself. -
#514
1bc7337Thanks @kome12! -trade executeandtrade limit-orderon 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
820bf05Thanks @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-outcomeflag; 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.
-
#519
55ab7dbThanks @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
977e326Thanks @aikido-autofix! - Fix potential path traversal in safeQuotesPath by rejecting absolute relative paths (Windows cross-drive escape). -
#497
223a9d5Thanks @crazywriter1! - Reject--oidvalues above 2^53-1 onperp cancel: large Hyperliquid uint64 order IDs would be silently rounded by JS Number, potentially cancelling the wrong order.
- #516
48722efThanks @kome12! - Fix cross-chain bridges into native SOL being refused at execute time. The quote/intent binding compared the wrapped-SOL mint (how--to SOLresolves) 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.
-
#509
430c300Thanks @kome12! -trade executenow 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.
-
#498
a964dd1Thanks @crazywriter1! - Usependingnonce block tag for EVM sends: back-to-back transfers no longer risk reusing the same nonce when mempool transactions are queued. -
#493
bc89fefThanks @crazywriter1! - Validate--slippage-bpsonlimit-order create: values outside 0-10000 now fail with a clear error before any auth/API call.
- #495
3306897Thanks @kome12! - Add EVM swap-outcome verification totrade 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.
-
#495
e8cf217Thanks @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
de0bcc5Thanks @gulshngill! - Fixprofiler labels: call/api/v1/profiler/address/labelswith its v1 request body — the beta endpoint previously used was removed from the Nansen API.profiler batch --include labelsnow returns the label array itself instead of the raw{pagination, data}envelope. -
#506
f407edbThanks @gulshngill! - Add a canonical MCP setup section to the README — endpointhttps://mcp.nansen.ai/ra/mcp,NANSEN-API-KEYauth, 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 bareapp.nansen.ai/api. -
#500
9ccf8a2Thanks @gulshngill! - Document global pagination options innansen schema.
-
#486
b752d81Thanks @gulshngill! - Addnansen auth statusandnansen doctor.auth statusis 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.doctorruns health checks over the whole setup — Node version, config file validity and permissions, wallet storage and password hygiene (flags the insecure.credentialsfile), 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).--jsonreturns machine-readable checks. -
#494
67027e6Thanks @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-inputin base units of the sell token. The quote persists thatmaxInputAmount, 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 clearMAX_INPUT_EXCEEDEDerror 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.
- #494
54b9d41Thanks @kome12! - Fix exactOut--max-inputso 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.
-
#481
ccaa40bThanks @kome12! - Addresearch profiler first-fundercommand 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
b49c758Thanks @MarcLlopart! -nansen perp orderandperp closenow print the Hyperliquid order id (oid) and fill (size @ avg price) returned by the exchange, plus a ready-to-runnansen perp cancelcommand 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.
-
#483
d0d10a2Thanks @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
bc5f774Thanks @kome12! - Write the cost-map and update-check cache files atomically (temp file + rename) so concurrentnansenprocesses can no longer observe an empty or truncated cache. -
#465
4105193Thanks @dobbydobap! - Fixnansen quote --help,nansen trade quote --help, andnansen execute --helpto print the trade usage and exit with code 0 instead of erroring with exit code 1. -
#485
c9aaf58Thanks @MarcLlopart! -nansen perp order/perp closenow emit an anonymousperp_order_completedtelemetry event after the Hyperliquid/exchangeresponse 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 existingDO_NOT_TRACK/NANSEN_NO_TELEMETRYopt-out; order rejections remain covered bycli_command_failed. -
#478
758ce13Thanks @boleklebovski! - Document the missingtrade quoteandtrade executeoptions insrc/schema.json:--swap-mode,--slippage,--auto-slippage,--max-auto-slippage,--quote,--quote-indexand--no-simulate. These options are already implemented and documented for humans, but were absent from the machine-readable schema. -
#488
f653b37Thanks @gulshngill! - Warn on logout whenNANSEN_API_KEYremains active in the environment.
- #479
e2590edThanks @gulshngill! - Surface richer API response metadata: theX-Nansen-Credits-Costheader now drives credit reporting (a conciseCredits: N (this call)stderr line after each data command, falling back to the cached spec estimate when the header is absent),requestIdis hoisted to the top level of the JSON error envelope (includingnansen agentfailures, which previously dropped it), and error codes now come from the API's stablecodefield 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.
-
#467
54386c0Thanks @kome12! - Output shape change: every command failure now serializes through the same error envelope —{success: false, error, code, status, details}. Previously aCommandErrorprinted its structured payload at the top level instead, so errors fromtrade,limit-orderand 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 readdetailsinstead of the root object. The newperpandbridgecommands raiseCommandErrorthroughout, 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 csvor--stream, still gets the envelope — so nothing consuming the CLI programmatically sees a different shape.
-
#467
8ab8bb4Thanks @kome12! -bridge executenow 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
--walletor 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
44805e2Thanks @kome12! -nansen schemanow describes thebridgecommand group — its three subcommands, their options, and the supported routes — so agents driving the CLI off the schema can discover it.The mutating
perpsubcommands (order,cancel,close,leverage,transfer,approve-builder-fee) now declaresubmitsTo: "https://api.hyperliquid.xyz/exchange"in place of anendpoint, which is where they actually send a signed action, alongside anapiEndpointslist of the Nansen routes each one reads for compliance screening, market metadata and builder-fee status. Read-only subcommands keep theirendpointunchanged. -
#467
7185359Thanks @kome12! -nansen bridgesupportsbase -> hyperliquidfor deposits, andhyperliquid -> base,hyperliquid -> ethereum,hyperliquid -> arbitrumfor 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
19738ddThanks @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 affectstrade executeandbridge execute, which share the signer.bridge executealso stops discarding the fee fields the bridge quote provides. It previously overwrote them with a bareeth_gasPricereading, 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
f649eeaThanks @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.packboutput byte-for-byte (insertion-ordered maps, smallest-width ints, utf-8 strings), so an action'sconnectionIdhash matches the known-good path. actionHash+l1Eip712reproduce the phantom-agent EIP-712 payload (Exchange domain, mainnetsource: "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. approveBuilderFeeandusdClassTransferuser-signed payload builders.
Pinned against the live prepare endpoints with golden-vector tests that assert both the built action and its
connectionIdmatch byte-for-byte. - msgpack encoder that reproduces the reference
-
#467
3bd3909Thanks @kome12! - Addsrc/hl-client.js, the single direct-to-Hyperliquid submission path:submitExchange()POSTs a signed action straight toapi.hyperliquid.xyz/exchangefrom 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 inresponse.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 viaNANSEN_HL_API_URL(for testnet / tests). -
#467
b5d6946Thanks @kome12! - Harden perp, swap, and bridge command safety:perp order/closenow reject an invalid--sideinstead of silently opening the opposite direction, andperp leveragerejects an invalid--margin-typeinstead 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 quotevalidates--quote-index,--slippage, and--max-auto-slippage, rejecting out-of-range values (e.g. a percent-vs-decimal slippage mix-up).bridge quotenow validates--slippageclient-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 howperpvalidates--slippage).perp order/closewarn before signing when--size(or--pricefororder) is finer than the asset's Hyperliquid precision, which the exchange silently rounds.perp order/closenow 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 listno 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 tobridge execute). bridge executenow refuses a quote that has already been executed, preventing an accidental double-bridge on retry.bridge quoteaccepts human amounts via--amount-unit token|usd(default stays base units), resolving token decimals per chain so the same5isn'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 metasupports--alland--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-orderrejects 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
b577954Thanks @kome12! -perpandbridgeno longer serve any API response from the--cachestore, andbridge executeno longer retries its submission.- Compliance screening is always a live check. Every mutating command re-screens the signing wallet immediately before signing; with
--cachethat verdict could previously come from a cache written up to five minutes earlier, which is exactly the window the check exists to close. bridge executesetsretry: false. It proxies to Relay's/authorizeand 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 —closesizes its order from the positions read, and asset ids come frommeta.
bridge executealso refuses to sign a step whose EIP-712 type definition is missing or whoseprimaryTypematches 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. - Compliance screening is always a live check. Every mutating command re-screens the signing wallet immediately before signing; with
-
#467
4c1d3aaThanks @kome12! - Close three residual safety gaps on the perp/bridge signing paths:perp ordernow rejects a take-profit or stop-loss price that rounds to zero at the asset's precision, instead of encoding atriggerPxof0and 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 offrom, so the nonce must come from that account — and this stays correct even if a quote omitsfrom.
-
#469
85b1934Thanks @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_METAsymbol, and the client exposeslastResponseMeta. Both are additive: the JSON each command prints is unchanged. -
#470
8159300Thanks @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 theRESPONSE_METAsymbol.Absent on deployments that do not send the header yet, in which case the field is simply omitted.
-
#459
37e6725Thanks @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
aac4bbeThanks @gulshngill! - Add trader_type, sectors_filter, sm_label_filter, and trader_label_filter filters tonansen 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)
- #457
8149564Thanks @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'sextra.assetTransferMethod—eip3009keeps the existing gasless flow (U, USD1), whilepermit2-exact(USDT, USDC on BSC) signs a Permit2PermitWitnessTransferFromagainst the spender contract advertised in the 402. Permit2 entries are skipped with an actionable message when the wallet hasn't made the one-timeapprove(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.
- #455
875fabbThanks @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 abscentry in the shared RPC registry with aNANSEN_BSC_RPCoverride.
- #451
73600d9Thanks @kome12! - Addnansen research profiler dex-tradescommand for DEX trade history
- #443
0ee84dbThanks @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.
- #437
5ec7bd3Thanks @gulshngill! - Addnansen researchcommand 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.
-
#440
701dad4Thanks @kome12! - Fixresearch historical-token-screenerschema to mark--to-dateas required (matching CLI and API behavior) -
#442
6edbb68Thanks @kome12! -research historical-token-flow-summarynow errors immediately when--pageor--limitare passed (the endpoint returns a single aggregated row and does not support pagination).research historical-smart-money-balancesnow errors when--sortor--order-byare passed (the endpoint does not support ordering). Previously both flags were silently dropped.
- #431
c2c033bThanks @MarcLlopart! - Pass backend quoteId in execute requests for BI correlation
-
#411
26cd863Thanks @gulshngill! - Add thenansen-limit-ordersskill. The skill teaches agents to use the nativenansen trade limit-order create|list|cancel|updatecommands for Solana price-triggered orders, and documents the alert-based settlement-signal fallback (common-token-transfersmart alert on the settlement wallet) for chains without native limit-order support. Builds on thetrade limit-ordercommand surface added by #328. -
#429
511e795Thanks @gulshngill! - Improve discovery ofnansen tradein package metadata, help output, install tips, and agent-facing docs.
- #422
10da2f0Thanks @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 402acceptslist — no client-side allowlist, sincesrc/x402-evm.jsalready readsextra.name,extra.version, andassetgenerically. NewNANSEN_XLAYER_RPCenv var overrides the default X Layer RPC, andcheckX402Balance()now picks the right token + RPC based on the requirement'snetworkfield.
-
#422
dc9d1c1Thanks @gulshngill! - Document MPP (Tempo) as a third paid-access rail alongside API key and x402. Adds anansen-mpp-paymentskill, a README section explaining when to reach for the separatetempoCLI, and updates the no-API-key 402 error to mention tempo as a third option. -
#422
93e6a6dThanks @gulshngill! - Fix x402 low-balance warning to use the actual stablecoin symbol (USDC or USDT0) returned bycheckX402Balance()instead of hardcoding "USDC". -
#422
8f9397fThanks @gulshngill! - Fix x402 payment header decoding and WalletConnect payment payload encoding to use UTF-8 instead of Latin-1. Previously thePayment-Requiredheader was decoded withatob(), which corrupted multi-byte UTF-8 chars in fields likeextra.name = 'USD₮0'. The corrupted name then signed the wrong EIP-712 domain and the server rejected withinvalid_exact_evm_signature. X Layer USDT0 payments now sign correctly; Base USDC was unaffected because'USD Coin'is pure ASCII.
- #423
d10aa57Thanks @imhta! - Add Relay aggregator support for Base↔Solana cross-chain swaps. Users now see Relay quotes alongside Li.Fi innansen trade quote --to-chain ..., can execute them throughtrade execute, and optionally use Relay's gasless path with--gasless(local/Privy wallets only — not WalletConnect).trade bridge-statusauto-detects which aggregator produced a tx (via a local tx record) and polls the right backend.
-
#417
ae6079fThanks @0xlaveen! - Addtrade limit-ordercommands (create, list, cancel, update) for Jupiter Limit Order V2 on Solana. Supports local, Privy, and WalletConnect wallets. -
#413
94bd349Thanks @jake-kennis! - Addtop-tokenssubcommand to discover top-scoring tokens by Nansen Score. Calls the public endpoint (/api/v1/nansen-score/top-tokens) with optional--market-capfilter.
- #408
d1e9787Thanks @0xlaveen! - Add cross-chain notes to trade help text and document --to-chain constraints in schema.json.
- #403
fe53dbeThanks @marius-reed! - Add prediction market filtering (order_by, volume/liquidity/OI/trader/price/date filters, neg_risk, tags) and address-summary endpoint
- #402
cfd94ceThanks @TimNooren! - Enforce USDC or native token on one side of every swap
- #392
025993dThanks @TimNooren! - Add gas balance validation: rejects trades when the wallet lacks sufficient native token for gas fees.
- #380
12e4e25Thanks @TimNooren! - Add--amount-unit percentto trade commands, allowing trades as a percentage of wallet balance (e.g.--amount 100 --amount-unit percentto sell all)
-
#382
d9c87efThanks @kome12! - fix: defaultprofiler balancechain to'all'instead of'ethereum'Previously,
nansen profiler balance --address <addr>without--chaindefaulted toethereum, 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.
- #367
9fea10aThanks @kome12! - add --premium-labels flag to tgm/holders, tgm/pnl-leaderboard, tgm/perp-pnl-leaderboard, and perp-leaderboard endpoints
- #363
6ae402eThanks @TimNooren! - Add--amount-unit usdto trade commands — specify swap amounts in USD
-
#374
0f14803Thanks @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
f358fffThanks @kome12! - fix(token): replace dead--daysparam with working--timeframefortoken flow-intelligenceThe
--daysoption was accepted but never sent to the API, resulting in always fetching1ddata. This replaces it with--timeframe(enum:1h | 6h | 12h | 1d | 7d, default1d) which maps correctly to the API parameter.
-
#333
c8fe79cThanks @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 tokennansen trade execute --quote <id>Bridge status can be checked with
nansen trade bridge-status.
- #365
56335afThanks @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).
-
#361
ff22da3Thanks @TimNooren! - fix(alerts): error when --webhook-secret is passed without --webhookPreviously, 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
70ee712Thanks @TimNooren! - Add pre-quote trade input validation: rejects same-token swaps, invalid address formats, and non-positive amounts before any network call.
-
#341
4b60056Thanks @gulshngill! - Add--webhook <url>and--webhook-secret <secret>flags toalerts createandalerts update.Allows alerts to be delivered to any HTTP/HTTPS endpoint via POST, alongside the existing
--telegram,--slack, and--discordchannels. The optional--webhook-secretenables HMAC payload signing for verification.
-
#344
3dc09ccThanks @0xlaveen! - Add nansen-agent-guide skill — routing guide for when to usenansen agentvs direct CLI data commands -
#347
a243c7aThanks @kome12! - Add --buy-or-sell option totoken who-bought-soldcommand — allows filtering by buy or sell side (BUY | SELL, defaults to BUY)
-
#336
c3b1fbdThanks @kome12! - Add --label option totoken flowscommand to filter by holder segment (top_100_holders, smart_money, public_figure, whale, exchange). -
#334
83244c6Thanks @kome12! - Add--include-stablecoinsflag totoken screenercommand. Pass--include-stablecoins falseto exclude stablecoins from screener results (API default istrue). Supports combined usage with--smart-money. -
#339
27ebcfcThanks @TimNooren! - Add --amount-unit token flag to trade quote for human-readable amounts
- #315
908fa0cThanks @TimNooren! - Addnansen agentcommand for the Nansen AI research agent with fast/expert modes, SSE streaming, conversation continuation, and JSON output.
-
#326
1532ba4Thanks @TimNooren! - Show API credit cost in research subcommand help text (fetched from OpenAPI spec, cached 24h). -
#330
a6b9b8fThanks @0xlaveen! - Suppress misleading PASSWORD_REQUIRED error when--provider privyis 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
f047833Thanks @TimNooren! - Limit deprecation warnings and update notices to help output only, keeping stdout/stderr clean for programmatic usage. -
#332
e9b6de1Thanks @0xlaveen! - docs: add trading examples and Privy wallet setup to README
- #302
3f0a5abThanks @arein! - Add post-install onboarding that interactively offers to install the Nansen AI coding skill and run a test query afternpm install -g nansen-cli. Non-interactive environments (CI, piped stdin) receive a one-liner tip and are never blocked.
- #313
bb4d9e4Thanks @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.
- #306
f685eb8Thanks @0xlaveen! - Rename 30 skills for clarity and clawhub slug uniqueness. Abbreviations expanded (pm→polymarket,smprefix 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.).
-
#308
569d7d4Thanks @kome12! - fix: include src subdirectories in npm packageThe
filesfield in package.json usedsrc/*.jswhich only matched files directly insrc/, causingsrc/commands/to be missing from the 1.18.0 publish. Changed tosrc/**/*.jsto include all subdirectories recursively, and added!src/__tests__/**to exclude test files from the package.
-
#265
c3de691Thanks @TimNooren! - Addnansen alertscommand for managing smart alerts (list, create, update, toggle, delete).Supports three alert types:
sm-token-flows,common-token-transfer, andsmart-contract-call. Named flags (--inflow-1h-min,--chains,--telegram, etc.) let you build alerts without raw JSON; a--dataescape hatch is available for full config overrides.Also adds a
nansen-alertsskill for agent integration. -
#295
3ddcbdeThanks @kome12! - feat: addnansen web searchandnansen web fetchcommands (ECINT-6393)nansen web search <query> [query...]— search the web for one or more queries in parallel via/api/v1/search/web-searchnansen web fetch <url> [url...] --question <q>— fetch and analyze URL content with AI via/api/v1/search/web-fetch
-
#293
bcd95a8Thanks @TimNooren! - Add default values for all required alert data fields to match backend schema -
#265
c3de691Thanks @TimNooren! - Fixalerts listfiltering (--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
cda6796Thanks @kome12! - fix: add missing openclaw metadata to 19 skills -
#294
8a1cc7bThanks @yodablocks! - fix: include skills/ directory in published npm package
-
#279
174a3d6Thanks @kome12! - Addnansen accountcommand to verify API key and check credit balanceUsers can now run
nansen accountto 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/accountendpoint (ECINT-6365). -
#234
10a5cedThanks @kome12! - Reduced schema.json to a minimal format (~66% smaller).
-
#272
50213c1Thanks @TimNooren! - fix: show human-readable error when trade fails due to insufficient ETHWhen 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."
-
#249
0c17437Thanks @0xlaveen! - Addpmto top-level COMMAND_ALIASES sonansen pm <subcommand>works (previously onlynansen research pm <subcommand>resolved the alias) -
#244
6427a9fThanks @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.
- #196
0c286c2Thanks @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.
-
#216
5b88241Thanks @TimNooren! - Unified wallet abstraction: Privy server wallets are first-class citizens.wallet create --provider privycreates 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
-
#231
c3968daThanks @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.credentialsfile 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.--humanflag 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
passwordHashon last wallet delete, verify password before keychain writes, exit non-zero when keychain migration fails, source-aware error messages. - New skill:
nansen-wallet-migrationfor migrating from old~/.nansen/.envstorage to keychain.
- New
- #225
051e4a3Thanks @TimNooren! - Remove "recommended, lower fees" label from Base network in wallet create output
- #107
5877c06Thanks @marius-reed! - Add 11 prediction market (Polymarket) endpoints undernansen research pm. Includes OHLCV, orderbook, top holders, trades, screeners, PnL, position detail, and categories. Supports--market-id,--address,--sort-by,--query,--statusflags with pagination, sorting, and table output.
- #207
73ca500Thanks @TimNooren! - Add --unsafe-no-password flag to wallet create for agent-friendly passwordless wallets.
-
#212
726c29dThanks @0xlaveen! - Clarify empty input handling in parseAddressList with explicit early return -
#218
8c4dd71Thanks @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
a6dc1edThanks @0xlaveen! - fix: prevent --help from executing destructive commands (logout, schema, cache)
- #205
dba24aaThanks @TimNooren! - Add hot wallet and password handling warnings to wallet create output
-
#194
89225f5Thanks @TimNooren! - fix: --help on trade subcommands and wallet subcommands now shows full help identical to the no-args case -
#199
9ae981eThanks @TimNooren! - fix: replace misleadingwalletconnect connectcommand reference in x402 payment error with actionable guidance mentioning both local wallet (nansen wallet create) and external WalletConnect CLI options
- #186
feecc50Thanks @TimNooren! - Trade commands output to stdout instead of stderr; wallet send prints human-readable text instead of JSON
-
#166
c1034dbThanks @0xlaveen! - fix: pass --page parameter correctly in smart-money, profiler, token, perp, and points commands -
#137
1214767Thanks @0xlaveen! - Add missing sort/filters options to profiler schema and fix pnl sort/filters forwarding
-
#133
4cbeb65Thanks @0xlaveen! - fix: correct profiler pagination parameter fromrecordsPerPagetoper_page; remove unsupported pagination from pnl-summary; add --limit to labels, historical-balances, counterparties schema -
#164
ec6ab78Thanks @DMagowan! - fix: correct--dateoption marked asrequired: truewhen it is optionalThe schema incorrectly marked
--dateasrequired: truefor three commands:research token flowsresearch token who-bought-soldresearch profiler transactions
All three use
parseDateOptionwith adaysfallback, so--dateis 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
4dbe181Thanks @DMagowan! - fix: surface wallet prerequisite intrade quotehelp text and schemanansen trade quoterequires 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 aprerequisitesfield to the schema so agents can discover this requirement before running the command. -
#165
92f37eaThanks @0xlaveen! - Fix trading docs and config to reflect actual supported chains (Base and Solana only)
- #125
5a5a80aThanks @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 tonansen --helpoutput.
-
#122
9a1ada8Thanks @TimNooren! -nansen research <unknown>andnansen trade <unknown>now exit with code 1 and return{"success":false,...}instead of silently exiting 0. -
#138
c61881fThanks @TimNooren! - Fixnansen login --helpto show usage instead of erroring. Previously,--helpwas 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-deprecatednansen research token screenerpath. -
#129
eeabf89Thanks @araa47! - Fixtoken ohlcvsending unsupported pagination/limit params that caused 422 errors -
#139
e86dc68Thanks @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
eeabf89Thanks @araa47! - Fixtrade quotecrash when no wallet exists — now shows actionable error instead of uncaught exception -
#126
f3b87e7Thanks @araa47! - Remove root SKILL.md sonpx skills add nansen-ai/nansen-clicorrectly discovers all 7 skills inskills/instead of treating the repo as a single skill.
- #118
0bd4c3cThanks @TimNooren! - Show warning when trade quote price impact exceeds 5%, and show pin command to avoid fallback to worse quotes
-
#116
7a2b729Thanks @TimNooren! - Fix usage examples fornansen trade quoteto show correct command name instead of deprecatednansen quote -
#114
37d8c0bThanks @TimNooren! - Show API key URL in non-interactive login error message -
#117
55ad922Thanks @TimNooren! - Add --wallet and WalletConnect documentation tonansen trade helpoutput
- #110
82aa780Thanks @TimNooren! - Fixnansen changelogalways showing "CHANGELOG.md not found". Added afilesfield topackage.jsonto explicitly bundleCHANGELOG.mdwith the published package. Also excludessrc/__tests__/from the package, reducing package size from ~537 kB to ~269 kB.
-
#98
2f3f556Thanks @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 USDCinstead of raw contract addresses. -
#32
08a8d21Thanks @arein! - Add WalletConnect support for trading, transfers, and x402 auto-payment (EVM only)
-
#99
9144cbaThanks @Codier! - Show clear error when--amountcontains a decimal (e.g.0.005) instead of base units (lamports, wei). Detected client-side before hitting the API. -
#100
19559bfThanks @Codier! - Fixnansen trade helpreturning blank output. Now prints subcommands, usage, and examples. Also fixeserrorOutputReferenceError inbuildCommandsscope (affectedtradeandchangelogcommands). -
#93
342c91fThanks @Codier! - Warn when--fromis a wrapped native token (WETH/WBNB) or native sentinel, so AI agents can correct the token before execution fails
-
#56
d10998aThanks @askeluv! - Add CHANGELOG.md,nansen changelogcommand, and post-update "what's new" notice- Added CHANGELOG.md following Keep a Changelog format with history back to v1.5.0
- Added
nansen changelogcommand with--since <version>filtering - Added one-time upgrade notice on first run after version update (prints to stderr)
-
#77
46e4660Thanks @0xlaveen! - Add token-ohlcv endpoint for OHLCV candle data -
#75
287937eThanks @TimNooren! - Restructure CLI into research/trade/wallet namespaces- Commands reorganized:
smart-money,profiler,token,portfolionow live undernansen research - New
nansen tradenamespace forquoteandexecute - New
nansen walletnamespace for wallet management - Old top-level commands still work with deprecation warnings
- Commands reorganized:
-
#61
9af0192Thanks @askeluv! - Add ENS name resolution for profiler commands. Use.ethnames directly in--addressflags — 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, and this project adheres to Semantic Versioning.
- Trading commands —
quoteandexecutefor 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-runflag forwallet send- x402 low balance warning
- AI Agent Access setup docs and improved onboarding flow
- Solana execute crash with OKX quotes
- x402 auto-pay retry path (3 reference errors)
- Gas estimation — use API
quote.gasas 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
- Pricing clarity — from $0.01/call, min $0.05 balance
- Consolidated crypto primitives into shared module
token indicatorsendpointprofiler search— general entity search command--x402-payment-signatureflag for pre-signed payment headersX-Client-TypeandX-Client-Versiontracking headers on all API requests
- Error JSON now outputs to stdout (not stderr) for consistent agent parsing
- Config loading — environment variables correctly override file config
- Allow API requests without API key when using x402 payment flow
Baseline version. Changes above are relative to this release.