WebSocket

This page will help you get started with zkLighter WebSocket server.

Connection

URL: wss://mainnet.zklighter.elliot.ai/stream; wss://testnet.zklighter.elliot.ai/stream

You can directly connect to the WebSocket server using wscat:

wscat -c 'wss://mainnet.zklighter.elliot.ai/stream'

Send Tx

You can send transactions using the websocket as follows:

{
    "type": "jsonapi/sendtx",
    "data": {
        "tx_type": INTEGER,
        "tx_info": ...
    }
}

The tx_type options can be found in the SignerClient file, while tx_info can be generated using the sign methods in the SignerClient.

Example: ws_send_tx.py

Send Batch Tx

You can send batch transactions to execute up to 50 transactions in a single message.

{
    "type": "jsonapi/sendtxbatch",
    "data": {
        "tx_types": "[INTEGER]",
        "tx_infos": "[tx_info]"
    }
}

The tx_type options can be found in the SignerClient file, while tx_info can be generated using the sign methods in the SignerClient.

Example: ws_send_batch_tx.py

Types

We first need to define some types that appear often in the JSONs.

Transaction JSON

To decode event_info, you can refer to Data Structures.

Transaction = {
    "hash": STRING,
    "type": INTEGER,
    "info": STRING, // json object as string, attributes depending on the tx type
    "event_info": STRING, // json object as string, attributes depending on the tx type
    "status": INTEGER,
    "transaction_index": INTEGER,
    "l1_address": STRING,
    "account_index": INTEGER,
    "nonce": INTEGER,
    "expire_at": INTEGER,
    "block_height": INTEGER,
    "queued_at": INTEGER,
    "executed_at": INTEGER,
    "sequence_index": INTEGER,
    "parent_hash": STRING
}

Example:

{
    "hash": "0xabc123456789def",
    "type": 15,
    "info": "{\"AccountIndex\":1,\"ApiKeyIndex\":2,\"MarketIndex\":3,\"Index\":404,\"ExpiredAt\":1700000000000,\"Nonce\":1234,\"Sig\":\"0xsigexample\"}",
    "event_info": "{\"a\":1,\"i\":404,\"u\":123,\"ae\":\"\"}",
    "status": 2,
    "transaction_index": 10,
    "l1_address": "0x123abc456def789",
    "account_index": 101,
    "nonce": 12345,
    "expire_at": 1700000000000,
    "block_height": 1500000,
    "queued_at": 1699999990000,
    "executed_at": 1700000000005,
    "sequence_index": 5678,
    "parent_hash": "0xparenthash123456"
}

Used in: Account Tx.

Order JSON

Order = {
    "order_index": INTEGER,
    "client_order_index": INTEGER,
    "order_id": STRING, // same as order_index but string
    "client_order_id": STRING, // same as client_order_index but string
    "market_index": INTEGER,
    "owner_account_index": INTEGER,
    "initial_base_amount": STRING,
    "price": STRING,
    "nonce": INTEGER,
    "remaining_base_amount": STRING,
    "is_ask": BOOL,
    "base_size": INTEGER,
    "base_price": INTEGER,
    "filled_base_amount": STRING,
    "filled_quote_amount": STRING,
    "side": STRING,
    "type": STRING,
    "time_in_force": STRING,
    "reduce_only": BOOL,
    "trigger_price": STRING,
    "order_expiry": INTEGER,
    "status": STRING,
    "trigger_status": STRING,
    "trigger_time": INTEGER,
    "parent_order_index": INTEGER,
    "parent_order_id": STRING,
    "to_trigger_order_id_0": STRING,
    "to_trigger_order_id_1": STRING,
    "to_cancel_order_id_0": STRING,
    "block_height": INTEGER,
    "timestamp": INTEGER,
		"created_at": INTEGER,
		"updated_at": INTEGER
}

Used in: Account Market, Account All Orders, Account Orders.

Trade JSON

