головна сторінка

Початок роботи

SDK для Python і Rust

Офіційні SDK Seeryx для Python і Rust: ринкові дані, вхід через Solana, підписані ордери, поповнення й виведення з перевіркою перед підписом, потоки.

Огляд

Офіційні SDK обгортають API з цієї документації для Python і Rust, з однаковими поняттями й назвами в обох мовах. Їхній код відкритий за ліцензією MIT: github.com/Seeryx/seeryx-python і github.com/Seeryx/seeryx-rust.

  • Ринкові дані: ринки, поточні й минулі раунди, книги ордерів, угоди, обсяг, комісії, статистика, рейтинг, профілі та ринки подій — без акаунта.
  • Sign-In With Solana з ключовою парою вашого гаманця; коли строк дії токена спливає, SDK сам входить знову.
  • Торгівля: торгова сесія, відкрита одним підписом гаманця, далі лімітні, ринкові ордери й ордери «Лише мейкер», пакети до 15 ордерів, скасування, розділення й об’єднання — усе підписується на вашому комп’ютері.
  • Кошти: поповнення з гаманця, виведення на ваш власний гаманець і відкладене виведення; кожну транзакцію перевіряють перед підписом.
  • Реальний час: потоки WebSocket за раундом і вашим акаунтом, які самі перепідключаються.
  • Допоміжні функції: сітка цін, комісії, слаги й час раундів.

Установіть

Python 3.9 або новіший (блокувальний Client і асинхронний AsyncClient на asyncio з однаковими методами) або Rust 1.88 чи новіший (асинхронний, на tokio). Обидва встановлюються з GitHub:

# Python 3.9 or newer
pip install "git+https://github.com/Seeryx/seeryx-python"

Прочитайте дані ринку

Для ринкових даних акаунт не потрібен. Ціни вказано в центах; рівні книги ордерів — [ціна, частки], найкращі першими.

quickstart.py
"""The live BTC 5-minute round, its order book and its last trades. No account needed.

    python quickstart.py
"""
from seeryx import Client

with Client() as client:
    rnd = client.current_round("BTC", "5m")
    book = client.order_book(rnd["slug"], "up")  # levels are [cents, shares], best first
    trades = client.trades(rnd["slug"])

    bid = book["bids"][0][0] if book["bids"] else None
    ask = book["asks"][0][0] if book["asks"] else None
    print(rnd["slug"], "opened at", rnd["open"], "ends at", rnd["end"])
    print("Up bid", bid, "ask", ask, "chance of Up", f"{(bid + ask) / 2}%" if bid and ask else "no quotes yet")
    print("last trade", trades[0] if trades else "none yet")
    print("taker fee", client.fees()["rateBps"] / 100, "% of p x (1 - p) per share")

Увійдіть

Завантажте гаманець із файлу ключової пари Solana CLI або з секретного ключа в base58; він ніколи не залишає ваш процес. Перш ніж гаманець підпише текст входу, SDK перевіряє, що в ньому зазначено цей сайт, цей гаманець і щойно виданий nonce, а потім зберігає токен на 7 днів.

Якщо GET /api/funds повідомляє onChainTrading, один підпис гаманця відкриває торгову сесію; її ключ створюється на вашому комп’ютері й далі підписує кожен ордер. Якщо вказати шлях, сесію буде збережено (прочитати її можете лише ви) і використано під час наступного запуску; без шляху вона зберігається лише в пам’яті.

from seeryx import Client, Keypair

client = Client()  # https://seeryx.com
wallet = Keypair.from_file("wallet.json")  # a solana-keygen file; it never leaves this process
client.sign_in(wallet)  # checks the sign-in text, signs it, keeps the 7-day token
if client.funds().get("onChainTrading"):
    # one wallet signature; the session key then signs every order. Saved with mode 0600 and reused next time
    session = client.open_session(wallet, path="session.json")
    print("session key", session.address, "until", session.expires_at)

