GaiaEx AcademyGaiaEx Academy
Handel z API GaiaEx: autoryzacja, zlecenia i dane rynkowe
DeweloperProgramowanie12 min read

Handel z API GaiaEx: autoryzacja, zlecenia i dane rynkowe

Połącz się z GaiaEx programistycznie i złóż swoją pierwszą automatyczną transakcję

Udostępnij posty

Przegląd API GaiaEx: REST + WebSocket na Hyperliquid L1

GaiaEx jest zdecentralizowaną giełdą zbudowaną na Hyperliquid L1, a jej API daje ci programistyczny dostęp do wszystkiego, co platforma oferuje — dane rynkowe, zarządzanie zleceniami, śledzenie pozycji i strumieniowanie w czasie rzeczywistym. Czy budujesz bota handlowego, dashboard portfela, czy niestandardowy system powiadomień, API jest twoim punktem wejścia.

API jest podzielone na dwa uzupełniające się protokoły:

  • REST API — Punkty dostępowe żądanie-odpowiedź do składania zleceń, zapytania o salda, pobierania historycznych transakcji i zarządzania kluczami API. Użyj REST, gdy musisz zrobić coś albo zapytać o coś konkretnego.
  • WebSocket API — Trwałe połączenia strumieniujące dla danych rynkowych w czasie rzeczywistym (transakcje, aktualizacje księgi zleceń, tickery) i prywatnych zdarzeń konta (wykonania zleceń, zmiany pozycji). Użyj WebSocket, gdy musisz zareagować na coś w momencie, gdy się dzieje.

Pod maską GaiaEx łączy się z księgą zleceń on-chain Hyperliquid L1. Twoje zlecenia są dopasowywane on-chain z deterministycznym wykonaniem, a twoje środki są zabezpieczone portfelami MPC (obliczenia wielostronne) — co znaczy, że żadna pojedyncza strona (nawet GaiaEx) nie posiada twojego kompletnego klucza prywatnego. API abstrahuje złożoność blockchaina: wysyłasz żądanie JSON, aby złożyć zlecenie, a platforma obsługuje podpisywanie, przesłanie i potwierdzenie na L1.

Bazowy URL dla REST API przestrzega standardowych konwencji: https://api.gaiaex.com/v1/. Połączenia WebSocket są ustanawiane na wss://api.gaiaex.com/ws/v1/. Wszystkie punkty dostępowe zwracają JSON, wszystkie znaczniki czasu są w milisekundach od epoki (UTC), a wszystkie wartości monetarne są ciągami znaków, aby unikać problemów z precyzją liczb zmiennoprzecinkowych.

REST vs WebSocket: kiedy używać którego REST (żądanie / odpowiedź) Składanie / anulowanie zleceń Salda, historia, odczyt REST Najlepsze dla akcji i zdjęć stanu WebSocket (strumień) Transakcje, księga, zdarzenia konta Aktualizacje push, niższe opóźnienie Najlepsze dla żywych strategii Boty zwykle łączą obie: WS na sygnały, REST na wykonanie i uzgadnianie.
Użyj strumieniowania dla ciągłego stanu rynku; użyj REST, gdy potrzebujesz dyskretnej komendy albo zdjęcia stanu.

Zarządzanie kluczami API i autoryzacja HMAC

Aby uzyskać dostęp do prywatnych punktów dostępowych (składanie zleceń, zapytanie o twoje salda), potrzebujesz parę kluczy API. Wygeneruj jedną z panelu GaiaEx pod Ustawienia → Klucze API. Otrzymasz dwie wartości:

  • Klucz API — Publiczny identyfikator wysyłany z każdym żądaniem. Myśl o nim jako o swojej nazwie użytkownika.
  • Sekret API — Klucz prywatny używany do podpisywania żądań. Nigdy go nie udostępniaj, nigdy nie zatwierdzaj go do kontroli wersji, nigdy nie wysyłaj go w nagłówku żądania.