Trade = {
    "trade_id": INTEGER,
    "tx_hash": STRING,
    "type": STRING,
    "market_id": INTEGER,
    "size": STRING,
    "price": STRING,
    "usd_amount": STRING,
    "ask_id": INTEGER,
    "bid_id": INTEGER,
    "ask_account_id": INTEGER,
    "bid_account_id": INTEGER,
    "is_maker_ask": BOOLEAN,
    "block_height": INTEGER,
    "timestamp": INTEGER,
    "taker_fee": INTEGER (omitted when zero),
    "taker_position_size_before": STRING (omitted when empty),
    "taker_entry_quote_before": STRING (omitted when empty),
    "taker_initial_margin_fraction_before": INTEGER (omitted when zero),
    "taker_position_sign_changed": BOOL (omitted when false),
    "maker_fee": INTEGER (omitted when zero),
    "maker_position_size_before": STRING (omitted when empty),
    "maker_entry_quote_before": STRING (omitted when empty),
    "maker_initial_margin_fraction_before": INTEGER (omitted when zero),
    "maker_position_sign_changed": BOOL (omitted when false),
}

Example:

{
    "trade_id": 401,
    "tx_hash": "0xabc123456789",
    "type": "buy",
    "market_id": 101,
    "size": "0.5",
    "price": "20000.00",
    "usd_amount": "10000.00",
    "ask_id": 501,
    "bid_id": 502,
    "ask_account_id": 123456,
    "bid_account_id": 654321,
    "is_maker_ask": true,
    "block_height": 1500000,
    "timestamp": 1700000000,
    "taker_position_size_before":"1.14880",
    "taker_entry_quote_before":"136130.046511",
    "taker_initial_margin_fraction_before":500,
    "maker_position_size_before":"-0.02594",
    "maker_entry_quote_before":"3075.396750",
    "maker_initial_margin_fraction_before":400
}

Used in: Trade, Account All, Account Market, Account All Trades.

Position JSON

Position = {
    "market_id": INTEGER,
    "symbol": STRING,
    "initial_margin_fraction": STRING,
    "open_order_count": INTEGER,
    "pending_order_count": INTEGER,
    "position_tied_order_count": INTEGER,
    "sign": INTEGER,
    "position": STRING,
    "avg_entry_price": STRING,
    "position_value": STRING,
    "unrealized_pnl": STRING,
    "realized_pnl": STRING,
    "liquidation_price": STRING,
    "total_funding_paid_out": STRING (omitted when empty),
    "margin_mode": INT,
    "allocated_margin": STRING,
}

Example:

{
    "market_id": 101,
    "symbol": "BTC-USD",
    "initial_margin_fraction": "0.1",
    "open_order_count": 2,
    "pending_order_count": 1,
    "position_tied_order_count": 3,
    "sign": 1,
    "position": "0.5",
    "avg_entry_price": "20000.00",
    "position_value": "10000.00",
    "unrealized_pnl": "500.00",
    "realized_pnl": "100.00",
    "liquidation_price": "3024.66",
    "total_funding_paid_out": "34.2",
    "margin_mode": 1,
    "allocated_margin": "46342",
}

Used in: Account All, Account Market, Account All Positions.

PoolShares JSON

PoolShares = {
    "public_pool_index": INTEGER,
    "shares_amount": INTEGER,
    "entry_usdc": STRING
}

Example:

{
    "public_pool_index": 1,
    "shares_amount": 100,
    "entry_usdc": "1000.00"
}

Used in: Account All, Account All Positions.

Channels

Order Book

The order book channel sends the new ask and bid orders for the given market. While the nonce is tied to Lighter's matching engine, the offset is tied to the API servers; hence, you can expect the offset to change on reconnection if you're routed to a different server. Additionally, this channel sends a complete snapshot on connection, but only state updates after that.

{
    "type": "subscribe",
    "channel": "order_book/{MARKET_INDEX}"
}

Example Subscription

{
    "type": "subscribe",
    "channel": "order_book/0"
}

Response Structure