Розмістіть ордер

Ціни вказують у центах (з кроком 0,1¢, де ринок це дозволяє), розміри — у частках, суми — в USDC. SDK сам вибирає форму підпису (PMO2, PMO3 або PMO4), id ордера й строк дії; ринковому ордеру потрібен cap — найгірша ціна, яку ви приймаєте.

limit_order.py
"""Sign in, rest a small post-only buy below the market, list it, then cancel it.

    SEERYX_WALLET=~/.config/solana/id.json python limit_order.py
"""
import os

from seeryx import Client, Keypair

wallet = Keypair.from_file(os.path.expanduser(os.environ.get("SEERYX_WALLET", "wallet.json")))

with Client() as client:
    client.sign_in(wallet)
    if client.funds().get("onChainTrading"):
        # one wallet signature opens a trading session; its key then signs every order. Saved (mode 0600) so the
        # next run reuses it; leave out `path` to keep the key in memory only.
        client.open_session(wallet, path="session.json")

    rnd = client.current_round("BTC", "5m")
    book = client.order_book(rnd["slug"], "up")
    bid = book["bids"][0][0] if book["bids"] else 10
    limit = max(1, int(bid) - 5)  # 5c under the best bid: it rests in the book
    placed = client.buy(rnd["slug"], "up", shares=5, limit=limit, post_only=True)  # post_only: never trades at once
    print("resting order", placed["order"], "at", limit, "c")

    print("open orders", client.open_orders())
    if placed["order"]:
        print(client.cancel_order(placed["order"]))
market_buy.py
"""Spend up to $5 on Up now, paying at most 2c over the best ask. What the book cannot fill is dropped.

    SEERYX_WALLET=~/.config/solana/id.json python market_buy.py
"""
import os

from seeryx import Client, Keypair

wallet = Keypair.from_file(os.path.expanduser(os.environ.get("SEERYX_WALLET", "wallet.json")))

with Client() as client:
    client.sign_in(wallet)
    if client.funds().get("onChainTrading"):
        client.open_session(wallet, path="session.json")
    slug = client.current_round("BTC", "5m")["slug"]
    cap = client.market_cap(slug, "up", "buy", slippage=2)  # the worst price you accept, on the price grid
    result = client.market_buy(slug, "up", amount=5, cap=cap)
    print(result["status"], "filled", result["filled"], "shares for", result["spent"], "USDC, average", result.get("avgPrice"))

Оновлення в реальному часі

Потік стежить за одним раундом або ринком подій (обидві книги ордерів, угоди, обсяг), а після входу — і за вашим акаунтом. Він перепідключається зі зростанням затримки й підписується знову; коли раунд завершується, перейдіть на наступний у тому самому з’єднанні.

stream.py
"""Live books and trades of the BTC 5-minute rounds, and your account, over the WebSocket. Reconnects by itself.

    python stream.py                                           # market data only
    SEERYX_WALLET=~/.config/solana/id.json python stream.py    # and your account
"""
import asyncio
import os
import time

from seeryx import AsyncClient, Keypair


async def main() -> None:
    async with AsyncClient() as client:
        path = os.environ.get("SEERYX_WALLET")
        if path:
            await client.sign_in(Keypair.from_file(os.path.expanduser(path)))
        rnd = await client.current_round("BTC", "5m")
        async with client.stream(rnd["slug"], account=bool(path)) as stream:
            while True:
                # a message comes only when something changed: wait at most until the round ends
                message = await stream.next(timeout=max(1.0, rnd["end"] - time.time()))
                if message is None or time.time() >= rnd["end"]:
                    rnd = await client.current_round("BTC", "5m")  # follow the next round, same connection
                    await stream.watch_round(rnd["slug"])
                    continue
                if message["type"] == "round":
                    up = message["up"]
                    print(message["slug"], "bid", up["bids"][:1], "ask", up["asks"][:1], "volume", message["volume"])
                elif message["type"] == "account":
                    print("cash", message["balance"]["available"], "open orders", len(message["orders"]))
                else:
                    print("error", message["error"])


