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
10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
All notable changes to the `cryptohopper` gem are documented in this file.
The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## 0.1.0.pre.alpha.1 — Unreleased
## 0.1.0.pre.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 (`405 Missing Authentication Token`). Cryptohopper's Public API v1 uses `access-token: <token>` — confirmed by the official [API documentation](https://www.cryptohopper.com/api-documentation/how-the-api-works) and the legacy iOS/Android SDKs. Switching to send `access-token`. The `Authorization` header is no longer set.

### Compatibility
No public-API change. `client.user.get`, `client.hoppers.list`, etc. keep their signatures.

## 0.1.0.pre.alpha.1 — 2026-04-24

Initial release. Launches at full surface parity with the other SDKs at 0.4.0 — all 18 public API domains from day one.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ ch.hoppers.buy(hopper_id: 42, market: "BTC/USDT", amount: 0.001)
ch.hoppers.config_update(42, strategy_id: 99)
ch.hoppers.panic(42)

# Exchange (public, no auth)
# Exchange — market data (still requires a real token; the gateway has no anonymous routes)
ch.exchange.ticker(exchange: "binance", market: "BTC/USDT")
ch.exchange.candles(exchange: "binance", market: "BTC/USDT", timeframe: "1h")

Expand Down
5 changes: 4 additions & 1 deletion lib/cryptohopper/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,10 @@ def build_request(method, uri, body)
end

req = klass.new(uri.request_uri)
req["Authorization"] = "Bearer #{@api_key}"
# 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.
req["access-token"] = @api_key
req["Accept"] = "application/json"
req["User-Agent"] = user_agent_header
# Ruby treats empty strings as truthy, so a literal `if @app_key`
Expand Down
2 changes: 1 addition & 1 deletion lib/cryptohopper/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Cryptohopper
VERSION = "0.1.0.pre.alpha.1"
VERSION = "0.1.0.pre.alpha.2"
end
14 changes: 12 additions & 2 deletions spec/cryptohopper/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ def build_client(**opts)
end

describe "transport" do
it "sends Authorization + User-Agent headers and unwraps {data}" do
it "sends access-token + User-Agent headers and unwraps {data}" do
stub_request(:get, "https://api.cryptohopper.com/v1/user/get")
.with(
headers: {
"Authorization" => "Bearer ch_test",
"access-token" => "ch_test",
"Accept" => "application/json",
"User-Agent" => "cryptohopper-sdk-ruby/#{Cryptohopper::VERSION}"
}
Expand All @@ -39,6 +39,16 @@ def build_client(**opts)
expect(out).to eq({ "hello" => "world" })
end

it "does not send an Authorization header" do
stub_request(:get, "https://api.cryptohopper.com/v1/user/get")
.to_return(status: 200, body: '{"data":{}}')
build_client.send(:_request, "GET", "/user/get")
expect(WebMock).to(
have_requested(:get, "https://api.cryptohopper.com/v1/user/get")
.with { |req| req.headers["Authorization"].nil? }
)
end

it "sends x-api-app-key when app_key is provided" do
stub_request(:get, "https://api.cryptohopper.com/v1/user/get")
.with(headers: { "x-api-app-key" => "client_123" })
Expand Down