Blast Futures Exchange
  • Get Started
    • 👋Introduction
      • What Is Blast?
    • What are Perpetual Futures?
    • Bridging to Blast
    • Blast Points & Gold
      • Blast Gold Liquidity Program
    • BFX Points
      • Staking $RBX
      • Staking $RBX LP
    • USDB Native Yield
    • Referral Program
    • Index Price
    • Funding Rate
    • Deposit & Withdrawal
    • Trading Fees
    • BFX OTC Service
    • Dynamic Market Maker (DMM)
      • Dynamic Router
    • Profit / Loss Calculation
    • Margin Calculation
    • Insurance Fund
    • Liquidations
  • API DOCUMENTATION
    • Introduction
    • Generate Your API Keys
    • Signing with API Key
    • Public Endpoints
      • Market Info
      • Trades
      • Orderbook
      • Funding Rate
      • Candles
    • Private Endpoints
      • Account Operations
      • Authentication
      • Orders
      • Fills
      • Positions
      • Profile
      • Balance History
      • Deadman Switch
    • Websocket
      • Trades
      • Orderbook
      • Market Info
      • Account
    • Responses Data Structure
    • Vault Setup
  • Frequently Asked Questions
  • Contracts
  • Telegram
  • Discord
  • Audits
Powered by GitBook
On this page
  • General Information
  • List of centrifuge websocket client SDKs​
  • Authentication
  • Initial snapshot
  • Updates
  • Channels
  • Reference implementation
  1. API DOCUMENTATION

Websocket

PreviousDeadman SwitchNextTrades

Last updated 9 months ago

General Information

BFX uses a centrifuge scalable real-time websocket for publishing messages. We recommend using one of the client SDKs available on the official centrifuge .

List of centrifuge websocket client SDKs

  • – for browser, NodeJS and React Native

  • - for Go language

  • - for Dart and Flutter

  • – for native iOS development

  • – for native Android development and general Java

Testnet websocket endpoint: wss://api.testnet.rabbitx.io/ws

Mainnet websocket endpoint: wss://api.prod.rabbitx.io/ws

BFX offers a complete pub/sub API with table diffing over WebSocket. You may subscribe to real-time changes on any available channel. All channels require .

Websocket packets may contain multiple messages separated \n. It is recommended to split the message string before parsing the JSON.

def on_message(self, ws: WebSocketApp, message: str):
        for line in message.split('\n'):
            try:
                data = json.loads(line)
            except Exception as e:
                print(u'\u001b[31m ~~~ EXCEPTION ~~~')
                print(e)
                print(message, u'u\u001b[0m')
                return

Authentication

Before subscribing to channels, you must first authenticate using the JWT token received through onboarding. You only need to authenticate once at the beginning. To authenticate, send the following message:

data = {'connect': {'token':"<jwt token>", name='js'}, 'id'=1}

Once onboarded, to subscribe to a channel, send

{"subscribe": {'channel':"<channel name>", 'name':"js"}, 'id': "<internal counter>"}

Note: JWT tokens expire in 48hrs. If your JWT token is expired, you will need to update it. If your JWT token is expired, the connection will be disconnected and you will need to resubscribe with a new token.

Initial snapshot

The initial snapshot will send ALL information about the account. Subsequent messages will only send account change updates.

Initial messages will always be in the following format:

{'id':<internal counter>, 'subscribe':{'data':<data>}}

Updates

Subsequent messages will only send account updates.

Update messages are in the following format:

{'push':{'channel':<channel name>, 'pub':{'data':<data>}}}

Reference implementation for channel subscription

def on_open(self, ws: WebSocketApp):
    # authenticate 
    data = dict(connect=dict(token=self.session._jwt, name='js'), id=1)
    ws.send(json.dumps(data)) 
    
    channels = [f'account@{self.session.profile_id}']

    for market_id in self.market_ids:
        channels.append(f'orderbook:{market_id}')
        channels.append(f'trade:{market_id}')
        channels.append(f'market:{market_id}')

    channels = list(set(channels))

    # subscribe to channels
    for idx, ch in enumerate(channels):
        data = dict(subscribe=dict(channel=ch, name='js'), id=idx + 1)
        self._id_to_channel[idx + 1] = ch
        ws.send(json.dumps(data)) 

Channels

"trade:<symbol>"
"orderbook:<symbol>"
"market:<symbol>"
"account@<profile_id>"  // contains account balances, fills, orders, transfers

Websocket connections go through the following lifecycle:

  • Establish a websocket connection with wss://api.testnet.rabbitx.io/ws/

  • Authenticate with JWT token

  • Subscribe to a channel with {"subscribe": {'channel':"trade:BTC-USD", 'name':"js"}, 'id': "<counter increment>"}

  • Receive data from channels

  • Handle pings at regular intervals: Send an empty frame to the server{} when you get an empty message from the exchange.

Reference implementation

Example script

from websocket import WebSocketApp

from rabbitx import const
from rabbitx.client import Client, WSClient, WSClientCallback


class TestWebSocketCallback(WSClientCallback):

    def account_init(self, profile_id: int, data, ws: WebSocketApp):
        print('account_init', profile_id, data)

    def account_data(self, profile_id: int, data, ws: WebSocketApp):
        print('account_data', profile_id, data)

    def orderbook_init(self, market_id: str, data, ws: WebSocketApp):
        print('orderbook_init', market_id, data)

    def orderbook_data(self, market_id: str, data, ws: WebSocketApp):
        print('orderbook_data', market_id, data)

    def market_init(self, market_id: str, data, ws: WebSocketApp):
        print('market_init', market_id, data)

    def market_data(self, market_id: str, data, ws: WebSocketApp):
        print('market_data', market_id, data)

    def trade_init(self, market_id: str, data, ws: WebSocketApp):
        print('trade_init', market_id, data)

    def trade_data(self, market_id: str, data, ws: WebSocketApp):
        print('trade_data', market_id, data)


if __name__ == '__main__':
    private_key = '<YOUR PRIVATE KEY>'
    client = Client(api_url=const.DEV_URL, private_key=private_key)
    client.onboarding.onboarding()

    wsc = WSClient(const.WS_DEV_URL, client, TestWebSocketCallback(), ['BTC-USD', 'SOL-USD'])
    wsc.run()

jwt_token can be retrieved by .

profile_id is retrieved by .

Python:

Examples:

onboarding
https://github.com/rabbitx-io/rabbitx-python-client
https://github.com/rabbitx-io/rabbitx-python-client/blob/main/examples/ws.py
page
​
centrifuge-js
centrifuge-go
centrifuge-dart
centrifuge-swift
centrifuge-java
authentication
onboarding