Venue Setup
Configure trading venues using one of two setup models: Prepare+Confirm or User Credentials
XATA supports two venue configuration models depending on each venue's native delegation capabilities.
Model 1: Prepare + Confirm
Venues: Hyperliquid, HyENA, AsterDex, Paradex, GRVT
A two-step process: XATA generates a keypair, the user registers it in the venue's web UI, then confirms the setup. Your main wallet private key is never exposed to XATA.
Step 1: Prepare
POST /v2/account/venues/{venue}/prepareWhere {venue} is hyperliquid, hyena, aster, paradex, or grvt.
Request: Empty JSON body {}
Response:
{
"venue": "aster",
"wallet_address": "0x5555555555555555555555555555555555555555",
"status": "pending_user_action",
"instructions": "Go to https://www.asterdex.com/api-wallet and add 0x555... as API wallet"
}- For Hyperliquid / HyENA, the response includes
agent_name(derived from the first 10 characters of your API key). You'll use this name when approving the agent in the Hyperliquid UI. - For Paradex, the response returns
public_keyinstead ofwallet_address(Starknet keypair). - For GRVT, the response returns
signer_address.
Step 2: User Action
Follow the instructions in the response to register the generated address in the venue's web UI:
- Hyperliquid / HyENA: Go to https://app.hyperliquid.xyz/API, find "Approve Agent", enter the
agent_nameandwallet_address, and set an expiry - AsterDex: Go to the API wallet page and add the address
- Paradex: Go to Account Security → Key Management → Add New Subkey
- GRVT: Go to API Keys → Create → Input the signer address
Step 3: Confirm
POST /v2/account/venues/{venue}/confirmThe confirm request body varies by venue:
Hyperliquid / HyENA / AsterDex
{
"main_wallet_address": "0xYourMainWalletAddress..."
}Paradex
{}GRVT
GRVT requires additional credentials obtained during the UI setup:
{
"grvt_api_key": "grvt_live_abc123def456",
"sub_account_id": "sub_account_1"
}Confirm Response
{
"venue": "aster",
"status": "active",
"wallet_address": "0x5555555555555555555555555555555555555555"
}Venue-Specific Details
Hyperliquid / HyENA
- Uses EVM keypair; the generated address is approved as an "agent wallet" via the Hyperliquid API page
- Agent wallets have trade-only permissions — cannot withdraw or transfer (enforced by Hyperliquid protocol)
- The
agent_nameis derived from the first 10 characters of your API key - User controls the expiry when approving the agent in the UI
- Revocation: revoke the agent in the Hyperliquid UI or let it expire
AsterDex
- Uses EVM keypair; the generated address is added as an "API wallet" in the AsterDex UI
- Trading requests are signed with the API wallet private key using Keccak256 + ECDSA
- Revocation: remove the API wallet in the AsterDex UI
Paradex
- Uses Starknet keypair; the public key is registered as a "subkey"
- Subkeys can place/cancel orders and view balances but cannot withdraw, transfer, or manage other subkeys
- Revocation: remove the subkey in the Paradex UI
GRVT
- Uses EVM keypair as the "signer address"
- Requires a GRVT API key and sub-account ID (created in the GRVT UI alongside the signer)
- Trading uses EIP-712 signing
- Revocation: delete the API key in the GRVT UI
Python Example: Complete Hyperliquid Flow
import requests
api_key = "api_..."
headers = {
"x-api-key": api_key,
"Content-Type": "application/json",
}
# Step 1: Prepare
resp = requests.post(
"https://api.x.ata.network/v2/account/venues/hyperliquid/prepare",
headers=headers,
json={},
)
prepare_data = resp.json()
print(f"Generated wallet: {prepare_data['wallet_address']}")
print(f"Agent name: {prepare_data['agent_name']}")
print(f"Instructions: {prepare_data['instructions']}")
# Step 2: Approve agent in Hyperliquid UI (manual step)
# Go to https://app.hyperliquid.xyz/API and approve the agent wallet
input("Press Enter after approving the agent in Hyperliquid UI...")
# Step 3: Confirm
resp = requests.post(
"https://api.x.ata.network/v2/account/venues/hyperliquid/confirm",
headers=headers,
json={"main_wallet_address": "0xYourMainWalletAddress..."},
)
print(f"Status: {resp.json()['status']}")Model 2: User-Provided Credentials
Venues: Lighter, Kuru, Nado
Submit your venue-specific credentials directly. XATA encrypts them using AES-256-GCM and stores them securely.
Endpoint
POST /v2/account/venues/{venue}/credentialsWhere {venue} is lighter, kuru, or nado.
Lighter
{
"credentials": {
"api_key_private_key": "0xdeadbeef...",
"api_key_index": 2,
"account_index": 0,
"l1_address": "0x1234567890abcdef1234567890abcdef12345678"
}
}| Field | Type | Description |
|---|---|---|
api_key_private_key | string | Your Lighter API key private key |
api_key_index | integer | API key index (e.g., 2) |
account_index | integer | Account index (usually 0) |
l1_address | string | Your L1 wallet address |
Kuru
{
"credentials": {
"private_key": "0xdeadbeef..."
}
}| Field | Type | Description |
|---|---|---|
private_key | string | Your Kuru trading account private key |
Nado
{
"credentials": {
"private_key": "0xdeadbeef...",
"subaccount": "default"
}
}| Field | Type | Description |
|---|---|---|
private_key | string | Your Nado trading account private key |
subaccount | string | Subaccount name (e.g., "default") |
Response
{
"venue": "lighter",
"status": "active",
"account_address": "0x1234567890abcdef1234567890abcdef12345678"
}Credentials are encrypted before storage but you should treat them with the same care as private keys. Use environment variables or secrets vaults to manage them.
Python Example: Setup Lighter
import requests
api_key = "api_..."
headers = {
"x-api-key": api_key,
"Content-Type": "application/json",
}
resp = requests.post(
"https://api.x.ata.network/v2/account/venues/lighter/credentials",
headers=headers,
json={
"credentials": {
"api_key_private_key": "0x...",
"api_key_index": 2,
"account_index": 0,
"l1_address": "0x1234567890abcdef1234567890abcdef12345678",
}
},
)
if resp.status_code == 200:
print(f"Lighter setup complete: {resp.json()}")
else:
print(f"Error: {resp.status_code} — {resp.text}")