diff --git a/bfxapi/websocket/BfxWebsocketClient.py b/bfxapi/websocket/BfxWebsocketClient.py index 628e316..32abb99 100644 --- a/bfxapi/websocket/BfxWebsocketClient.py +++ b/bfxapi/websocket/BfxWebsocketClient.py @@ -4,11 +4,13 @@ from pyee.asyncio import AsyncIOEventEmitter from .handlers import Channels, PublicChannelsHandler, AuthenticatedChannelsHandler -from .errors import BfxWebsocketException, ConnectionNotOpen, InvalidAuthenticationCredentials +from .errors import BfxWebsocketException, ConnectionNotOpen, InvalidAuthenticationCredentials, OutdatedClientVersion HEARTBEAT = "hb" class BfxWebsocketClient(object): + VERSION = 1 + def __init__(self, host, API_KEY=None, API_SECRET=None): self.host, self.chanIds, self.event_emitter = host, dict(), AsyncIOEventEmitter() @@ -32,7 +34,10 @@ class BfxWebsocketClient(object): async for message in websocket: message = json.loads(message) - if isinstance(message, dict) and message["event"] == "subscribed": + if isinstance(message, dict) and message["event"] == "info" and "version" in message: + if BfxWebsocketClient.VERSION != message["version"]: + raise OutdatedClientVersion(f"Mismatch between the client version and the server version. Update the library to the latest version to continue (client version: {BfxWebsocketClient.VERSION}, server version: {message['version']}).") + elif isinstance(message, dict) and message["event"] == "subscribed": self.chanIds[message["chanId"]] = message self.event_emitter.emit("subscribed", message) @@ -43,14 +48,15 @@ class BfxWebsocketClient(object): if message["status"] == "OK": self.event_emitter.emit("authenticated", message) else: raise InvalidAuthenticationCredentials("Cannot authenticate with given API-KEY and API-SECRET.") + elif isinstance(message, dict) and message["event"] == "error": + self.event_emitter.emit("error", message["code"], message["msg"]) elif isinstance(message, list) and ((chanId := message[0]) or True) and message[1] != HEARTBEAT: if chanId == 0: self.handlers["authenticated"].handle(message[1], message[2]) else: self.handlers["public"].handle(self.chanIds[chanId], *message[1:]) except websockets.ConnectionClosed: continue - - @staticmethod + def __require_websocket_connection(function): async def wrapper(self, *args, **kwargs): if self.websocket == None or self.websocket.open == False: diff --git a/bfxapi/websocket/__init__.py b/bfxapi/websocket/__init__.py index c3aee02..5253ab5 100644 --- a/bfxapi/websocket/__init__.py +++ b/bfxapi/websocket/__init__.py @@ -1,3 +1,3 @@ from .BfxWebsocketClient import BfxWebsocketClient from .handlers import Channels -from .errors import BfxWebsocketException, ConnectionNotOpen, InvalidAuthenticationCredentials \ No newline at end of file +from .errors import BfxWebsocketException, ConnectionNotOpen, InvalidAuthenticationCredentials, OutdatedClientVersion \ No newline at end of file diff --git a/bfxapi/websocket/errors.py b/bfxapi/websocket/errors.py index d8f4b03..c5338d1 100644 --- a/bfxapi/websocket/errors.py +++ b/bfxapi/websocket/errors.py @@ -23,4 +23,11 @@ class InvalidAuthenticationCredentials(BfxWebsocketException): This error indicates that the user has provided incorrect credentials (API-KEY and API-SECRET) for authentication. """ + pass + +class OutdatedClientVersion(BfxWebsocketException): + """ + This error indicates a mismatch between the client version and the server WSS version. + """ + pass \ No newline at end of file