# Kana Perps Python Websocket API

### **Important Note:**

For all the Websocket endpoints below, pass your profile address.

To track your transactions on-chain (e.g., via **Aptos Explorer** or **Aptos Scan**), you must use your **profile address**, as all on-chain trades are executed using this profile address.

To obtain your profile address, use the `/getProfileAddress` endpoint and provide your wallet address as the `userAddress` parameter.

### How to Fetch the Profile Address:

**Example endpoint:**\
<https://perps-tradeapi.kanalabs.io/getProfileAddress?userAddress=0xd01e3a233632a41463bd6d289e99e69e1b50815c7afff710e1c992659a8722f3>\
\
**Example code:**\
[https://docs.kanalabs.io/perpetual-futures/kana-perps/api-docs/kana-perps-python-rest-api#id-20.-](https://docs.kanalabs.io/perpetual-futures/kana-perps/api-docs/kana-perps-typescript-rest-api#id-19.-update-stop-loss)get-profile-address

### Testnet Supported Markets

<table data-header-hidden><thead><tr><th></th><th width="282"></th><th></th></tr></thead><tbody><tr><td><strong>Asset</strong></td><td><strong>Market ID</strong></td><td><strong>Description</strong></td></tr><tr><td>APT-USD</td><td>1338</td><td>Aptos-based trading market.</td></tr><tr><td>BTC-USD</td><td>1339</td><td>Bitcoin-based trading market.</td></tr><tr><td>ETH-USD</td><td>1340</td><td>Ethereum-based trading market.</td></tr><tr><td>SOL-USD</td><td>2387</td><td>Solana-based trading market.</td></tr></tbody></table>

### Mainnet Supported Markets

<table data-header-hidden><thead><tr><th></th><th width="282"></th><th></th></tr></thead><tbody><tr><td><strong>Asset</strong></td><td><strong>Market ID</strong></td><td><strong>Description</strong></td></tr><tr><td>APT-USD</td><td>14</td><td>Aptos-based trading market.</td></tr><tr><td>BTC-USD</td><td>15</td><td>Bitcoin-based trading market.</td></tr><tr><td>ETH-USD</td><td>16</td><td>Ethereum-based trading market.</td></tr><tr><td>SOL-USD</td><td>31</td><td>Solana-based trading market.</td></tr></tbody></table>

**WebSocket URL:**

### ✅ <mark style="color:red;">**Testnet WebSocket URL**</mark>

```typescript
wss://perpetuals-indexer-ws-develop.kanalabs.io/ws/
```

### ✅ <mark style="color:red;">**Mainnet WebSocket URL**</mark>

```typescript
wss://perpetuals-indexer-ws.kana.trade/ws/
```

### **Important Note: Profile Address Required**

🔹 You **must** pass your **profile address** for WebSocket endpoints.\
🔹 To get your **profile address**, use the `/getProfileAddress` endpoint.

#### **Profile Address API:**

&#x20;**Endpoint:**

```
https://perps-tradeapi.kanalabs.io/getProfileAddress
```

**Example Request:**

```
https://perps-tradeapi.kanalabs.io/getProfileAddress?userAddress=0xd01e3a233632a41463bd6d289e99e69e1b50815c7afff710e1c992659a8722f3
```

&#x20;**Input Parameter:**

* `userAddress` (your wallet address)

&#x20;**Response Example:**

```typescript
{
  success: true,
  message: 'Profile address fetched successfully',
  data: '0x3c78886aa67752706b3502b12959edf92e68d85ae64b24226783d26ce6efc1e'
}
```

#### WebSocket Client Documentation

**Installation:**

1. **Install Dependencies**: You will need the `websocket-client` library. Install it using pip:

```python
pip install websocket-client
```

### 1. WebSocket Client for Subscribing to Position Updates

**WebSocket URL:**

```
wss://perpetuals-indexer-ws-develop.kanalabs.io/ws/
```

**Example Request:**

When you connect to the WebSocket server, the client will send a subscription message like this:

```json
{
  "topic": "positions",
  "address": "0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770"
}
```

* **topic**: The topic to subscribe to, which is `positions` in this case.
* **address**: The address to track for position updates.

**Example Response:**

After subscribing, you will receive position updates as a response from the server. The response might look like this:

{% code fullWidth="false" %}

```json
[client] Connected to the server
[client] Sent subscription request: {"topic": "positions", "address": "0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770"}
[client] Received message: {"data":[{"address":"0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770","entry_price":"6050","is_long":false,"last_updated":"1739788459","leverage":2,"liq_price":"8853.658536585366","margin":"3025000","market_id":"396","size":"1000","sl":null,"tp":null,"trade_id":"16509835945970048696716","value":"6050000"}],"message":"positions"}
```

{% endcode %}

#### Example Code to Connect to the WebSocket and Subscribe:

Here’s a Python script that demonstrates how to connect to the WebSocket server and subscribe to position updates for a specific address.

```python
import websocket
import json
import time
import threading

# WebSocket server URL
WS_URL = 'wss://perpetuals-indexer-ws-develop.kanalabs.io/ws/'

# Address to subscribe to
address = 'your_address'

# Global WebSocket variable
ws = None

# WebSocket event handlers
def on_open(ws):
    print('[client] Connected to the server')
    
    # Send subscription message to the WebSocket server
    subscription_message = json.dumps({
        'topic': 'positions',
        'address': address,
    })
    ws.send(subscription_message)
    print(f'[client] Sent subscription request: {subscription_message}')

    # Start ping thread to keep the connection alive
    start_ping_thread(ws)

def ping(ws):
    while ws.sock and ws.sock.connected:
        time.sleep(20)  # Send ping every 20 seconds
        try:
            ws.sock.ping()
            print('[client] Sent ping to keep connection alive')
        except Exception as e:
            print(f'[client] Error sending ping: {e}')
            break

def start_ping_thread(ws):
    ping_thread = threading.Thread(target=ping, args=(ws,))
    ping_thread.daemon = True
    ping_thread.start()

def on_message(ws, message):
    print(f'[client] Received message: {message}')

def on_pong(ws, message):
    print('[client] Received pong response')

def on_close(ws, close_status_code, close_msg):
    print('[client] Disconnected from the server')
    reconnect_websocket()

def on_error(ws, error):
    print(f'[client] WebSocket error: {error}')
    ws.close()

# WebSocket connection setup
def connect_websocket():
    global ws
    ws = websocket.WebSocketApp(WS_URL,
                                on_open=on_open,
                                on_message=on_message,
                                on_pong=on_pong,
                                on_close=on_close,
                                on_error=on_error)

    # Run the WebSocket connection
    ws.run_forever()

# Reconnect logic
def reconnect_websocket():
    print('[client] Attempting to reconnect...')
    time.sleep(5)
    connect_websocket()

# Start WebSocket connection
if __name__ == "__main__":
    connect_websocket()
```

### 2. WebSocket Client for Subscribing to Order Fills Updates

**WebSocket URL:**

```
wss://perpetuals-indexer-ws-develop.kanalabs.io/ws/
```

**Example Request:**

When you connect to the WebSocket server, the client will send a subscription message like this:

```json
{
  "topic": "trade_history",
  "address": "0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770"
}
```

* **topic**: The topic to subscribe to, which is trade\_history in this case.
* **address**: The address to track for order fills updates.

**Example Response:**

After subscribing, you will receive order fills updates as a response from the server. The response might look like this:

{% code fullWidth="false" %}

```json
[client] Connected to the server
[client] Sent subscription request: {"topic": "trade_history", "address": "0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770"}
[client] Received message: {"data":[{"address":"0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770","fee":"3025","last_updated":"1739788459","market_id":"396","order_type":2,"pnl":"0","price":"6050","size":"1000","timestamp":"1739788459","trade_id":"16509835945970048696716"},"message":"trade_history"}
```

{% endcode %}

#### Example Code to Connect to the WebSocket and Subscribe:

Here’s a Python script that demonstrates how to connect to the WebSocket server and subscribe to order fills updates for a specific address.

```python
import websocket
import json
import time
import threading

# WebSocket server URL
WS_URL = 'wss://perpetuals-indexer-ws-develop.kanalabs.io/ws/'

# Address to subscribe to
address = 'your_address'

# Global WebSocket variable
ws = None

# WebSocket event handlers
def on_open(ws):
    print('[client] Connected to the server')
    
    # Send subscription message to the WebSocket server
    subscription_message = json.dumps({
        'topic': 'trade_history',
        'address': address,
    })
    ws.send(subscription_message)
    print(f'[client] Sent subscription request: {subscription_message}')

    # Start ping thread to keep the connection alive
    start_ping_thread(ws)

def ping(ws):
    while ws.sock and ws.sock.connected:
        time.sleep(20)  # Send ping every 20 seconds
        try:
            ws.sock.ping()
            print('[client] Sent ping to keep connection alive')
        except Exception as e:
            print(f'[client] Error sending ping: {e}')
            break

def start_ping_thread(ws):
    ping_thread = threading.Thread(target=ping, args=(ws,))
    ping_thread.daemon = True
    ping_thread.start()

def on_message(ws, message):
    print(f'[client] Received message: {message}')

def on_pong(ws, message):
    print('[client] Received pong response')

def on_close(ws, close_status_code, close_msg):
    print('[client] Disconnected from the server')
    reconnect_websocket()

def on_error(ws, error):
    print(f'[client] WebSocket error: {error}')
    ws.close()

# WebSocket connection setup
def connect_websocket():
    global ws
    ws = websocket.WebSocketApp(WS_URL,
                                on_open=on_open,
                                on_message=on_message,
                                on_pong=on_pong,
                                on_close=on_close,
                                on_error=on_error)

    # Run the WebSocket connection
    ws.run_forever()

# Reconnect logic
def reconnect_websocket():
    print('[client] Attempting to reconnect...')
    time.sleep(5)
    connect_websocket()

# Start WebSocket connection
if __name__ == "__main__":
    connect_websocket()
```

### 3. WebSocket Client for Subscribing to Open Orders Updates

**WebSocket URL:**

```
wss://perpetuals-indexer-ws-develop.kanalabs.io/ws/
```

**Example Request:**

When you connect to the WebSocket server, the client will send a subscription message like this:

```json
{
  "topic": "open_orders",
  "address": "0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770"
}
```

* **topic**: The topic to subscribe to, which is open\_orders in this case.
* **address**: The address to track for open orders updates.

**Example Response:**

After subscribing, you will receive open orders updates as a response from the server. The response might look like this:

{% code fullWidth="false" %}

```json
[client] Connected to the server
[client] Sent subscription request: {"topic": "open_orders", "address": "0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770"}
[client] Received message: {"data":[],"message":"open_orders"}
[client] Received message: {"data":[{"address":"0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770","last_updated":"1739790733","leverage":2,"market_id":"396","order_id":"12907057702855018828273522","order_type":1,"order_value":"6002000","price":"6002","remaining_size":"1000","timestamp":"1739790733","total_size":"1000","trade_id":"16528282690043758248332"}],"message":"open_orders"}
```

{% endcode %}

#### Example Code to Connect to the WebSocket and Subscribe:

Here’s a Python script that demonstrates how to connect to the WebSocket server and subscribe to open orders updates for a specific address.

```python
import websocket
import json
import time
import threading

# WebSocket server URL
WS_URL = 'wss://perpetuals-indexer-ws-develop.kanalabs.io/ws/'

# Address to subscribe to
address = 'your_address'

# Global WebSocket variable
ws = None

# WebSocket event handlers
def on_open(ws):
    print('[client] Connected to the server')
    
    # Send subscription message to the WebSocket server
    subscription_message = json.dumps({
        'topic': 'open_orders',
        'address': address,
    })
    ws.send(subscription_message)
    print(f'[client] Sent subscription request: {subscription_message}')

    # Start ping thread to keep the connection alive
    start_ping_thread(ws)

def ping(ws):
    while ws.sock and ws.sock.connected:
        time.sleep(20)  # Send ping every 20 seconds
        try:
            ws.sock.ping()
            print('[client] Sent ping to keep connection alive')
        except Exception as e:
            print(f'[client] Error sending ping: {e}')
            break

def start_ping_thread(ws):
    ping_thread = threading.Thread(target=ping, args=(ws,))
    ping_thread.daemon = True
    ping_thread.start()

def on_message(ws, message):
    print(f'[client] Received message: {message}')

def on_pong(ws, message):
    print('[client] Received pong response')

def on_close(ws, close_status_code, close_msg):
    print('[client] Disconnected from the server')
    reconnect_websocket()

def on_error(ws, error):
    print(f'[client] WebSocket error: {error}')
    ws.close()

# WebSocket connection setup
def connect_websocket():
    global ws
    ws = websocket.WebSocketApp(WS_URL,
                                on_open=on_open,
                                on_message=on_message,
                                on_pong=on_pong,
                                on_close=on_close,
                                on_error=on_error)

    # Run the WebSocket connection
    ws.run_forever()

# Reconnect logic
def reconnect_websocket():
    print('[client] Attempting to reconnect...')
    time.sleep(5)
    connect_websocket()

# Start WebSocket connection
if __name__ == "__main__":
    connect_websocket()
```

### 4. WebSocket Client for Subscribing to Order history Updates

**WebSocket URL:**

```
wss://perpetuals-indexer-ws-develop.kanalabs.io/ws/
```

**Example Request:**

When you connect to the WebSocket server, the client will send a subscription message like this:

```json
{
  "topic": "order_history",
  "address": "0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770"
}
```

* **topic**: The topic to subscribe to, which is order\_history in this case.
* **address**: The address to track for order history updates.

**Example Response:**

After subscribing, you will receive order history updates as a response from the server. The response might look like this:

{% code fullWidth="false" %}

```json
[client] Connected to the server
[client] Sent subscription request: {"topic": "order_history", "address": "0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770"}
[client] Received message: {"data":[{"address":"0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770","is_market_order":false,"last_updated":"1739790733","leverage":2,"market_id":"396","order_id":"12907057702855018828273522","order_type":1,"order_value":"6002000","price":"6002","size":"1000","status":"Open","timestamp":"1739790733","trade_id":"16528282690043758248332"},{"address":"0x4d6dc68e391e86991e58ab4d548b7e92872430d1f51bc666fe0c206bad7ff770","is_market_order":false,"last_updated":"1739790700","leverage":2,"market_id":"396","order_id":"12906965467445688751095808","order_type":4,"order_value":"6002000","price":"6002","size":"1000","status":"Filled","timestamp":"1739790700","trade_id":"16509835945970048696716"}],"message":"order_history"}
```

{% endcode %}

#### Example Code to Connect to the WebSocket and Subscribe:

Here’s a Python script that demonstrates how to connect to the WebSocket server and subscribe to order history updates for a specific address.

```python
import websocket
import json
import time
import threading

# WebSocket server URL
WS_URL = 'wss://perpetuals-indexer-ws-develop.kanalabs.io/ws/'

# Address to subscribe to
address = 'your_address'

# Global WebSocket variable
ws = None

# WebSocket event handlers
def on_open(ws):
    print('[client] Connected to the server')
    
    # Send subscription message to the WebSocket server
    subscription_message = json.dumps({
        'topic': 'order_history',
        'address': address,
    })
    ws.send(subscription_message)
    print(f'[client] Sent subscription request: {subscription_message}')

    # Start ping thread to keep the connection alive
    start_ping_thread(ws)

def ping(ws):
    while ws.sock and ws.sock.connected:
        time.sleep(20)  # Send ping every 20 seconds
        try:
            ws.sock.ping()
            print('[client] Sent ping to keep connection alive')
        except Exception as e:
            print(f'[client] Error sending ping: {e}')
            break

def start_ping_thread(ws):
    ping_thread = threading.Thread(target=ping, args=(ws,))
    ping_thread.daemon = True
    ping_thread.start()

def on_message(ws, message):
    print(f'[client] Received message: {message}')

def on_pong(ws, message):
    print('[client] Received pong response')

def on_close(ws, close_status_code, close_msg):
    print('[client] Disconnected from the server')
    reconnect_websocket()

def on_error(ws, error):
    print(f'[client] WebSocket error: {error}')
    ws.close()

# WebSocket connection setup
def connect_websocket():
    global ws
    ws = websocket.WebSocketApp(WS_URL,
                                on_open=on_open,
                                on_message=on_message,
                                on_pong=on_pong,
                                on_close=on_close,
                                on_error=on_error)

    # Run the WebSocket connection
    ws.run_forever()

# Reconnect logic
def reconnect_websocket():
    print('[client] Attempting to reconnect...')
    time.sleep(5)
    connect_websocket()

# Start WebSocket connection
if __name__ == "__main__":
    connect_websocket()
```

### 5. WebSocket Client for Subscribing to Order Book Updates

**WebSocket URL:**

```
wss://perpetuals-indexer-ws-develop.kanalabs.io/ws/
```

**Example Request:**

When you connect to the WebSocket server, the client will send a subscription message like this:

```json
{
  "topic": "orderbook",
  "market_id": "1338"
}
```

* **topic**: The topic to subscribe to, which is orderbook in this case.
* **address**: The address to track for order book updates.

**Example Response:**

After subscribing, you will receive order book updates as a response from the server. The response might look like this:

{% code fullWidth="false" %}

```json
[client] Connected to the server
[client] Sent subscription request: {"topic": "orderbook", "market_id": "1338"}
[client] Received message: {"data":[{"is_ask":true,"last_updated":"1739790988","market_id":"396","price":"6036","size":"169320"},{"is_ask":true,"last_updated":"1739790988","market_id":"396","price":"6037","size":"253735"},{"is_ask":true,"last_updated":"1739790988","market_id":"396","price":"6040","size":"230485"},{"is_ask":true,"last_updated":"1739790996","market_id":"396","price":"6044","size":"255685"},{"is_ask":true,"last_updated":"1739790996","market_id":"396","price":"6051","size":"264082"},{"is_ask":true,"last_updated":"1739790990","market_id":"396","price":"6053","size":"235088"},{"is_ask":true,"last_updated":"1739790996","market_id":"396","price":"6057","size":"230868"},{"is_ask":true,"last_updated":"1739790990","market_id":"396","price":"6059","size":"487477"},{"is_ask":true,"last_updated":"1739758360","market_id":"396","price":"8000","size":"500"},{"is_ask":false,"last_updated":"1739790988","market_id":"396","price":"6031","size":"174998"},{"is_ask":false,"last_updated":"1739790988","market_id":"396","price":"6027","size":"225183"},{"is_ask":false,"last_updated":"1739790988","market_id":"396","price":"6024","size":"244770"},{"is_ask":false,"last_updated":"1739790996","market_id":"396","price":"6019","size":"238312"},{"is_ask":false,"last_updated":"1739790987","market_id":"396","price":"6018","size":"260393"},{"is_ask":false,"last_updated":"1739790996","market_id":"396","price":"6014","size":"267821"},{"is_ask":false,"last_updated":"1739790996","market_id":"396","price":"6011","size":"234869"},{"is_ask":false,"last_updated":"1739790990","market_id":"396","price":"6006","size":"447877"},{"is_ask":false,"last_updated":"1739790990","market_id":"396","price":"6002","size":"1000"},{"is_ask":false,"last_updated":"1739779575","market_id":"396","price":"5800","size":"103303"}],"message":"orderbook"}
```

{% endcode %}

#### Example Code to Connect to the WebSocket and Subscribe:

Here’s a Python script that demonstrates how to connect to the WebSocket server and subscribe to order book updates for a specific address.

```python
import websocket
import json
import time
import threading

# WebSocket server URL
WS_URL = 'wss://perpetuals-indexer-ws-develop.kanalabs.io/ws/'

# Address to subscribe to
market_id= 'your_market_id'

# Global WebSocket variable
ws = None

# WebSocket event handlers
def on_open(ws):
    print('[client] Connected to the server')
    
    # Send subscription message to the WebSocket server
    subscription_message = json.dumps({
        'topic': 'orderbook',
        'market_id': market_id,
    })
    ws.send(subscription_message)
    print(f'[client] Sent subscription request: {subscription_message}')

    # Start ping thread to keep the connection alive
    start_ping_thread(ws)

def ping(ws):
    while ws.sock and ws.sock.connected:
        time.sleep(20)  # Send ping every 20 seconds
        try:
            ws.sock.ping()
            print('[client] Sent ping to keep connection alive')
        except Exception as e:
            print(f'[client] Error sending ping: {e}')
            break

def start_ping_thread(ws):
    ping_thread = threading.Thread(target=ping, args=(ws,))
    ping_thread.daemon = True
    ping_thread.start()

def on_message(ws, message):
    print(f'[client] Received message: {message}')

def on_pong(ws, message):
    print('[client] Received pong response')

def on_close(ws, close_status_code, close_msg):
    print('[client] Disconnected from the server')
    reconnect_websocket()

def on_error(ws, error):
    print(f'[client] WebSocket error: {error}')
    ws.close()

# WebSocket connection setup
def connect_websocket():
    global ws
    ws = websocket.WebSocketApp(WS_URL,
                                on_open=on_open,
                                on_message=on_message,
                                on_pong=on_pong,
                                on_close=on_close,
                                on_error=on_error)

    # Run the WebSocket connection
    ws.run_forever()

# Reconnect logic
def reconnect_websocket():
    print('[client] Attempting to reconnect...')
    time.sleep(5)
    connect_websocket()    

# Start WebSocket connection
if __name__ == "__main__":
    connect_websocket()
```

### 6. WebSocket Client for Subscribing to Recent Trades Updates

**WebSocket URL:**

```
wss://perpetuals-indexer-ws-develop.kanalabs.io/ws/
```

**Example Request:**

When you connect to the WebSocket server, the client will send a subscription message like this:

```json
{
  "topic": "recent_trades",
  "market_id": "1338"
}
```

* **topic**: The topic to subscribe to, which is recent\_trades in this case.
* **address**: The address to track for recent trades updates.

**Example Response:**

After subscribing, you will receive recent trades updates as a response from the server. The response might look like this:

{% code fullWidth="false" %}

```json
[client] Connected to the server
[client] Sent subscription request: {"topic": "recent_trades", "market_id": "1338"}
[client] Received message: {"data":[{"address":"0x73e73911c0771e4d58f17aea3d0c70980ca2bae32c665b37101d1a18f4ef60f1","fee":"0","last_updated":1746177751,"leverage":2,"market_id":"1338","order_type":1,"order_value":"65.393818","pnl":"0","price":"5.518","size":"11.851","timestamp":1746177750,"trade_id":"176590681017621537621306","transaction_version":6704413443},{"address":"0x85a0d7c3e1f5e243b80055b249d6e4cc4b2db5f599fa7a27b05850af8eccffdd","fee":"0.0326969090000000006806411505","last_updated":1746177751,"leverage":2,"market_id":"1338","order_type":7,"order_value":"65.393818","pnl":"-0.0682499090000000006806411505","price":"5.518","size":"11.851","timestamp":1746177750,"trade_id":"176609127761695247172922","transaction_version":6704413443}]}
```

{% endcode %}

#### Example Code to Connect to the WebSocket and Subscribe:

Here’s a Python script that demonstrates how to connect to the WebSocket server and subscribe to recent trades updates for a specific address.

```python
import websocket
import json
import time
import threading

# WebSocket server URL
WS_URL = 'wss://perpetuals-indexer-ws-develop.kanalabs.io/ws/'

# Address to subscribe to
market_id= '1338'

# Global WebSocket variable
ws = None

# WebSocket event handlers
def on_open(ws):
    print('[client] Connected to the server')
    
    # Send subscription message to the WebSocket server
    subscription_message = json.dumps({
        'topic': 'recent_trades',
        'market_id': market_id,
    })
    ws.send(subscription_message)
    print(f'[client] Sent subscription request: {subscription_message}')

    # Start ping thread to keep the connection alive
    start_ping_thread(ws)

def ping(ws):
    while ws.sock and ws.sock.connected:
        time.sleep(20)  # Send ping every 20 seconds
        try:
            ws.sock.ping()
            print('[client] Sent ping to keep connection alive')
        except Exception as e:
            print(f'[client] Error sending ping: {e}')
            break

def start_ping_thread(ws):
    ping_thread = threading.Thread(target=ping, args=(ws,))
    ping_thread.daemon = True
    ping_thread.start()

def on_message(ws, message):
    print(f'[client] Received message: {message}')

def on_pong(ws, message):
    print('[client] Received pong response')

def on_close(ws, close_status_code, close_msg):
    print('[client] Disconnected from the server')
    reconnect_websocket()

def on_error(ws, error):
    print(f'[client] WebSocket error: {error}')
    ws.close()

# WebSocket connection setup
def connect_websocket():
    global ws
    ws = websocket.WebSocketApp(WS_URL,
                                on_open=on_open,
                                on_message=on_message,
                                on_pong=on_pong,
                                on_close=on_close,
                                on_error=on_error)

    # Run the WebSocket connection
    ws.run_forever()

# Reconnect logic
def reconnect_websocket():
    print('[client] Attempting to reconnect...')
    time.sleep(5)
    connect_websocket()    

# Start WebSocket connection
if __name__ == "__main__":
    connect_websocket()
```

### 7. WebSocket Client for Subscribing to Live Funding Rate Updates

**WebSocket URL:**

```
wss://perpetuals-indexer-ws-develop.kanalabs.io/ws/
```

**Example Request:**

When you connect to the WebSocket server, the client will send a subscription message like this:

```json
{
  "topic": "live_funding_rate"
}
```

* **topic**: The topic to subscribe to, which is live\_funding\_rate in this case.

**Example Response:**

After subscribing, you will receive live funding rate updates as a response from the server. The response might look like this:

{% code fullWidth="false" %}

```json
[client] Connected to the server
[client] Sent subscription request: {"topic": "live_funding_rate"}
[client] Received message: {"data":[{"funding_rate":"0","funding_timestamp":0,"last_updated":1747382402,"market_id":"14","transaction_timestamp":1747382400,"transaction_version":2726355750},{"funding_rate":"0","funding_timestamp":0,"last_updated":1747382402,"market_id":"16","transaction_timestamp":1747382400,"transaction_version":2726355754},{"funding_rate":"0","funding_timestamp":0,"last_updated":1747382402,"market_id":"15","transaction_timestamp":1747382400,"transaction_version":2726355752}],"message":"live_funding_rate"}
```

{% endcode %}

#### Example Code to Connect to the WebSocket and Subscribe:

Here’s a Python script that demonstrates how to connect to the WebSocket server and subscribe to live funding rate updates for a specific address.

```python
import websocket
import json
import time
import threading

# WebSocket server URL
WS_URL = 'wss://perpetuals-indexer-ws.kana.trade/ws/'

# Global WebSocket variable
ws = None

# WebSocket event handlers
def on_open(ws):
    print('[client] Connected to the server')
    
    # Send subscription message to the WebSocket server
    subscription_message = json.dumps({
        'topic': 'live_funding_rate',
    })
    ws.send(subscription_message)
    print(f'[client] Sent subscription request: {subscription_message}')

    # Start ping thread to keep the connection alive
    start_ping_thread(ws)

def ping(ws):
    while ws.sock and ws.sock.connected:
        time.sleep(20)  # Send ping every 20 seconds
        try:
            ws.sock.ping()
            print('[client] Sent ping to keep connection alive')
        except Exception as e:
            print(f'[client] Error sending ping: {e}')
            break

def start_ping_thread(ws):
    ping_thread = threading.Thread(target=ping, args=(ws,))
    ping_thread.daemon = True
    ping_thread.start()

def on_message(ws, message):
    print(f'[client] Received message: {message}')

def on_pong(ws, message):
    print('[client] Received pong response')

def on_close(ws, close_status_code, close_msg):
    print('[client] Disconnected from the server')
    reconnect_websocket()

def on_error(ws, error):
    print(f'[client] WebSocket error: {error}')
    ws.close()

# WebSocket connection setup
def connect_websocket():
    global ws
    ws = websocket.WebSocketApp(WS_URL,
                                on_open=on_open,
                                on_message=on_message,
                                on_pong=on_pong,
                                on_close=on_close,
                                on_error=on_error)

    # Run the WebSocket connection
    ws.run_forever()

# Reconnect logic
def reconnect_websocket():
    print('[client] Attempting to reconnect...')
    time.sleep(5)
    connect_websocket()    

# Start WebSocket connection
if __name__ == "__main__":
    connect_websocket()
```