GaiaEx używa podpisywania HMAC-SHA256 do autoryzacji prywatnych żądań. Proces: konkatenuj znacznik czasu, metodę HTTP, ścieżkę żądania i treść w jeden ciąg, następnie oblicz podpis HMAC używając swojego sekretu. Serwer wykonuje to samo obliczenie i porównuje podpisy.

import hmac, hashlib, time, requests, json

API_KEY = "your_api_key"
API_SECRET = "your_api_secret"
BASE_URL = "https://api.gaiaex.com/v1"

def signed_request(method, path, body=None):
    timestamp = str(int(time.time() * 1000))
    body_str = json.dumps(body) if body else ""
    message = timestamp + method.upper() + path + body_str
    signature = hmac.new(
        API_SECRET.encode(), message.encode(), hashlib.sha256
    ).hexdigest()

    headers = {
        "X-API-Key": API_KEY,
        "X-Timestamp": timestamp,
        "X-Signature": signature,
        "Content-Type": "application/json",
    }

    resp = requests.request(method, BASE_URL + path, headers=headers,
                            data=body_str if body else None)
    return resp.json()

Przechowuj swój sekret API w zmiennych środowiskowych albo menedżerze sekretów — nigdy nie hardkoduj go. Ustaw białą listę IP na swoim kluczu API w panelu, aby ograniczyć użycie do adresu IP twojego serwera. Jeśli twój klucz jest skompromitowany, odwołaj go natychmiast z panelu i wygeneruj nowy.

Komponent znacznika czasu zapobiega atakom powtórzenia (replay attacks): serwer odrzuca każde żądanie, gdzie znacznik czasu jest więcej niż 30 sekund od zegara serwera. Upewnij się, że zegar twojej maszyny jest zsynchronizowany przez NTP.

Podpisywanie żądania HMAC (koncepcyjnie) Klient sign(ts + method + path + body) HMAC-SHA256 z sekretem API GaiaEx weryfikuje Sekret nigdy nie podróżuje na przewodzie — tylko podpis + id klucza + znacznik czasu. Okno przesunięcia zegara blokuje nieświeże powtórzenia
Serwer przelicza skrót ponownie; niezgodność odrzuca wywołanie bez ujawnienia twojego sekretu.

Pobieranie danych rynkowych: księga zleceń, transakcje i tickery

Punkty dostępowe danych rynkowych są publiczne — bez wymaganej autoryzacji. Dostarczają surowe informacje, które potrzebujesz do podejmowania decyzji handlowych.

Księga zleceń — Zwraca bieżące bidy i aski dla danego symbolu. Parametr depth kontroluje, ile poziomów cenowych jest zwracanych (domyślnie 20, maksymalnie 100).

# Pobierz księgę zleceń BTC-USD (górne 10 poziomów)
resp = requests.get(f"{BASE_URL}/orderbook/BTC-USD?depth=10")
book = resp.json()

best_bid = book["bids"][0]  # [cena, wielkość]
best_ask = book["asks"][0]
spread = float(best_ask[0]) - float(best_bid[0])
print(f"Spread: ${spread:.2f}")

Ostatnie transakcje — Zwraca ostatnie N wykonanych transakcji dla symbolu. Każda transakcja zawiera cenę, wielkość, stronę (czy taker kupował czy sprzedawał) i znacznik czasu.

# Pobierz ostatnie 50 transakcji ETH-USD
resp = requests.get(f"{BASE_URL}/trades/ETH-USD?limit=50")
trades = resp.json()["trades"]
avg_price = sum(float(t["price"]) for t in trades) / len(trades)
print(f"Średnia z ostatnich 50 transakcji: ${avg_price:.2f}")

Ticker — Podsumowanie bieżącego stanu rynku: ostatnia cena, 24h high/low, 24h wolumen, najlepszy bid/ask, i procentowa zmiana. Idealne do budowania watchlist albo skanowania zmienności.

# Pobierz wszystkie tickery
resp = requests.get(f"{BASE_URL}/tickers")
for ticker in resp.json():
    if float(ticker["change24h"]) > 5.0:
        print(f"{ticker['symbol']}: +{ticker['change24h']}%")