{
    "channel": "order_book:{MARKET_INDEX}",
    "offset": INTEGER,
    "order_book": {
        "code": INTEGER,
        "asks": [
            {
                "price": STRING,
                "size": STRING
            }
        ],
        "bids": [
            {
                "price": STRING,
                "size": STRING
            }
        ],
      	"offset": INTEGER,
        "nonce": INTEGER,
				"timestamp": INTEGER
    },
    "type": "update/order_book"
}

Example Response

{
    "channel": "order_book:0",
    "offset": 41692864,
    "order_book": {
        "code": 0,
        "asks": [
            {
                "price": "3327.46",
                "size": "29.0915"
            }
        ],
        "bids": [
            {
                "price": "3338.80",
                "size": "10.2898"
            }
        ],
        "offset": 41692864
    },
    "type": "update/order_book"
}

Market Stats

The market stats channel sends the market stat data for the given market.

{
    "type": "subscribe",
    "channel": "market_stats/{MARKET_INDEX}"
}

or

{
    "type": "subscribe",
    "channel": "market_stats/all"
}

Example Subscription

{
    "type": "subscribe",
    "channel": "market_stats/0"
}

Response Structure

{
    "channel": "market_stats:{MARKET_INDEX}",
    "market_stats": {
        "market_id": INTEGER,
        "index_price": STRING,
        "mark_price": STRING,
        "open_interest": STRING,
        "last_trade_price": STRING,
      	"current_funding_rate": STRING,
        "funding_rate": STRING,
        "funding_timestamp": INTEGER,
        "daily_base_token_volume": FLOAT,
        "daily_quote_token_volume": FLOAT,
        "daily_price_low": FLOAT,
        "daily_price_high": FLOAT,
        "daily_price_change": FLOAT
    },
    "type": "update/market_stats"
}

Example Response

{
    "channel": "market_stats:0",
    "market_stats": {
        "market_id": 0,
        "index_price": "3335.04",
        "mark_price": "3335.09",
        "open_interest": "235.25",
        "last_trade_price": "3335.65",
        "current_funding_rate": "0.0057",
        "funding_rate": "0.0005",
        "funding_timestamp": 1722337200000,
        "daily_base_token_volume": 230206.48999999944,
        "daily_quote_token_volume": 765295250.9804002,
        "daily_price_low": 3265.13,
        "daily_price_high": 3386.01,
        "daily_price_change": -1.1562612047992835
    },
    "type": "update/market_stats"
}

Trade

The trade channel sends the new trade data for the given market.

{
    "type": "subscribe",
    "channel": "trade/{MARKET_INDEX}"
}

Example Subscription

{
    "type": "subscribe",
    "channel": "trade/0"
}

Response Structure

{
    "channel": "trade:{MARKET_INDEX}",
    "trades": [Trade]
    ],
    "type": "update/trade"
}

Example Response

{
    "channel": "trade:0",
    "trades": [
        {
            "trade_id": 14035051,
            "tx_hash": "189068ebc6b5c7e5efda96f92842a2fafd280990692e56899a98de8c4a12a38c",
            "type": "trade",
            "market_id": 0,
            "size": "0.1187",
            "price": "3335.65",
            "usd_amount": "13.67",
            "ask_id": 41720126,
            "bid_id": 41720037,
            "ask_account_id": 2304,
            "bid_account_id": 21504,
            "is_maker_ask": false,
            "block_height": 2204468,
            "timestamp": 1722339648
        }
    ],
    "type": "update/trade"
}

Account All

The account all channel sends specific account market data for all markets.

{
    "type": "subscribe",
    "channel": "account_all/{ACCOUNT_ID}"
}

Example Subscription

{
    "type": "subscribe",
    "channel": "account_all/1"
}

Response Structure

