def __init__(self,
                 subscriptions: List[Subscription],
                 api_key: str = None,
                 sec_key: str = None,
                 ssl_context=None) -> None:
        super().__init__(websocket_uri=self.WEBSOCKET_URI,
                         subscriptions=subscriptions,
                         builtin_ping_interval=None,
                         periodic_timeout_sec=10,
                         ssl_context=ssl_context)

        self.api_key = api_key
        self.sec_key = sec_key

        self.ping_checker = PeriodicChecker(period_ms=60 * 1000)
示例#2
0
class BitforexWebsocket(WebsocketMgr):
    WEBSOCKET_URI = "wss://www.bitforex.com/mkapi/coinGroup1/ws"

    PING_MSG = 'ping_p'
    PONG_MSG = 'pong_p'

    def __init__(self,
                 subscriptions: List[Subscription],
                 ssl_context=None) -> None:
        super().__init__(websocket_uri=BitforexWebsocket.WEBSOCKET_URI,
                         subscriptions=subscriptions,
                         builtin_ping_interval=None,
                         periodic_timeout_sec=10,
                         ssl_context=ssl_context)

        self.ping_checker = PeriodicChecker(period_ms=30 * 1000)

    async def _process_periodic(self, websocket: Websocket) -> None:
        if self.ping_checker.check():
            LOG.debug(f"> {BitforexWebsocket.PING_MSG}")
            await websocket.send(BitforexWebsocket.PING_MSG)

    async def _process_message(self, websocket: Websocket,
                               message: str) -> None:
        if message != BitforexWebsocket.PONG_MSG:
            message = json.loads(message)
            subscription_id = BitforexSubscription.make_subscription_id(
                message['event'], message['param'])
            await self.publish_message(
                WebsocketMessage(subscription_id=subscription_id,
                                 message=message))
class LiquidWebsocket(WebsocketMgr):
    WEBSOCKET_URI = "wss://tap.liquid.com/app/LiquidTapClient"

    def __init__(self, subscriptions: List[Subscription], api_key: str = None, sec_key: str = None, ssl_context = None) -> None:
        super().__init__(websocket_uri = self.WEBSOCKET_URI, subscriptions = subscriptions,
                         builtin_ping_interval = None, periodic_timeout_sec = 10, ssl_context = ssl_context)

        self.api_key = api_key
        self.sec_key = sec_key

        self.ping_checker = PeriodicChecker(period_ms = 60 * 1000)

    async def _subscribe(self, websocket: Websocket):
        authentication_payload = {
            "token_id": self.api_key,
            "path": '/realtime',
            "nonce": int(time.time_ns())
        }
        LOG.debug(f"Authentication payload: {authentication_payload}")
        signature = jwt.encode(authentication_payload, self.sec_key, 'HS256')

        authentication_data = {
            "headers": {
                "X-Quoine-Auth": signature.decode('utf-8')
            },
            "path": "/realtime"
        }

        authentication_request = {
            "event": "quoine:auth_request",
            "data": authentication_data
        }
        LOG.debug(f"> {authentication_request}")
        await websocket.send(json.dumps(authentication_request))

    async def _process_periodic(self, websocket: Websocket) -> None:
        if self.ping_checker.check():
            ping_message = {
                "event": "pusher:ping",
                "data": ''
            }
            LOG.debug(f"> {ping_message}")
            await websocket.send(json.dumps(ping_message))

    async def _process_message(self, websocket: Websocket, message: str) -> None:
        message = json.loads(message)

        if message['event'] == "pusher:connection_established":
            pass
        elif message['event'] == "pusher:pong":
            pass
        elif message['event'] == "quoine:auth_success":
            subscription_messages = []
            for subscription in self.subscriptions:
                subscription_message = subscription.get_subscription_message()
                subscription_messages.append(subscription_message)

            LOG.debug(f"> {subscription_messages}")
            await websocket.send(json.dumps(subscription_messages))
        elif message['event'] == "quoine:auth_failure":
            raise LiquidException(f"Websocket authentication error: {message}")
        elif message['event'] == "pusher_internal:subscription_succeeded":
            LOG.info(f'Websocket subscribed successfuly: {message}')
        elif message['event'] == "updated":
            await self.publish_message(WebsocketMessage(subscription_id = message['channel'], message = message))
        else:
            raise LiquidException(f"Websocket unknown event type: {message}")
示例#4
0
class BtseWebsocket(WebsocketMgr):
    WEBSOCKET_URI = "wss://ws.btse.com/spotWS"

    def __init__(self,
                 subscriptions: List[Subscription],
                 api_key: str = None,
                 sec_key: str = None,
                 ssl_context=None) -> None:
        super().__init__(websocket_uri=self.WEBSOCKET_URI,
                         subscriptions=subscriptions,
                         ssl_context=ssl_context,
                         builtin_ping_interval=None,
                         auto_reconnect=True,
                         periodic_timeout_sec=5)

        self.api_key = api_key
        self.sec_key = sec_key

        self.ping_checker = PeriodicChecker(period_ms=30 * 1000)

    def get_websocket(self) -> Websocket:
        return self.get_aiohttp_websocket()

    async def _process_periodic(self, websocket: Websocket) -> None:
        if self.ping_checker.check():
            await websocket.send("2")

    async def _authenticate(self, websocket: Websocket):
        requires_authentication = False
        for subscription in self.subscriptions:
            if subscription.requires_authentication():
                requires_authentication = True
                break

        if requires_authentication:
            timestamp_ms = int(
                datetime.datetime.now(tz=datetime.timezone.utc).timestamp() *
                1000)
            signature_string = f"/spotWS{timestamp_ms}"
            signature = hmac.new(self.sec_key.encode('utf-8'),
                                 signature_string.encode('utf-8'),
                                 hashlib.sha384).hexdigest()

            authentication_message = {
                "op": "authKeyExpires",
                "args": [self.api_key, timestamp_ms, signature]
            }

            LOG.debug(f"> {authentication_message}")
            await websocket.send(json.dumps(authentication_message))

            message = await websocket.receive()
            LOG.debug(f"< {message}")

            if 'authenticated successfully' in message:
                LOG.info(f"Websocket authenticated successfully.")
            else:
                raise BtseException(
                    f"Authentication error. Response [{message}]")

    async def _subscribe(self, websocket: Websocket):
        subscription_list = []
        for subscription in self.subscriptions:
            subscription_list += subscription.get_subscription_list()

        subscription_message = {"op": "subscribe", "args": subscription_list}

        LOG.debug(f"> {subscription_message}")
        await websocket.send(json.dumps(subscription_message))

    async def _process_message(self, websocket: Websocket,
                               message: str) -> None:
        message = json.loads(message)
        topic = message['topic']
        channel = topic.split(':')[0]

        await self.publish_message(
            WebsocketMessage(subscription_id=channel, message=message))