Dla danych w czasie rzeczywistym używaj kanałów WebSocket zamiast odpytywania tych punktów dostępowych. Punkty dostępowe REST mają ograniczoną liczbę żądań i wprowadzają opóźnienie; WebSocket dostarcza aktualizacje w momencie, gdy zdarzają się na Hyperliquid L1.

Składanie zleceń: rynkowe, z limitem ceny i stop

Składanie zleceń jest podstawową akcją w każdym systemie handlowym. GaiaEx wspiera trzy typy zleceń przez punkt dostępowy POST /orders:

Zlecenie rynkowe — Wykonuje się natychmiast po najlepszej dostępnej cenie. Użyj, gdy szybkość wykonania ma większe znaczenie niż precyzja ceny.

# Kup 0,1 BTC po cenie rynkowej
order = signed_request("POST", "/orders", {
    "symbol": "BTC-USD",
    "side": "buy",
    "type": "market",
    "quantity": "0.1",
})
print(f"Wykonano po {order['avgPrice']}")

Zlecenie z limitem ceny — Wykonuje się tylko po twojej podanej cenie albo lepszej. Czeka w księdze zleceń, aż zostanie wykonane, anulowane albo wygaśnie.

# Sprzedaj 2 ETH po 3500 USD lub wyżej
order = signed_request("POST", "/orders", {
    "symbol": "ETH-USD",
    "side": "sell",
    "type": "limit",
    "price": "3500.00",
    "quantity": "2.0",
    "timeInForce": "GTC",  # Aktywne do odwołania
})

Zlecenie stop — Zlecenie warunkowe, które staje się aktywne, gdy rynek dosięgnie ceny wyzwalającej. Używane dla stop-lossów i wejść na wybicie.

# Stop-loss: sprzedaj 0,5 BTC, jeśli cena spadnie do 58 000 USD
order = signed_request("POST", "/orders", {
    "symbol": "BTC-USD",
    "side": "sell",
    "type": "stop_market",
    "stopPrice": "58000.00",
    "quantity": "0.5",
})

Aby zarządzać istniejącymi zleceniami: zapytaj o otwarte zlecenia z GET /orders?status=open, anuluj konkretne zlecenie z DELETE /orders/{orderId}, albo anuluj wszystkie otwarte zlecenia dla symbolu z DELETE /orders?symbol=BTC-USD. Do zarządzania pozycją, GET /positions zwraca wszystkie otwarte pozycje z ceną wejścia, wielkością, niezrealizowanym PnL i ceną likwidacji.

Strumieniowanie danych w czasie rzeczywistym przez WebSocket

API WebSocket GaiaEx używa modelu subskrybuj/wypisz się. Po połączeniu wysyłasz wiadomości subskrypcji określające, które kanały chcesz otrzymywać. Dostępne są zarówno kanały publiczne (dane rynkowe), jak i prywatne (zdarzenia konta) na tym samym połączeniu.

import asyncio, json, hmac, hashlib, time
import websockets

async def connect_gaiaex():
    uri = "wss://api.gaiaex.com/ws/v1"
    async with websockets.connect(uri) as ws:
        # Autoryzacja dla kanałów prywatnych
        ts = str(int(time.time() * 1000))
        sig = hmac.new(API_SECRET.encode(),
                       (ts + "websocket_auth").encode(),
                       hashlib.sha256).hexdigest()
        await ws.send(json.dumps({
            "method": "auth",
            "apiKey": API_KEY,
            "timestamp": ts,
            "signature": sig,
        }))

        # Subskrypcja kanałów publicznych + prywatnych
        await ws.send(json.dumps({
            "method": "subscribe",
            "channels": [
                "trades.BTC-USD",
                "orderbook.BTC-USD",
                "account.orders",
                "account.positions",
            ]
        }))

        async for msg in ws:
            data = json.loads(msg)
            ch = data.get("channel", "")
            if ch == "account.orders":
                print(f"Aktualizacja zlecenia: {data['status']} {data['orderId']}")
            elif ch == "trades.BTC-USD":
                print(f"Transakcja: {data['price']} x {data['quantity']}")

asyncio.run(connect_gaiaex())

