# Python

### Table of Contents

1. [Base URLs](#base-urls)
2. [Authentication](#authentication)
3. [Core Concepts](#core-concepts)
4. [Account Management](#account-management)
5. [Market Data](#market-data)
6. [Order Management](#order-management)
7. [Position Management](#position-management)
8. [Trade History](#trade-history)
9. [Utility Endpoints](#utility-endpoints)

### Base URLs

```markdown
BASE_URLS = {
    "TESTNET": "https://perps-tradeapi.kanalabs.io",
    "MAINNET": "https://perps-tradeapi.kana.trade"
}

NODE_URLS = {
    "TESTNET": "https://api.testnet.aptoslabs.com/v1",
    "MAINNET": "https://api.mainnet.aptoslabs.com/v1"
}
```

### Authentication

All endpoints require an API key in the request headers:

```python
import os
from dotenv import load_dotenv

load_dotenv()

headers = {"x-api-key": os.getenv("API_KEY")}
```

### Core Concepts

#### Profile Address

On-chain trades use a profile address rather than a wallet address. You can fetch it using the `/getProfileAddress` endpoint.

**Endpoint**: `GET /getProfileAddress`

```python
import requests

def get_profile_address(base_url, user_address):
    response = requests.get(
        f"{base_url}/getProfileAddress", 
        params={"userAddress": user_address}, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

### Account Management

#### Get Wallet Balance

Retrieves the wallet balance for a given user address.

**Endpoint**: `GET /getWalletAccountBalance`

```python
def get_wallet_balance(base_url, user_address):
    response = requests.get(
        f"{base_url}/getWalletAccountBalance", 
        params={"userAddress": user_address}, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

#### Get Profile Balance

Retrieves the profile balance snapshot for a given user address.

**Endpoint**: `GET /getProfileBalanceSnapshot`

```python
def get_profile_balance(base_url, user_address):
    response = requests.get(
        f"{base_url}/getProfileBalanceSnapshot", 
        params={"userAddress": user_address}, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

Get Net Profile Balance

This endpoint returns the net profile balance, which includes both the available balance in trading account and any pending balances from closed positions on all markets.

**Endpoint**: `GET /getNetProfileBalance`

```python
def get_net_profile_balance(base_url, user_address):
    response = requests.get(
        f"{base_url}/getNetProfileBalance", 
        params={"userAddress": user_address}, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

#### Deposit Funds

Deposits funds from wallet to trading profile.

**Endpoint**: `GET /deposit`

```python
import asyncio
from aptos_sdk.account import Account
from aptos_sdk.async_client import RestClient
from aptos_sdk.transactions import EntryFunction, TransactionPayload
from aptos_sdk.bcs import Serializer

async def deposit_funds(base_url, node_url, user_address, amount, private_key):
    response = requests.get(
        f"{base_url}/deposit", 
        params={"userAddress": user_address, "amount": amount}, 
        headers=headers
    )
    response.raise_for_status()
    payload = response.json()["data"]

    rest_client = RestClient(node_url)
    account = Account.load_key(bytes.fromhex(private_key.lstrip("0x")))
    
    payload["functionArguments"] = [user_address, int(payload["functionArguments"][1])]
    payload["argumentTypes"] = [Serializer.struct, Serializer.u64]
    
    module, function_id = payload["function"].split("::")[:-1], payload["function"].split("::")[-1]
    entry_function = EntryFunction.natural(
        "::".join(module), 
        function_id, 
        [], 
        [TransactionArgument(arg, serializer) for arg, serializer in zip(payload["functionArguments"], payload["argumentTypes"])]
    )
    
    transaction = await rest_client.create_bcs_signed_transaction(account, TransactionPayload(entry_function))
    txn_hash = await rest_client.submit_bcs_transaction(transaction)
    await rest_client.wait_for_transaction(txn_hash)
    return txn_hash
```

#### Withdraw Funds

Withdraws funds from trading profile to wallet for a specific market.

**Endpoint**: `GET /withdrawSpecifiMarket`

```python
async def withdraw_funds(base_url, node_url, user_address, market_id, amount, private_key):
    response = requests.get(
        f"{base_url}/withdrawSpecifiMarket", 
        params={"userAddress": user_address, "marketId": market_id, "amount": amount}, 
        headers=headers
    )
    response.raise_for_status()
    payload = response.json()["data"]

    rest_client = RestClient(node_url)
    account = Account.load_key(bytes.fromhex(private_key.lstrip("0x")))
    
    payload["functionArguments"] = [user_address, int(payload["functionArguments"][1]), int(payload["functionArguments"][2])]
    payload["argumentTypes"] = [Serializer.struct, Serializer.u64, Serializer.u64]
    
    module, function_id = payload["function"].split("::")[:-1], payload["function"].split("::")[-1]
    entry_function = EntryFunction.natural(
        "::".join(module), 
        function_id, 
        [], 
        [TransactionArgument(arg, serializer) for arg, serializer in zip(payload["functionArguments"], payload["argumentTypes"])]
    )
    
    transaction = await rest_client.create_bcs_signed_transaction(account, TransactionPayload(entry_function))
    txn_hash = await rest_client.submit_bcs_transaction(transaction)
    await rest_client.wait_for_transaction(txn_hash)
    return txn_hash
```

### Market Data

#### Get Market Info

Retrieves information about a specific market.

**Endpoint**: `GET /getMarketInfo`

```python
def get_market_info(base_url, market_id):
    response = requests.get(
        f"{base_url}/getMarketInfo", 
        params={"marketId": market_id}, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"][0]
```

#### Get Market Price

Gets the current price for a specific market.

**Endpoint**: `GET /getMarketPrice`

```python
def get_market_price(base_url, market_id):
    response = requests.get(
        f"{base_url}/getMarketPrice", 
        params={"marketId": market_id}, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

#### Get Last Execution Price

Retrieves the last execution price for a market.

**Endpoint**: `GET /getLastPlacedPrice`

```python
def get_last_execution_price(base_url, market_id):
    response = requests.get(
        f"{base_url}/getLastPlacedPrice", 
        params={"marketId": market_id}, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

#### Get Perpetual Market Info

Retrieves information about perpetual assets, optionally filtered by market ID or base name.

**Endpoint**: `GET /getPerpetualAssetsInfo`

```python
def get_perpetual_assets_info(base_url, market_id=None, base_name=None):
    params = {}
    if market_id:
        params["marketId"] = market_id
    if base_name:
        params["baseName"] = base_name
    response = requests.get(
        f"{base_url}/getPerpetualAssetsInfo", 
        params=params, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

#### Get All Markets

Retrieves information about all available markets.

**Endpoint**: `GET /getPerpetualAssetsInfo/allMarkets`

```python
def get_all_markets(base_url):
    response = requests.get(
        f"{base_url}/getPerpetualAssetsInfo/allMarkets", 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

### Order Management

#### Place Limit Order

Places a limit order on the exchange.

**Endpoint**: `GET /placeLimitOrder`

```python
async def place_limit_order(base_url, node_url, params, private_key):
    response = requests.get(
        f"{base_url}/placeLimitOrder", 
        params=params, 
        headers=headers
    )
    response.raise_for_status()
    payload = response.json()["data"]

    rest_client = RestClient(node_url)
    account = Account.load_key(bytes.fromhex(private_key.lstrip("0x")))
    
    payload["functionArguments"] = [
        int(payload["functionArguments"][0]),
        payload["functionArguments"][1].lower() == "true",
        payload["functionArguments"][2].lower() == "true",
        *map(int, payload["functionArguments"][3:])
    ]
    payload["argumentTypes"] = [
        Serializer.u64, Serializer.bool, Serializer.bool, 
        Serializer.u64, Serializer.u64, Serializer.u64, 
        Serializer.u8, Serializer.u64, Serializer.u64
    ]
    
    module, function_id = payload["function"].split("::")[:-1], payload["function"].split("::")[-1]
    entry_function = EntryFunction.natural(
        "::".join(module), 
        function_id, 
        [], 
        [TransactionArgument(arg, serializer) for arg, serializer in zip(payload["functionArguments"], payload["argumentTypes"])]
    )
    
    transaction = await rest_client.create_bcs_signed_transaction(account, TransactionPayload(entry_function))
    txn_hash = await rest_client.submit_bcs_transaction(transaction)
    await rest_client.wait_for_transaction(txn_hash)
    return txn_hash
```

#### Place Market Order

Places a market order on the exchange.

**Endpoint**: `GET /placeMarketOrder`

```python
async def place_market_order(base_url, node_url, params, private_key):
    response = requests.get(
        f"{base_url}/placeMarketOrder", 
        params=params, 
        headers=headers
    )
    response.raise_for_status()
    payload = response.json()["data"]

    rest_client = RestClient(node_url)
    account = Account.load_key(bytes.fromhex(private_key.lstrip("0x")))
    
    payload["functionArguments"] = [
        int(payload["functionArguments"][0]),
        payload["functionArguments"][1].lower() == "true",
        payload["functionArguments"][2].lower() == "true",
        *map(int, payload["functionArguments"][3:])
    ]
    payload["argumentTypes"] = [Serializer.u64, Serializer.bool, Serializer.bool] + [Serializer.u64] * (len(payload["functionArguments"]) - 3)
    
    module, function_id = payload["function"].split("::")[:-1], payload["function"].split("::")[-1]
    entry_function = EntryFunction.natural(
        "::".join(module), 
        function_id, 
        [], 
        [TransactionArgument(arg, serializer) for arg, serializer in zip(payload["functionArguments"], payload["argumentTypes"])]
    )
    
    transaction = await rest_client.create_bcs_signed_transaction(account, TransactionPayload(entry_function))
    txn_hash = await rest_client.submit_bcs_transaction(transaction)
    await rest_client.wait_for_transaction(txn_hash)
    return txn_hash
```

#### Place Multiple Orders

Places multiple orders in a single transaction.

**Endpoint**: `POST /placeMultipleOrders`

```python
async def place_multiple_orders(base_url, node_url, body, private_key):
    response = requests.post(
        f"{base_url}/placeMultipleOrders", 
        json=body, 
        headers=headers
    )
    response.raise_for_status()
    payload = response.json()["data"]

    rest_client = RestClient(node_url)
    account = Account.load_key(bytes.fromhex(private_key.lstrip("0x")))
    
    payload["argumentTypes"] = [
        Serializer.u64,
        Serializer.sequence_serializer(Serializer.bool),
        Serializer.sequence_serializer(Serializer.bool),
        Serializer.sequence_serializer(Serializer.bool),
        Serializer.sequence_serializer(Serializer.u64),
        Serializer.sequence_serializer(Serializer.u64),
        Serializer.sequence_serializer(Serializer.u64),
        Serializer.sequence_serializer(Serializer.u8),
        Serializer.sequence_serializer(Serializer.u64),
        Serializer.sequence_serializer(Serializer.u64)
    ]
    
    module, function_id = payload["function"].split("::")[:-1], payload["function"].split("::")[-1]
    entry_function = EntryFunction.natural(
        "::".join(module), 
        function_id, 
        [], 
        [TransactionArgument(arg, serializer) for arg, serializer in zip(payload["functionArguments"], payload["argumentTypes"])]
    )
    
    transaction = await rest_client.create_bcs_signed_transaction(account, TransactionPayload(entry_function))
    txn_hash = await rest_client.submit_bcs_transaction(transaction)
    await rest_client.wait_for_transaction(txn_hash)
    return txn_hash
```

#### Cancel Multiple Orders

Cancels multiple orders in a single transaction.

**Endpoint**: `POST /cancelMultipleOrders`

```python
async def cancel_multiple_orders(base_url, node_url, body, private_key):
    response = requests.post(
        f"{base_url}/cancelMultipleOrders", 
        json=body, 
        headers=headers
    )
    response.raise_for_status()
    payload = response.json()["data"]
    payload["functionArguments"][1] = [int(x) for x in payload["functionArguments"][1]]

    rest_client = RestClient(node_url)
    account = Account.load_key(bytes.fromhex(private_key.lstrip("0x")))
    
    payload["argumentTypes"] = [
        Serializer.u64,
        Serializer.sequence_serializer(Serializer.u128),
        Serializer.sequence_serializer(Serializer.bool)
    ]
    
    module, function_id = payload["function"].split("::")[:-1], payload["function"].split("::")[-1]
    entry_function = EntryFunction.natural(
        "::".join(module), 
        function_id, 
        [], 
        [TransactionArgument(arg, serializer) for arg, serializer in zip(payload["functionArguments"], payload["argumentTypes"])]
    )
    
    transaction = await rest_client.create_bcs_signed_transaction(account, TransactionPayload(entry_function))
    txn_hash = await rest_client.submit_bcs_transaction(transaction)
    await rest_client.wait_for_transaction(txn_hash)
    return txn_hash
```

#### Cancel and Place Multiple Orders

Cancels existing orders and places new ones in a single transaction.

**Endpoint**: `POST /cancelAndPlaceMultipleOrders`

```python
async def cancel_and_place_multiple_orders(base_url, node_url, body, private_key):
    response = requests.post(
        f"{base_url}/cancelAndPlaceMultipleOrders", 
        json=body, 
        headers=headers
    )
    response.raise_for_status()
    payload = response.json()["data"]
    payload["functionArguments"][1] = [int(x) for x in payload["functionArguments"][1]]

    rest_client = RestClient(node_url)
    account = Account.load_key(bytes.fromhex(private_key.lstrip("0x")))
    
    payload["argumentTypes"] = [
        Serializer.u64,
        Serializer.sequence_serializer(Serializer.u128),
        Serializer.sequence_serializer(Serializer.bool),
        Serializer.sequence_serializer(Serializer.bool),
        Serializer.sequence_serializer(Serializer.bool),
        Serializer.sequence_serializer(Serializer.bool),
        Serializer.sequence_serializer(Serializer.u64),
        Serializer.sequence_serializer(Serializer.u64),
        Serializer.sequence_serializer(Serializer.u64),
        Serializer.sequence_serializer(Serializer.u8),
        Serializer.sequence_serializer(Serializer.u64),
        Serializer.sequence_serializer(Serializer.u64)
    ]
    
    module, function_id = payload["function"].split("::")[:-1], payload["function"].split("::")[-1]
    entry_function = EntryFunction.natural(
        "::".join(module), 
        function_id, 
        [], 
        [TransactionArgument(arg, serializer) for arg, serializer in zip(payload["functionArguments"], payload["argumentTypes"])]
    )
    
    transaction = await rest_client.create_bcs_signed_transaction(account, TransactionPayload(entry_function))
    txn_hash = await rest_client.submit_bcs_transaction(transaction)
    await rest_client.wait_for_transaction(txn_hash)
    return txn_hash
```

### Position Management

#### Get Positions

Retrieves current positions for a user, optionally filtered by market ID.

**Endpoint**: `GET /getPositions`

```python
def get_positions(base_url, user_address, market_id=None):
    params = {"userAddress": user_address}
    if market_id:
        params["marketId"] = market_id
    response = requests.get(
        f"{base_url}/getPositions", 
        params=params, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

#### Update Take Profit

Updates the take profit price for a position.

**Endpoint**: `GET /updateTakeProfit`

```python
async def update_take_profit(base_url, node_url, market_id, trade_side, new_take_profit_price, private_key):
    params = {
        "marketId": market_id, 
        "tradeSide": trade_side, 
        "newTakeProfitPrice": new_take_profit_price
    }
    response = requests.get(
        f"{base_url}/updateTakeProfit", 
        params=params, 
        headers=headers
    )
    response.raise_for_status()
    payload = response.json()["data"]

    rest_client = RestClient(node_url)
    account = Account.load_key(bytes.fromhex(private_key.lstrip("0x")))
    
    payload["functionArguments"] = [
        int(payload["functionArguments"][0]),
        payload["functionArguments"][1].lower() == "true",
        int(payload["functionArguments"][2])
    ]
    payload["argumentTypes"] = [Serializer.u64, Serializer.bool, Serializer.u64]
    
    module, function_id = payload["function"].split("::")[:-1], payload["function"].split("::")[-1]
    entry_function = EntryFunction.natural(
        "::".join(module), 
        function_id, 
        [], 
        [TransactionArgument(arg, serializer) for arg, serializer in zip(payload["functionArguments"], payload["argumentTypes"])]
    )
    
    transaction = await rest_client.create_bcs_signed_transaction(account, TransactionPayload(entry_function))
    txn_hash = await rest_client.submit_bcs_transaction(transaction)
    await rest_client.wait_for_transaction(txn_hash)
    return txn_hash
```

#### Update Stop Loss

Updates the stop loss price for a position.

**Endpoint**: `GET /updateStopLoss`

```python
async def update_stop_loss(base_url, node_url, market_id, trade_side, new_stop_loss_price, private_key):
    params = {
        "marketId": market_id, 
        "tradeSide": trade_side, 
        "newStopLossPrice": new_stop_loss_price
    }
    response = requests.get(
        f"{base_url}/updateStopLoss", 
        params=params, 
        headers=headers
    )
    response.raise_for_status()
    payload = response.json()["data"]

    rest_client = RestClient(node_url)
    account = Account.load_key(bytes.fromhex(private_key.lstrip("0x")))
    
    payload["functionArguments"] = [
        int(payload["functionArguments"][0]),
        payload["functionArguments"][1].lower() == "true",
        int(payload["functionArguments"][2])
    ]
    payload["argumentTypes"] = [Serializer.u64, Serializer.bool, Serializer.u64]
    
    module, function_id = payload["function"].split("::")[:-1], payload["function"].split("::")[-1]
    entry_function = EntryFunction.natural(
        "::".join(module), 
        function_id, 
        [], 
        [TransactionArgument(arg, serializer) for arg, serializer in zip(payload["functionArguments"], payload["argumentTypes"])]
    )
    
    transaction = await rest_client.create_bcs_signed_transaction(account, TransactionPayload(entry_function))
    txn_hash = await rest_client.submit_bcs_transaction(transaction)
    await rest_client.wait_for_transaction(txn_hash)
    return txn_hash
```

#### Collapse Position

Closes a position immediately at market price.

**Endpoint**: `GET /collapsePosition`

```python
async def collapse_position(base_url, node_url, market_id, private_key):
    response = requests.get(
        f"{base_url}/collapsePosition", 
        params={"marketId": market_id}, 
        headers=headers
    )
    response.raise_for_status()
    payload = response.json()["data"]

    rest_client = RestClient(node_url)
    account = Account.load_key(bytes.fromhex(private_key.lstrip("0x")))
    
    payload["functionArguments"] = [int(payload["functionArguments"][0])]
    payload["argumentTypes"] = [Serializer.u64]
    
    module, function_id = payload["function"].split("::")[:-1], payload["function"].split("::")[-1]
    entry_function = EntryFunction.natural(
        "::".join(module), 
        function_id, 
        [], 
        [TransactionArgument(arg, serializer) for arg, serializer in zip(payload["functionArguments"], payload["argumentTypes"])]
    )
    
    transaction = await rest_client.create_bcs_signed_transaction(account, TransactionPayload(entry_function))
    txn_hash = await rest_client.submit_bcs_transaction(transaction)
    await rest_client.wait_for_transaction(txn_hash)
    return txn_hash
```

### Trade History

#### Get Open Orders

Retrieves all open orders for a user, optionally filtered by market ID.

**Endpoint**: `GET /getOpenOrders`

```python
def get_open_orders(base_url, user_address, market_id=None):
    params = {"userAddress": user_address}
    if market_id:
        params["marketId"] = market_id
    response = requests.get(
        f"{base_url}/getOpenOrders", 
        params=params, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

Get All Open Order Ids

**Endpoint**: `GET /getAllOpenOrderIds`

```python
def get_all_open_order_ids(base_url, user_address, market_id=None):
    params = {"userAddress": user_address}
    if market_id:
        params["marketId"] = market_id
    response = requests.get(
        f"{base_url}/getAllOpenOrderIds", 
        params=params, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

Get Order Status By Order Id

**Endpoint**: `GET /getOrderStatusByOrderId`

```typescript
def get_order_status_by_order_id(base_url, market_id, order_id):
    params = {"marketId": market_id, "orderId": order_id}
    response = requests.get(
        f"{base_url}/getOrderStatusByOrderId", 
        params=params, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

#### Get Order History

Retrieves order history for a user, optionally filtered by market ID.

**Endpoint**: `GET /getOrderHistory`

```python
def get_order_history(base_url, user_address, market_id=None):
    params = {"userAddress": user_address}
    if market_id:
        params["marketId"] = market_id
    response = requests.get(
        f"{base_url}/getOrderHistory", 
        params=params, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

#### Get All Trades

Retrieves all trades for a specific market.

**Endpoint**: `GET /getAllTrades`

```python
def get_all_trades(base_url, market_id):
    response = requests.get(
        f"{base_url}/getAllTrades", 
        params={"marketId": market_id}, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

#### Get Fills

Retrieves fill history for a specific market and address within a time range.

**Endpoint**: `GET /getFills`

```python
def get_fills(base_url, market_id, address, from_time, to_time, order_id=None):
    params = {
        "marketId": market_id, 
        "address": address, 
        "from": from_time, 
        "to": to_time
    }
    if order_id:
        params["orderId"] = order_id
    response = requests.get(
        f"{base_url}/getFills", 
        params=params, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

#### Get Order Status by Order ID

Retrieves the status of a specific order by its ID.

**Endpoint**: `GET /getOrderStatusByOrderId`

```python
def get_order_status_by_order_id(base_url, market_id, order_id):
    response = requests.get(
        f"{base_url}/getOrderStatusByOrderId", 
        params={"marketId": market_id, "orderId": order_id}, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

#### Get All Open Order IDs

**Endpoint**: `GET /getAllOpenOrderIds`

```python
def get_all_open_order_ids(base_url, user_address, market_id=None):
    params = {"userAddress": user_address}
    if market_id:
        params["marketId"] = market_id
    response = requests.get(
        f"{base_url}/getAllOpenOrderIds", 
        params=params, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

Retrieves all open order IDs for a user, optionally filtered by market ID.

#### Add Margin

**Endpoint**: `GET /addMargin`

```python
async def add_margin(base_url, node_url, market_id, trade_side, amount, private_key):
    params = {
        "marketId": market_id, 
        "tradeSide": trade_side, 
        "amount": amount
    }
    response = requests.get(
        f"{base_url}/addMargin", 
        params=params, 
        headers=headers
    )
    response.raise_for_status()
    payload = response.json()["data"]

    rest_client = RestClient(node_url)
    account = Account.load_key(bytes.fromhex(private_key.lstrip("0x")))
    
    payload["functionArguments"] = [
        int(payload["functionArguments"][0]),
        payload["functionArguments"][1].lower() == "true",
        int(payload["functionArguments"][2])
    ]
    payload["argumentTypes"] = [Serializer.u64, Serializer.bool, Serializer.u64]
    
    module, function_id = payload["function"].split("::")[:-1], payload["function"].split("::")[-1]
    entry_function = EntryFunction.natural(
        "::".join(module), 
        function_id, 
        [], 
        [TransactionArgument(arg, serializer) for arg, serializer in zip(payload["functionArguments"], payload["argumentTypes"])]
    )
    
    transaction = await rest_client.create_bcs_signed_transaction(account, TransactionPayload(entry_function))
    txn_hash = await rest_client.submit_bcs_transaction(transaction)
    await rest_client.wait_for_transaction(txn_hash)
    return txn_hash
```

**Settle Pnl**

This API returns a transaction payload used to manually (or automatically, on user interactions) refresh the user's position and settle the Pnl for a specific market, allowing the user to claim any unreleased Pnl.

**Endpoint**: `GET /settlePnl`

```python
async def settle_pnl(base_url, node_url, user_address, market_id, private_key):
    response = requests.get(
        f"{base_url}/settlePnl", 
        params={"userAddress": user_address, "marketId": market_id}, 
        headers=headers
    )
    response.raise_for_status()
    payload = response.json()["data"]

    rest_client = RestClient(node_url)
    account = Account.load_key(bytes.fromhex(private_key.lstrip("0x")))
    
    payload["functionArguments"] = [user_address, int(payload["functionArguments"][1])]
    payload["argumentTypes"] = [Serializer.struct, Serializer.u64]
    
    module, function_id = payload["function"].split("::")[:-1], payload["function"].split("::")[-1]
    entry_function = EntryFunction.natural(
        "::".join(module), 
        function_id, 
        [], 
        [TransactionArgument(arg, serializer) for arg, serializer in zip(payload["functionArguments"], payload["argumentTypes"])]
    )
    
    transaction = await rest_client.create_bcs_signed_transaction(account, TransactionPayload(entry_function))
    txn_hash = await rest_client.submit_bcs_transaction(transaction)
    await rest_client.wait_for_transaction(txn_hash)
    return txn_hash
```

### Utility Endpoints

#### Get Account APT Balance

Retrieves the APT balance for a user's account.

**Endpoint**: `GET /getAccountAptBalance`

```python
def get_account_apt_balance(base_url, user_address):
    response = requests.get(
        f"{base_url}/getAccountAptBalance", 
        params={"userAddress": user_address}, 
        headers=headers
    )
    response.raise_for_status()
    return response.json()["data"]
```

#### Helper Types

```python
# Order type constants
ORDER_TYPES = {
    "OPEN_LONG": 1,
    "OPEN_SHORT": 2,
    "INCREASE_LONG": 3,
    "INCREASE_SHORT": 4,
    "DECREASE_LONG": 5,
    "DECREASE_SHORT": 6,
    "CLOSE_LONG": 7,
    "CLOSE_SHORT": 8
}

# Order restriction types
RESTRICTION_TYPES = {
    "NO_RESTRICTION": 0,
    "FILL_OR_ABORT": 1,
    "POST_OR_ABORT": 3
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.kanalabs.io/perpetual-futures/kana-perps/for-developers-and-mms/integrating-rest-apis/python.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