{
    "account": INTEGER,
    "channel": "account_all:{ACCOUNT_ID}",
    "daily_trades_count": INTEGER,
    "daily_volume": INTEGER,
    "weekly_trades_count": INTEGER,
    "weekly_volume": INTEGER,
    "monthly_trades_count": INTEGER,
    "monthly_volume": INTEGER,
    "total_trades_count": INTEGER,
    "total_volume": INTEGER,
    "funding_histories": {
    	"{MARKET_INDEX}": [
        {
          "timestamp": INTEGER,
          "market_id": INTEGER,
          "funding_id": INTEGER,
          "change": STRING,
          "rate": STRING,
          "position_size": STRING,
          "position_side": STRING
        }
      ]
    },
    "positions": {
        "{MARKET_INDEX}": Position
    },
    "shares": [PoolShares],
    "trades": {
        "{MARKET_INDEX}": [Trade]
    },
    "type": "update/account_all"
}

Example Response

{
    "account": 10,
    "channel": "account_all:10",
    "daily_trades_count": 123,
    "daily_volume": 234,
    "weekly_trades_count": 345,
    "weekly_volume": 456,
    "monthly_trades_count": 567,
    "monthly_volume": 678,
    "total_trades_count": 891,
    "total_volume": 912,
    "funding_histories": {
        "1": [
            {
                "timestamp": 1700000000,
                "market_id": 101,
                "funding_id": 2001,
                "change": "0.001",
                "rate": "0.0001",
                "position_size": "0.5",
                "position_side": "long"
            }
        ]
    },
    "positions": {
        "1": {
            "market_id": 101,
            "symbol": "BTC-USD",
            "initial_margin_fraction": "0.1",
            "open_order_count": 2,
            "pending_order_count": 1,
            "position_tied_order_count": 3,
            "sign": 1,
            "position": "0.5",
            "avg_entry_price": "20000.00",
            "position_value": "10000.00",
            "unrealized_pnl": "500.00",
            "realized_pnl": "100.00",
            "liquidation_price": "3024.66",
            "total_funding_paid_out": "34.2",
            "margin_mode": 1,
            "allocated_margin": "46342",
        }
    },
    "shares": [
        {
            "public_pool_index": 1,
            "shares_amount": 100,
            "entry_usdc": "1000.00"
        }
    ],
    "trades": {
        "1": [
            {
                "trade_id": 401,
                "tx_hash": "0xabc123456789",
                "type": "buy",
                "market_id": 101,
                "size": "0.5",
                "price": "20000.00",
                "usd_amount": "10000.00",
                "ask_id": 501,
                "bid_id": 502,
                "ask_account_id": 123456,
                "bid_account_id": 654321,
                "is_maker_ask": true,
                "block_height": 1500000,
                "timestamp": 1700000000,
                "taker_position_size_before":"1.14880",
                "taker_entry_quote_before":"136130.046511",
                "taker_initial_margin_fraction_before":500,
                "maker_position_size_before":"-0.02594",
                "maker_entry_quote_before":"3075.396750",
                "maker_initial_margin_fraction_before":400
            }
        ]
    },
    "type": "update/account"
}

Account Market

The account market channel sends specific account market data for a market.

{
    "type": "subscribe",
    "channel": "account_market/{MARKET_ID}/{ACCOUNT_ID}",
    "auth": "{AUTH_TOKEN}"
}

Example Subscription

{
    "type": "subscribe",
    "channel": "account_market/0/40",
    "auth": "{AUTH_TOKEN}"
}

Response Structure

{
    "account": INTEGER,
    "channel": "account_market/{MARKET_ID}/{ACCOUNT_ID}",
    "funding_history": {
        "timestamp": INTEGER,
        "market_id": INTEGER,
        "funding_id": INTEGER,
        "change": STRING,
        "rate": STRING,
        "position_size": STRING,
        "position_side": STRING
        },
    "orders": [Order],
    "position": Position,
    "trades": [Trade],
    "type": "update/account_market"
}

Account Stats

The account stats channel sends account stats data for the specific account.

{
    "type": "subscribe",
    "channel": "user_stats/{ACCOUNT_ID}"
}

Example Subscription

{
    "type": "subscribe",
    "channel": "user_stats/0"
}

Response Structure

