> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tplus.cx/llms.txt
> Use this file to discover all available pages before exploring further.

# First Python client

> Install tpluspy, create a local key, authenticate, discover markets, and simulate safely.

This first-run path is read-only plus simulation. It does not place live orders or send onchain transactions.

Production URLs:

```text theme={null}
OMS: https://oms.tplus.cx
MDS: https://mds.tplus.cx
OMS WebSocket base: wss://oms.tplus.cx
MDS WebSocket base: wss://mds.tplus.cx
```

## Install

```bash theme={null}
pip install tpluspy
```

Use the optional EVM extra only when you need onchain deposit, withdrawal, or settlement helpers:

```bash theme={null}
pip install "tpluspy[evm]"
```

## Create a local user

"Create user" means local Ed25519 key generation. There is no registration call. The first server-side account state is created by the first onchain deposit.

```python theme={null}
from tplus.utils.user import User

user = User()  # local throwaway Ed25519 keypair
print(user.public_key)
```

## Authenticate and read

```python theme={null}
import httpx

from tplus.client import OrderBookClient
from tplus.model.asset_identifier import AssetIdentifier
from tplus.model.orderbook import OrderBook

OMS = "https://oms.tplus.cx"
MDS = "https://mds.tplus.cx"

async with OrderBookClient(OMS, default_user=user) as oms:
    asset = AssetIdentifier(200)
    market = await oms.get_market(asset)

async with httpx.AsyncClient(base_url=MDS) as mds:
    depth_response = await mds.get(f"/marketdepth/{asset}")
    depth_response.raise_for_status()
    depth = OrderBook(**depth_response.json())
```

Raw auth is the same handshake:

```python theme={null}
# sign_nonce.py
import json
import sys

from tplus.utils.user import User

user = User(private_key="<ed25519-private-key-hex>")
print(json.dumps(list(user.sign(sys.argv[1]))))
```

```bash theme={null}
NONCE=$(curl -s https://oms.tplus.cx/nonce/$USER_ID | python3 -c 'import json,sys; print(json.load(sys.stdin)["value"])')
SIGNATURE=$(python3 sign_nonce.py "$NONCE")
curl -X POST https://oms.tplus.cx/auth \
  -H "Content-Type: application/json" \
  --data '{"user_id":"'$USER_ID'","nonce":"'$NONCE'","signature":'$SIGNATURE'}'
```

## Safe simulation

```python theme={null}
payload = {
    "sub_account": 1,
    "trade": {
        "asset": "200",
        "is_buy": True,
        "size": "1.0",
        "limit_price": "2500.0",
        "trade_type": "margin",
    },
    "pending_transfers": [],
}
result = await oms._request("POST", f"/account/simulate/{user.public_key}", json_data=payload)
print(result["is_solvent"], result["available_margin"])
```

Raw:

```bash theme={null}
curl -X POST https://oms.tplus.cx/account/simulate/$USER_ID \
  -H "Authorization: Bearer $TOKEN" \
  -H "User-Id: $USER_ID" \
  -H "Content-Type: application/json" \
  --data '{"sub_account":1,"trade":{"asset":"200","is_buy":true,"size":"1.0","limit_price":"2500.0","trade_type":"margin"},"pending_transfers":[]}'
```
