csko / gdax-python-api

GDAX API written in Python3 using async/await
MIT License
52 stars 21 forks source link

Invalid signature using authenticating with websockets #11

Open remarqUK opened 6 years ago

remarqUK commented 6 years ago

I'm writing a script to subscribe to the authenticated "user" channel using the code below (which used orderbook.py as its basis) and I'm passing the api_key/api_secret and passphrase through (I've redacted them in this code example)

The error I get back is:

{'message': 'Sorry, you could not be authenticated: Bad Request', 'reason': 'invalid signature', 'type': 'error'}

Any ideas ?

import asyncio
import pprint

from gdax.websocket_feed_listener import WebSocketFeedListener

class User(WebSocketFeedListener):

    def __init__(self, product_ids='ETH-USD', api_key=None, api_secret=None,
                 passphrase=None, use_heartbeat=False,
                 trade_log_file_path=None):

        super().__init__(product_ids=product_ids,
                         channels='user',
                         api_key=api_key,
                         api_secret=api_secret,
                         passphrase=passphrase,
                         use_heartbeat=use_heartbeat
                         )

        if not isinstance(product_ids, list):
            product_ids = [product_ids]

    async def __aenter__(self):

        await super().__aenter__()

        return self

    async def handle_message(self):

        try:
            message = await self._recv()
        except aiohttp.ServerDisconnectedError as exc:
            logging.error(
                f'Error: Exception: f{exc}. Re-initializing websocket.')
            await self.__aexit__(None, None, None)
            await self.__aenter__()
            return

        return message

async def run_user():  # pragma: no cover
    async with User(
            ['ETH-USD'],
            api_key="XXXXXXXX",
            api_secret="XXXXXXXX",
            passphrase="XXXXXXXX"
    ) as user:
        while True:
            message = await user.handle_message()
            if message is None:
                continue

            pprint.pprint(message)

if __name__ == "__main__":  # pragma: no cover
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run_user())
remarqUK commented 6 years ago

I think line 103 of websocket_feed_listener.py is incorrect, instead of: path = '/users/self'

it should read

path='/users/self/verify'

this is in accordance with the GDAX documentation here:

https://docs.gdax.com/#subscribe

Making this change results in the authentication working