{
    "channel": "user_stats:{ACCOUNT_ID}",
    "stats": {
        "collateral": STRING,
        "portfolio_value": STRING,
        "leverage": STRING,
        "available_balance": STRING,      
        "margin_usage": STRING,
        "buying_power": STRING,        
				"cross_stats":{
           "collateral": STRING,
           "portfolio_value": STRING,
           "leverage": STRING,
           "available_balance": STRING,
           "margin_usage": STRING,
           "buying_power": STRING
        },
        "total_stats":{
           "collateral": STRING,
           "portfolio_value": STRING,
           "leverage": STRING,
           "available_balance": STRING,
           "margin_usage": STRING,
           "buying_power": STRING
        }

    },
    "type": "update/user_stats"
}

Example Response

{
    "channel": "user_stats:10",
    "stats": {
        "collateral": "5000.00",
        "portfolio_value": "15000.00",
        "leverage": "3.0",
        "available_balance": "2000.00",
        "margin_usage": "0.80",
        "buying_power": "4000.00",
        "cross_stats":{
           "collateral":"0.000000",
           "portfolio_value":"0.000000",
           "leverage":"0.00",
           "available_balance":"0.000000",
           "margin_usage":"0.00",
           "buying_power":"0"
        },
        "total_stats":{
           "collateral":"0.000000",
           "portfolio_value":"0.000000",
           "leverage":"0.00",
           "available_balance":"0.000000",
           "margin_usage":"0.00",
           "buying_power":"0"
        }
    },
    "type": "update/user_stats"
}

Account Tx

This channel sends transactions related to a specific account.

{
    "type": "subscribe",
    "channel": "account_tx/{ACCOUNT_ID}",
    "auth": "{AUTH_TOKEN}"
}

Response Structure

{
    "channel": "account_tx:{ACCOUNT_ID}",
    "txs": [Account_tx],
    "type": "update/account_tx"
}

Account All Orders

The account all orders channel sends data about all the orders of an account.

{
    "type": "subscribe",
    "channel": "account_all_orders/{ACCOUNT_ID}",
    "auth": "{AUTH_TOKEN}"
}

Response Structure

{
    "channel": "account_all_orders:{ACCOUNT_ID}",
    "orders": {
        "{MARKET_INDEX}": [Order]
    },
    "type": "update/account_all_orders"
}

Height

Blockchain height updates

{
    "type": "subscribe",
    "channel": "height",
}

Response Structure

{
    "channel": "height",
    "height": INTEGER,
    "type": "update/height"
}

Pool data

Provides data about pool activities: trades, orders, positions, shares and funding histories.

{
    "type": "subscribe",
    "channel": "pool_data/{ACCOUNT_ID}",
    "auth": "{AUTH_TOKEN}"
}

Response Structure

{
    "channel": "pool_data:{ACCOUNT_ID}",
    "account": INTEGER,
    "trades": {
        "{MARKET_INDEX}": [Trade]
    },
    "orders": {
        "{MARKET_INDEX}": [Order]
    },
    "positions": {
        "{MARKET_INDEX}": Position
    },
    "shares": [PoolShares],
    "funding_histories": {
        "{MARKET_INDEX}": [PositionFunding]
    },
    "type": "subscribed/pool_data"
}

Pool info

Provides information about pools.

{
    "type": "subscribe",
    "channel": "pool_info/{ACCOUNT_ID}",
    "auth": "{AUTH_TOKEN}"
}

Response Structure

{
    "channel": "pool_info:{ACCOUNT_ID}",
    "pool_info": {
        "status": INTEGER,
        "operator_fee": STRING,
        "min_operator_share_rate": STRING,
        "total_shares": INTEGER,
        "operator_shares": INTEGER,
        "annual_percentage_yield": FLOAT,
        "daily_returns": [
            {
                "timestamp": INTEGER,
                "daily_return": FLOAT
            }
        ],
        "share_prices": [
            {
                "timestamp": INTEGER,
                "share_price": FLOAT
            }
        ]
    },
    "type": "subscribed/pool_info"
}

