- Critical: every authenticated API call was rejected by the gateway. The CLI's underlying
@cryptohopper/sdkv0.4.0-alpha.1 sentAuthorization: Bearer <token>on every request, which the AWS API Gateway in front ofapi.cryptohopper.com/v1/*rejects with405 Missing Authentication Token. The Public API v1 actually uses anaccess-token: <token>header — confirmed via the official API documentation and the legacy iOS/Android SDKs. Picks up the fix from@cryptohopper/sdk@0.4.0-alpha.2. (#9) cryptohopper upgradewould silently refuse the upgrade pastalpha.9.compareVersionsfell through toString#localeCompareon the prerelease tail, so"alpha.10"sorted before"alpha.2". The moment we shipped anyalpha.10+release, every user on an earlier alpha would have been told "✓ up to date" and stayed stuck. Replaced with a SemVer-2.0.0 §11 prerelease comparator (numeric identifiers compared numerically, non-numeric lexically, numeric always lower-precedence than non-numeric). (#7)cryptohopper upgradecould miss the latest version after a hotfix on an older line.fetchLatestReleasetrusted GitHub'screated_atorder, which is creation-date descending. After a hotfix release on an older minor (e.g.0.6.1shipped after0.7.0-alpha.1), the index-0 release was no longer the highest version. Now sorts the filteredcli-v*list by the corrected comparator and returns the actual top. (#7)- OAuth browser-flow: state-mismatch showed "✓ Logged in" to the browser anyway. State validation ran after the local HTTP listener had already responded with the success page. On a CSRF mismatch the browser saw "✓ Logged in" while the terminal aborted with
state mismatch— contradictory, and on a real attack the attacker saw a success page they shouldn't see. State is now validated inside the listener handler before writing the response; mismatches return 400 with an error page. (#8) - OAuth token exchange could hang forever on a stalled
/oauth2/token. The 5-minuteDEFAULT_TIMEOUT_MSonly coveredlistenForCallback— once the callback arrived, that timer cleared and the subsequentfetchhad no deadline. AddsTOKEN_EXCHANGE_TIMEOUT_MS = 30_000and wraps both the request and the body-read in a singleAbortControllerso the whole exchange has a bounded total deadline. (#8)
No CLI surface change. Same flags, same JSON output, same exit codes. The only thing that changes is what the underlying SDK sends on the wire (auth-fix), how the OAuth flow validates state (now correctly), and what cryptohopper upgrade decides about which release is newest (now correct on prereleases past alpha.9 and after hotfixes).
- npm:
npm install -g @cryptohopper/cli@latest(or@0.6.0-alpha.2explicitly). - Standalone binary:
cryptohopper upgrade(or download from GitHub Releases).
If you ran cryptohopper login on 0.6.0-alpha.1 and your saved token at ~/.cryptohopper/config.json worked back then somehow (it shouldn't have — every authenticated call returned 405), no action needed. The token itself is still valid; only the header carrying it changes.
cryptohopper strategy list(aliasls) — list all your saved trading strategies in a table.cryptohopper strategy get <id>— pretty-print a strategy's full config as JSON.cryptohopper exchange list(aliasls) — list all supported exchanges. Public endpoint, no auth needed.cryptohopper exchange markets <exchange>— list every trading pair available on an exchange. Public.
All four commands accept --json like the rest of the CLI and follow the same exit-code contract.
- Critical: destructive commands bypassed the
--yesconfirmation gate when--jsonwas passed.hoppers panic,template load, andtemplate deleteall usedif (!opts.yes && !json)to decide whether to print the confirmation warning, which caused them to execute the destructive action when--jsonwas passed without--yes. The--yesgate now always applies; in--jsonmode the refusal is emitted as JSON ({ "ok": false, "error": { "code": "CONFIRMATION_REQUIRED", "message": ... } }) to stderr with exit code 1. - OAuth token-exchange error message was empty on empty HTTP bodies. The fallback chain used
??ontext.slice(0, 200), which always returns a string — meaning theHTTP <status>tail was unreachable, and empty error bodies producedToken exchange failed:with nothing useful. Switched to||so empty bodies fall through to the status code.
If you have scripts that relied on --json silently bypassing confirmation on hoppers panic / template load / template delete, they will now fail with a CONFIRMATION_REQUIRED error and exit code 1. Add --yes to restore the prior behaviour — but note that prior behaviour was unintended and dangerous.
- CLI is now published to npm as
@cryptohopper/cli, in addition to the existing standalone binaries on GitHub Releases. Install vianpm i -g @cryptohopper/clior run on demand withnpx @cryptohopper/cli .... The Bun-compiled binaries remain the recommended install path for non-Node users (faster cold start, no Node dependency). - Unicode table formatting for every list/history command (
hoppers list,positions,orders,tournaments list/active/leaderboard,template list,signals list,ai models,arbitrage history,marketmaker history,subscription plans). Backed bycli-table3.
- Added
cli-table3as a runtime dependency.
Follows @cryptohopper/sdk@0.4.0-alpha.1. Adds tournaments commands.
tournaments list— list all tournaments.tournaments active— list currently-active tournaments (public, no auth).tournaments leaderboard <tournament-id>— leaderboard for a specific tournament.
(Social / webhooks / app commands deferred — social is visual-UI heavy, webhooks is a one-shot setup flow typically done through the dev dashboard, and app is mobile-only internals.)
@cryptohopper/sdkdep bumped to^0.4.0-alpha.1.- Shell completions updated with
tournaments.
Follows @cryptohopper/sdk@0.3.0-alpha.1. Adds CLI commands for the A2 resources that make sense in a terminal.
ai credits— remaining AI credit balance.ai models— LLM models available to the account.subscription get— account-level subscription state.subscription plans— list available plans (public, no auth).subscription credits— remaining platform credits.
(Platform / chart commands deferred — their endpoints are web-UI focused, little CLI value.)
@cryptohopper/sdkdep bumped to^0.3.0-alpha.1.- Shell completions updated with
aiandsubscription.
Follows @cryptohopper/sdk@0.2.0-alpha.1 and adds CLI commands for the new resources.
signals list,signals stats,signals performance— signal-provider analytics.arbitrage history,arbitrage total— read-only arbitrage helpers. (Starting new arbitrage runs remains SDK-only for v0.2 — too many params for ergonomic CLI flags; revisit with an interactive wizard in v0.3.)marketmaker get <hopper-id>,marketmaker history <hopper-id>— market-maker bot inspection.template list,template get <id>,template load <template-id> <hopper-id> --yes,template delete <id> --yes— template management.
@cryptohopper/sdkdep bumped to^0.2.0-alpha.1.- Shell completions updated to include the four new top-level commands.
cryptohopper loginis now a real browser OAuth2 flow. Opens your default browser tohttps://www.cryptohopper.com/oauth2/authorize, listens on127.0.0.1:18765/callbackfor the redirect, and exchanges the auth code for a bearer token at/oauth2/token. The CLI is registered as a public OAuth client on cryptohopper.com (noclient_secret).- The paste-token flow is retained as
--token <value>for CI, SSH, and other headless environments.
CRYPTOHOPPER_WEB_URLenv override for pointing at staging OAuth consent pages.webUrladded to the config file and tocryptohopper config get/set.
Initial release. Standalone binaries on GitHub Releases; Bun --compile cross-compiled for linux-x64, darwin-x64, darwin-arm64, windows-x64.
- Auth —
login,logout,whoami - Hoppers —
hoppers list,hoppers get,hoppers panic,positions,orders - Exchange —
ticker(public, no auth) - Backtest —
backtest new,backtest status,backtest limits - Upgrade —
upgrade(downloads next release, verifies SHA256, atomic swap) - Config —
config get,config set(apiUrl, appKey) - Completion —
completion bash|zsh|fish|powershell
- Paste-token flow — copy the OAuth bearer from the developer dashboard.
- Env overrides:
CRYPTOHOPPER_TOKEN,CRYPTOHOPPER_APP_KEY,CRYPTOHOPPER_API_URL. - Config stored at
~/.cryptohopper/config.json(0600).
- Thin wrapper on top of
@cryptohopper/sdk(no duplicate transport). - Exit-code taxonomy: 1 user error, 2 auth, 3 rate-limited, 4 server, 5 network.