You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jul 7, 2026. It is now read-only.
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'notinconfigor'key_id'notinconfig['coinbase'] or'key_secret'notinconfig['coinbase']:
raiseValueError('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:
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.