Version: 2.4.1 (code unchanged on current master)
The Coinbase adapter requires key_id/key_secret even for public market data, although Coinbase made Advanced Trade market data public in 2024. Two places enforce this:
Coinbase.symbols() (coinbase.py#L77-L82) raises unconditionally without credentials:
if 'coinbase' not in config or 'key_id' not in config['coinbase'] or 'key_secret' not in config['coinbase']:
raise ValueError('You must provide key_id and key_secret in config to retrieve symbols from Coinbase.')
subscribe() (coinbase.py#L173-L185) calls get_private_parameters(self.config, ...) unconditionally, which reads config["coinbase"]["key_secret"] and signs every subscription — so subscribing without keys fails even though the channels don't need a signature.
What Coinbase actually requires now
-
REST: GET https://api.coinbase.com/api/v3/brokerage/market/products is the public, unauthenticated twin of the authed /api/v3/brokerage/products the adapter currently uses for the symbol map. Verify with:
curl -s 'https://api.coinbase.com/api/v3/brokerage/market/products' | head -c 300
It returns the full product list with the same shape (products, product_id, base_currency_id, quote_currency_id, quote_increment), so _parse_symbol_data works as-is.
-
WebSocket: wss://advanced-trade-ws.coinbase.com accepts unsigned subscriptions to the public market data channels (market_trades, level2, heartbeats). An unsigned message of the shape the adapter already builds:
{"type": "subscribe", "product_ids": ["BTC-USD"], "channel": "market_trades"}
is accepted and streams trades (verified live).
Docs: https://docs.cdp.coinbase.com/advanced-trade/docs/ws-overview (public market data does not require authentication).
Suggested fix
- Point the symbol-map REST call at
/market/products (no headers needed) and drop the credential check in symbols().
- In
subscribe(), only merge in get_private_parameters(...) when credentials are actually configured, so authenticated use keeps working but TRADES/L2_BOOK run with zero config.
I have a working subclass doing exactly this and can open a PR if that's welcome.
Version: 2.4.1 (code unchanged on current master)
The Coinbase adapter requires
key_id/key_secreteven for public market data, although Coinbase made Advanced Trade market data public in 2024. Two places enforce this:Coinbase.symbols()(coinbase.py#L77-L82) raises unconditionally without credentials:subscribe()(coinbase.py#L173-L185) callsget_private_parameters(self.config, ...)unconditionally, which readsconfig["coinbase"]["key_secret"]and signs every subscription — so subscribing without keys fails even though the channels don't need a signature.What Coinbase actually requires now
REST:
GET https://api.coinbase.com/api/v3/brokerage/market/productsis the public, unauthenticated twin of the authed/api/v3/brokerage/productsthe adapter currently uses for the symbol map. Verify with:It returns the full product list with the same shape (
products,product_id,base_currency_id,quote_currency_id,quote_increment), so_parse_symbol_dataworks as-is.WebSocket:
wss://advanced-trade-ws.coinbase.comaccepts unsigned subscriptions to the public market data channels (market_trades,level2,heartbeats). An unsigned message of the shape the adapter already builds:{"type": "subscribe", "product_ids": ["BTC-USD"], "channel": "market_trades"}is accepted and streams trades (verified live).
Docs: https://docs.cdp.coinbase.com/advanced-trade/docs/ws-overview (public market data does not require authentication).
Suggested fix
/market/products(no headers needed) and drop the credential check insymbols().subscribe(), only merge inget_private_parameters(...)when credentials are actually configured, so authenticated use keeps working but TRADES/L2_BOOK run with zero config.I have a working subclass doing exactly this and can open a PR if that's welcome.