Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,16 @@
All notable changes to `@cryptohopper/sdk` are documented in this file.
The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## 0.4.0-alpha.1 — Unreleased
## 0.4.0-alpha.2 — Unreleased

### Fixed
- **Critical: every authenticated request was rejected by the API gateway.** The transport sent `Authorization: Bearer <token>`, which the AWS API Gateway in front of `api.cryptohopper.com/v1/*` rejects (it routes `Authorization` to a SigV4 parser and returns `405 Missing Authentication Token`). Cryptohopper's Public API v1 uses a different header — `access-token: <token>` — confirmed by the official [API documentation](https://www.cryptohopper.com/api-documentation/how-the-api-works) and the legacy `cryptohopper-ios-sdk` / `cryptohopper-android-sdk` (which also send `access-token` for v1 calls). Switching the SDK to send `access-token` instead. The `Authorization` header is no longer set.
- The `appKey` → `x-api-app-key` header is unchanged; that one was always correct.

### Compatibility
No public-API change. The fix is purely in the request-builder and is invisible to callers — `client.user.get()`, `client.hoppers.list()`, etc. all keep their existing signatures and behaviour. Only the wire-level header sent on each request changes.

## 0.4.0-alpha.1 — 2026-04-25

Adds four more API domains: `social`, `tournaments`, `webhooks`, `app`. This is the final A-wave — all 14 remaining public domains are now covered.

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ await ch.hoppers.configGet(42);
await ch.hoppers.configUpdate(42, { /* config fields */ });
await ch.hoppers.panic(42);

// Exchange (public — no auth required)
// Exchange — market data (still requires a real token; the gateway has no anonymous routes)
await ch.exchange.ticker({ exchange: "binance", market: "BTC/USDT" });
await ch.exchange.candles({ exchange: "binance", market: "BTC/USDT", timeframe: "1h" });
await ch.exchange.orderbook({ exchange: "binance", market: "BTC/USDT" });
Expand All @@ -74,7 +74,7 @@ await ch.backtest.list();
await ch.backtest.cancel(1);
await ch.backtest.limits();

// Marketplace (public — no auth required)
// Marketplace — same auth requirement as everything else
await ch.market.signals({ type: "buy" });
await ch.market.signal(99);
await ch.market.items({ type: "strategy" });
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cryptohopper/sdk",
"version": "0.4.0-alpha.1",
"version": "0.4.0-alpha.2",
"description": "Official Node.js SDK for the Cryptohopper API",
"type": "module",
"main": "./dist/index.js",
Expand Down
5 changes: 4 additions & 1 deletion src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,10 @@ export class CryptohopperClient {
const url = this.buildUrl(path, options.query);
const ua = `cryptohopper-sdk/${CURRENT_VERSION}${this.userAgentSuffix ? ` ${this.userAgentSuffix}` : ""}`;
const headers: Record<string, string> = {
Authorization: `Bearer ${this.apiKey}`,
// Cryptohopper Public API v1 uses `access-token: <token>`, not the
// OAuth2-conventional `Authorization: Bearer <token>`. The gateway in
// front of the API rejects Bearer with a SigV4 parse error.
"access-token": this.apiKey,
"User-Agent": ua,
Accept: "application/json",
};
Expand Down
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const CURRENT_VERSION = "0.4.0-alpha.1";
export const CURRENT_VERSION = "0.4.0-alpha.2";
3 changes: 2 additions & 1 deletion test/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ describe("CryptohopperClient transport", () => {
const req = mock.requests[0]!;
expect(req.url).toBe("https://api.cryptohopper.com/v1/user/get");
expect(req.method).toBe("GET");
expect(req.headers["authorization"]).toBe("Bearer ch_abc");
expect(req.headers["access-token"]).toBe("ch_abc");
expect(req.headers["authorization"]).toBeUndefined();
expect(req.headers["user-agent"]).toBe(`cryptohopper-sdk/${CURRENT_VERSION}`);
expect(req.headers["x-api-app-key"]).toBeUndefined();
});
Expand Down