asyncio.run(main())

Поповніть і виведіть кошти

Біржа готує кожну транзакцію й сплачує її комісію мережі, тож SOL на гаманці не потрібен. SDK звіряє транзакцію саме з тим, що ви запросили, і нічого іншого не підписує. Виведення підписує ключ сесії, якщо ввімкнено sessionWithdraw (від 1 USDC і лише на ваш власний гаманець), інакше — ваш гаманець.

withdraw.py
"""Deposit USDC from your wallet, then withdraw some of it to the same wallet. The exchange pays every network fee:
the wallet needs no SOL. Every transaction is inspected before it is signed.

    SEERYX_WALLET=~/.config/solana/id.json python withdraw.py
"""
import os

from seeryx import Client, Keypair

wallet = Keypair.from_file(os.path.expanduser(os.environ.get("SEERYX_WALLET", "wallet.json")))

with Client(before_sign=lambda review: print("signing:", review.headline) or True) as client:
    client.sign_in(wallet)
    print("wallet", client.wallet_funds())  # USDC in the wallet; "account" is None until the first deposit

    print("deposit", client.deposit(wallet, 10))  # the first deposit is at least 1 USDC
    print("balance", client.balance())

    # signed by the trading session key when one is open and the server allows it, else by the wallet;
    # max_fee refuses a withdrawal fee above 1 USDC
    if client.funds().get("onChainTrading"):
        client.open_session(wallet, path="session.json")
    print("withdrawal", client.withdraw(4, wallet=wallet, max_fee=1))
    print("balance", client.balance())

Помилки й повторні спроби

Відмова надходить як помилка зі статусом, текстом сервера і його code; коди зі списку помилок мають власні типи. Відповіді 429 і 503 повторюються через час із Retry-After, а запити на запис зберігають свій Idempotency-Key під час кожної повторної спроби, тож нічого не розміщується двічі.

from seeryx import ApiError, BelowMinimum, WouldTake

try:
    client.buy(slug, "up", shares=5, limit=60, post_only=True)
except WouldTake:
    print("it would trade at once: post only refused it")
except BelowMinimum as e:
    print("the smallest order is", e.minimum, "shares")
except ApiError as e:
    print(e.status, e.code, e.message)  # 429 and 503 were already retried as Retry-After said

Ключі та перевірки

  • Ключ гаманця й ключ сесії ніколи не залишають ваш процес: надсилаються лише публічні ключі та підписи.
  • Кожну підготовлену транзакцію декодують, і вона має бути власною інструкцією програми Seeryx з вашими рахунками й вашими сумами: дозвіл на списання, переказ, інший підписант чи інша програма відхиляються.
  • На seeryx.com програму, мінт USDC і кластер Solana зафіксовано, хоч би що повідомляв сервер.
  • Нічого, що містить секрет, не виводиться й не потрапляє в журнали, а збережений файл сесії може читати лише його власник.

Приклади

В обох мовах однакові програми лежать у папках examples:

ПрикладЩо робить
quickstartПоточний 5-хвилинний раунд BTC, його книга ордерів і останні угоди — без акаунта
limit_orderВхід, купівля «Лише мейкер» нижче ринку в книзі ордерів, перегляд і скасування
market_buyВитратити до $5 одразу, заплативши не більше ніж на 2¢ вище найкращої ціни продажу
streamКниги ордерів, угоди й ваш акаунт у реальному часі через WebSocket
market_makerНевеликий цикл двосторонніх котирувань з ордерами «Лише мейкер» і об’єднаннями
withdrawПоповнення з гаманця й виведення назад на нього

Вихідний код, усі методи, тести й список змін: github.com/Seeryx/seeryx-python і github.com/Seeryx/seeryx-rust.