Kanał account.orders wysyła aktualizacje, gdy jedno z twoich zleceń jest wykonane, częściowo wykonane albo anulowane — eliminując potrzebę odpytywania punktu dostępowego REST. Kanał account.positions strumieniuje aktualizacje PnL i marginu w czasie rzeczywistym. Połączone z publicznymi kanałami danych rynkowych, jedno połączenie WebSocket dostarcza wszystko, czego bot handlowy potrzebuje do działania.

Zawsze zaimplementuj mechanizm heartbeat: GaiaEx wysyła okresowe ramki ping, a twój klient musi odpowiadać ramkami pong. Jeśli żaden pong nie zostanie otrzymany w ciągu 30 sekund, serwer zamyka połączenie. Z twojej strony, jeśli żadne dane nie przychodzą przez 30 sekund, zakładaj, że połączenie jest martwe i połącz się ponownie.

Budowanie prostego bota handlowego: monitoruj, wykonuj, zarządzaj

Połączmy wszystko w minimalny, ale funkcjonalny bot handlowy. Bot monitoruje cenę BTC-USD przez WebSocket, a gdy cena spada poniżej celu, składa zlecenie kupna z limitem ceny. Gdy pozycja jest otwarta i cena wznosi się powyżej poziomu take-profit, zamyka pozycję.

import asyncio, json
import websockets

TARGET_BUY = 60000.0
TAKE_PROFIT = 63000.0
QUANTITY = "0.05"
position_open = False

async def trading_bot():
    global position_open
    uri = "wss://api.gaiaex.com/ws/v1"

    async with websockets.connect(uri) as ws:
        # Autoryzacja + subskrypcja (pominięte dla skrócenia)
        await ws.send(json.dumps({
            "method": "subscribe",
            "channels": ["trades.BTC-USD"]
        }))

        async for msg in ws:
            data = json.loads(msg)
            if data.get("channel") != "trades.BTC-USD":
                continue

            price = float(data["price"])

            if not position_open and price <= TARGET_BUY:
                order = signed_request("POST", "/orders", {
                    "symbol": "BTC-USD", "side": "buy",
                    "type": "limit", "price": str(TARGET_BUY),
                    "quantity": QUANTITY,
                })
                print(f"Zlecenie KUPNA złożone: {order['orderId']}")
                position_open = True

            elif position_open and price >= TAKE_PROFIT:
                order = signed_request("POST", "/orders", {
                    "symbol": "BTC-USD", "side": "sell",
                    "type": "market", "quantity": QUANTITY,
                })
                print(f"Zlecenie SPRZEDAŻY złożone: {order['orderId']}")
                position_open = False

asyncio.run(trading_bot())

To jest celowo proste. Produkcyjny bot dodałby: obsługę błędów z try/except wokół każdego wywołania API i automatycznym ponownym połączeniem; logikę ponownych prób z wykładniczym backoffem dla przejściowych awarii; śledzenie pozycji przez kanał WebSocket account.positions zamiast flagi boolean; limity ryzyka, które wstrzymują handel po maksymalnej dziennej stracie; i logowanie, które zapisuje każdą decyzję i odpowiedź API do analizy potransakcyjnej.

Architektura portfela MPC GaiaEx znaczy, że twój bot nigdy nie obsługuje surowych kluczy prywatnych — podpisywanie jest obsługiwane przez rozdzieloną infrastrukturę kluczy platformy. To redukuje powierzchnię bezpieczeństwa w porównaniu z botami, które zarządzają swoimi własnymi kluczami portfela, gdzie jedna kompromitacja może wysuszyć wszystkie środki. Połączone z białą listą IP kluczy API i warstwą autoryzacji HMAC, otrzymujesz obronę w głębi dla zautomatyzowanego handlu.

Zacznij mało: wdróż z minimalnym rozmiarem pozycji, monitoruj przez 48 godzin, zweryfikuj, że wykonania zgadzają się z oczekiwaniami, następnie skaluj postępowo. Najlepsze boty handlowe są budowane inkrementalnie, nie w jednym sprincie programowania.