Notification

Provides notifications received by an account. Notifications can be of three kinds: liquidation, deleverage, or announcement. Each kind has a different content structure.

{
    "type": "subscribe",
    "channel": "notification/{ACCOUNT_ID}",
    "auth": "{AUTH_TOKEN}"
}

Response Structure

{
    "channel": "notification:{ACCOUNT_ID}",
    "notifs": [
        {
            "id": STRING,
            "created_at": STRING,
            "updated_at": STRING,
            "kind": STRING,
            "account_index": INTEGER,
            "content": NotificationContent,
            "ack": BOOLEAN,
            "acked_at": STRING
        }
    ],
    "type": "subscribed/notification"
}

Liquidation Notification Content

{
    "id": STRING,
    "is_ask": BOOL,
    "usdc_amount": STRING,
    "size": STRING,
    "market_index": INTEGER,
    "price": STRING,
    "timestamp": INTEGER,
    "avg_price": STRING
}

Deleverage Notification Content

{
    "id": STRING,
    "usdc_amount": STRING,
    "size": STRING,
    "market_index": INTEGER,
    "settlement_price": STRING,
    "timestamp": INTEGER
}

Announcement Notification Content

{
    "title": STRING,
    "content": STRING, 
    "created_at": INTEGER
}

Example response

{
    "channel": "notification:12345",
    "notifs": [
        {
            "id": "notif_123",
            "created_at": "2024-01-15T10:30:00Z",
            "updated_at": "2024-01-15T10:30:00Z",
            "kind": "liquidation",
            "account_index": 12345,
            "content": {
                "id": "notif_123",
                "is_ask": false,
                "usdc_amount": "1500.50",
                "size": "0.500000",
                "market_index": 1,
                "price": "3000.00",
                "timestamp": 1705312200,
                "avg_price": "3000.00"
            },
            "ack": false,
            "acked_at": null
        },
        {
            "id": "notif_124",
            "created_at": "2024-01-15T11:00:00Z",
            "updated_at": "2024-01-15T11:00:00Z",
            "kind": "deleverage",
            "account_index": 12345,
            "content": {
                "id": "notif_124",
                "usdc_amount": "500.25",
                "size": "0.200000",
                "market_index": 1,
                "settlement_price": "2501.25",
                "timestamp": 1705314000
            },
            "ack": false,
            "acked_at": null
        }
    ],
    "type": "update/notification"
}

Account Orders

The account all orders channel sends data about the orders of an account on a certain market.

{
    "type": "subscribe",
    "channel": "account_orders/{MARKET_INDEX}/{ACCOUNT_ID}",
    "auth": "{AUTH_TOKEN}"
}

Response Structure

{
    "account": {ACCOUNT_INDEX}, 
    "channel": "account_orders:{MARKET_INDEX}",
    "nonce": INTEGER,
    "orders": {
        "{MARKET_INDEX}": [Order] // the only present market index will be the one provided
    },
    "type": "update/account_orders"
}

Account All Trades

The account all trades channel sends data about all the trades of an account.

{
    "type": "subscribe",
    "channel": "account_all_trades/{ACCOUNT_ID}",
    "auth": "{AUTH_TOKEN}"
}

Response Structure

{
    "channel": "account_all_trades:{ACCOUNT_ID}",
    "trades": {
        "{MARKET_INDEX}": [Trade]
    },
    "total_volume": FLOAT,
    "monthly_volume": FLOAT,
    "weekly_volume": FLOAT,
    "daily_volume": FLOAT,
    "type": "update/account_all_trades"
}

Account All Positions

The account all orders channel sends data about all the order of an account.

{
    "type": "subscribe",
    "channel": "account_all_positions/{ACCOUNT_ID}",
    "auth": "{AUTH_TOKEN}"
}

Response Structure

{
    "channel": "account_all_positions:{ACCOUNT_ID}",
    "positions": {
        "{MARKET_INDEX}": Position
    },
    "shares": [PoolShares],
    "type": "update/account_all_positions"
}