TypeScript SDK
Клієнт, стрім, пошук термінала й помилки пакета @spectre-trade/terminal.
Встановлення
npm install @spectre-trade/terminalTerminal
Клієнт одного запущеного термінала.
Створіть його з токеном або дозвольте Terminal.discover знайти порт
і токен та перевірити версію API. Усі методи async: вони кидають
ApiError на відповідь не 2xx і TerminalUnreachableError, коли
відповіді немає.
| Поле | Тип | Опис |
|---|---|---|
host | string | |
port | number | |
timeoutMs | number | |
baseUrl | string | http://127.0.0.1:48180/v1/ — токен до неї не входить. |
Terminal()
new Terminal(options: TerminalOptions)discover()
static discover(options: DiscoverOptions = {}): Promise<Terminal>Знайти термінал і перевірити його: токен — з options.token або
SPECTRE_LOCAL_API_TOKEN (інакше TokenMissingError), порт — з
options.port або instance.json (інакше 48180; LocalApiDisabledError,
коли файл каже, що API вимкнено), потім один GET /v1/meta.
api_version, відмінна від "1", — це IncompatibleTerminalError;
відповідь unauthorized — це ApiError, повідомлення якої каже, що
токен може бути застарілим або API вимкнено.
| Опції | Тип | Опис |
|---|---|---|
tokenнеобов’язковий | string | Має пріоритет над SPECTRE_LOCAL_API_TOKEN. |
portнеобов’язковий | number | Має пріоритет над instance.json. |
hostнеобов’язковий | string | |
timeoutMsнеобов’язковий | number | |
instancePathнеобов’язковий | string | Читати цей файл замість шляху instance.json, залежного від ОС (для тестів). |
meta()
meta(): Promise<Meta>GET /v1/meta: версія API, збірка, права токена, ліміти, топіки стріму.
Операція HTTP: GET /v1/meta
health()
health(): Promise<Health>GET /v1/health.
Операція HTTP: GET /v1/health
connections()
connections(): Promise<List<Connection>>GET /v1/connections (connections:read).
Операція HTTP: GET /v1/connections
connection()
connection(id: number): Promise<Connection>GET /v1/connections/{id} (connections:read); not_found для невідомого id.
Операція HTTP: GET /v1/connections/{id}
instruments()
instruments(options: InstrumentsOptions): Promise<InstrumentsPage>GET /v1/instruments (market:read): одна сторінка довідника біржі й
ринку, за connectionId або exchange + market. Ідіть за
next_cursor вручну або використовуйте iterInstruments.
Операція HTTP: GET /v1/instruments
| Опції | Тип | Опис |
|---|---|---|
connectionIdнеобов’язковий | number | |
exchangeнеобов’язковий | string | |
marketнеобов’язковий | string | |
qнеобов’язковий | string | Частина символу або базової монети, без урахування регістру. |
limitнеобов’язковий | number | 1–2000, типово 500. |
cursorнеобов’язковий | string | next_cursor попередньої сторінки. |
iterInstruments()
iterInstruments(options: InstrumentsOptions): AsyncGenerator<Instrument, void, undefined>Усі інструменти, що відповідають параметрам, сторінка за сторінкою.
| Опції | Тип | Опис |
|---|---|---|
connectionIdнеобов’язковий | number | |
exchangeнеобов’язковий | string | |
marketнеобов’язковий | string | |
qнеобов’язковий | string | Частина символу або базової монети, без урахування регістру. |
limitнеобов’язковий | number | 1–2000, типово 500. |
cursorнеобов’язковий | string | next_cursor попередньої сторінки. |
intervals()
intervals(): Promise<Intervals>GET /v1/market/intervals (market:read): інтервали свічок і кластерів.
Операція HTTP: GET /v1/market/intervals
candles()
candles(instrument: InstrumentAddress, options: CandlesOptions): Promise<Candles>GET /v1/market/candles (market:read): історія свічок, від старих до нових.
Операція HTTP: GET /v1/market/candles
| Опції | Тип | Опис |
|---|---|---|
interval | string | Код із /v1/market/intervals: 1m, 5m, … |
limitнеобов’язковий | number | До 2000, типово 500. |
endнеобов’язковий | number | Права межа, мілісекунди UTC; типово — зараз. |
connectionIdнеобов’язковий | number |
trades()
trades(instrument: InstrumentAddress, options: TradesOptions = {}): Promise<Trades>GET /v1/market/trades (market:read): останні угоди пари, від старих
до нових. Пара без підписки відкривається на вимогу, і виклик може
тривати до 3 с.
Операція HTTP: GET /v1/market/trades
| Опції | Тип | Опис |
|---|---|---|
limitнеобов’язковий | number | 1–1000 останніх, типово 100. |
sinceTsнеобов’язковий | number | Не раніше цього часу отримання, мілісекунди UTC. |
connectionIdнеобов’язковий | number |
snapshot()
snapshot(instrument: InstrumentAddress, options: ConnectionOptions = {}): Promise<Snapshot>GET /v1/market/snapshot (market:read): найкращі bid/ask, остання угода, ціна маркування, тікер.
Операція HTTP: GET /v1/market/snapshot
| Опції | Тип | Опис |
|---|---|---|
connectionIdнеобов’язковий | number |
orderbook()
orderbook(instrument: InstrumentAddress, options: OrderbookOptions = {}): Promise<Orderbook>GET /v1/market/orderbook (market:read); unavailable, якщо повний стакан не надійшов за 3 с.
Операція HTTP: GET /v1/market/orderbook
| Опції | Тип | Опис |
|---|---|---|
depthнеобов’язковий | number | 1–200, типово 50. |
connectionIdнеобов’язковий | number |
clusters()
clusters(instrument: InstrumentAddress, options: ConnectionOptions = {}): Promise<Clusters>GET /v1/market/clusters (market:read): до десяти бакетів за
інтервалом, вибраним у терміналі. Перший виклик для інструмента, не
відкритого у вікні, може відповісти not_active (409); повтор за кілька
секунд знаходить кластери.
Операція HTTP: GET /v1/market/clusters
| Опції | Тип | Опис |
|---|---|---|
connectionIdнеобов’язковий | number |
accountOrders()
accountOrders(connectionId: number): Promise<AccountOrders>GET /v1/account/orders (account:read): відкриті заявки й тригерні
заявки одного підключення, той самий зріз, який бачить вікно термінала.
not_found для невідомого підключення.
Операція HTTP: GET /v1/account/orders
accountPositions()
accountPositions(connectionId: number): Promise<AccountPositions>GET /v1/account/positions (account:read): відкриті позиції одного підключення.
Операція HTTP: GET /v1/account/positions
accountBalances()
accountBalances(connectionId: number): Promise<AccountBalances>GET /v1/account/balances (account:read): для кожної валюти — останнє
значення, яке біржа надіслала відтоді, як увімкнено API. Валюти, з якою
відтоді нічого не відбувалося, немає.
Операція HTTP: GET /v1/account/balances
accountFills()
accountFills(connectionId: number, options: AccountFillsOptions = {}): Promise<AccountFills>GET /v1/account/fills (account:read): виконання підключення відтоді,
як увімкнено API (остання тисяча), від старих до нових.
Операція HTTP: GET /v1/account/fills
| Опції | Тип | Опис |
|---|---|---|
limitнеобов’язковий | number | 1–1000 останніх, типово 100. |
sinceTsнеобов’язковий | number | Не раніше цього часу біржі, мілісекунди UTC. |
placeOrder()
placeOrder(options: PlaceOrderOptions): Promise<Accepted>POST /v1/orders (trading:write): поставити лімітну або ринкову заявку
тією самою командою, що й вікно. Відповідь означає «прийнято
терміналом», а не біржею: стежте за account.orders у стрімі або за
accountOrders, де заявка з’явиться під key. not_tradable (409) для
вимкненого підключення, підключення лише для читання або без облікових
даних, invalid_request (400) для чужого інструмента чи відхиленого
розміру або ціни, rate_limited (429) понад limits.commands_per_second.
Операція HTTP: POST /v1/orders
| Опції | Тип | Опис |
|---|---|---|
connectionId | number | Торгове підключення; типового немає. |
instrument | InstrumentAddress | |
side | Side | |
type | OrderType | limit потребує price, market ціни не приймає. |
priceнеобов’язковий | Decimal | |
sizeнеобов’язковий | Decimal | Кількість у базовій монеті; рівно одне з size і notional. |
notionalнеобов’язковий | Decimal | Сума у валюті котирування; рівно одне з size і notional. |
reduceOnlyнеобов’язковий | boolean | Типово false. |
postOnlyнеобов’язковий | boolean | Типово false. |
timeInForceнеобов’язковий | TimeInForce | Відсутній — типове значення біржі. |
clientKeyнеобов’язковий | string | Ключ ідемпотентності: повтор із тим самим ключем повертає попередню відповідь і не дублює заявку (термінал пам’ятає останню тисячу). |
cancelOrder()
cancelOrder(options: CancelOrderOptions): Promise<Accepted>DELETE /v1/orders/{id} (trading:write): скасувати одну заявку за
ключем термінала (t-…) або ідентифікатором біржі. Скасування йде на
біржу напряму; підтвердження надходить через стрім.
Операція HTTP: DELETE /v1/orders/{id}
| Опції | Тип | Опис |
|---|---|---|
connectionId | number | |
instrument | InstrumentAddress | |
orderId | string | Ключ термінала (t-…) або ідентифікатор заявки на біржі. |
cancelAll()
cancelAll(options: InstrumentCommandOptions): Promise<Accepted>POST /v1/orders/cancel-all (trading:write): скасувати всі заявки інструмента, як це робить пробіл.
Операція HTTP: POST /v1/orders/cancel-all
| Опції | Тип | Опис |
|---|---|---|
connectionId | number | |
instrument | InstrumentAddress |
closePosition()
closePosition(options: InstrumentCommandOptions): Promise<Accepted>POST /v1/positions/close (trading:write): закрити позицію інструмента
так, як це робить вікно — ринковою заявкою на розмір позиції на
ф’ючерсах, «скасувати все й закрити» однією атомарною командою на споті.
invalid_request без відкритої позиції.
Операція HTTP: POST /v1/positions/close
| Опції | Тип | Опис |
|---|---|---|
connectionId | number | |
instrument | InstrumentAddress |
placeTrigger()
placeTrigger(options: PlaceTriggerOptions): Promise<Accepted>POST /v1/orders/trigger (trading:write): стоп-лос, тейк-профіт або
стоп, поставлений тими самими сервісами, що й у вікні. stop_loss і
take_profit ставляться на відкриту позицію (сторона, розмір і правило
беруться з неї; без позиції — invalid_request); stop потребує side
і notional. key у відповіді — це ключ тригера (sl_…, tp_…,
stop_…), який з’являється як client_id тригера в accountOrders;
скасування і зміна використовують числовий id звідти. unsupported
(501) на біржі без тригерних заявок у терміналі.
Операція HTTP: POST /v1/orders/trigger
| Опції | Тип | Опис |
|---|---|---|
connectionId | number | |
instrument | InstrumentAddress | |
kind | TriggerType | stop_loss і take_profit ставляться на відкриту позицію; stop — окрема заявка. |
triggerPrice | Decimal | |
sideнеобов’язковий | Side | Лише для stop. |
notionalнеобов’язковий | Decimal | Лише для stop: сума у валюті котирування. |
ruleнеобов’язковий | TriggerRule | Лише для stop; без нього — вище ринку для купівлі, нижче для продажу. |
clientKeyнеобов’язковий | string | Ключ ідемпотентності, як у Terminal.placeOrder. |
cancelTrigger()
cancelTrigger(options: CancelTriggerOptions): Promise<Accepted>DELETE /v1/orders/trigger/{id} (trading:write): скасувати один тригер за його числовим id.
Операція HTTP: DELETE /v1/orders/trigger/{id}
| Опції | Тип | Опис |
|---|---|---|
connectionId | number | |
instrument | InstrumentAddress | |
triggerId | string | number | Числовий id тригера з accountOrders().triggers. |
cancelAllTriggers()
cancelAllTriggers(options: InstrumentCommandOptions): Promise<Accepted>POST /v1/orders/trigger/cancel-all (trading:write): скасувати всі тригери інструмента; звичайні заявки лишаються.
Операція HTTP: POST /v1/orders/trigger/cancel-all
| Опції | Тип | Опис |
|---|---|---|
connectionId | number | |
instrument | InstrumentAddress |
amendTrigger()
amendTrigger(options: AmendTriggerOptions): Promise<Accepted>PATCH /v1/orders/trigger/{id} (trading:write): перенести тригер на
нову ціну — послідовна заміна, як у вікні: скасувати, потім поставити.
kind обов’язковий; stop потребує ще й свого side. key дорівнює null.
Операція HTTP: PATCH /v1/orders/trigger/{id}
| Опції | Тип | Опис |
|---|---|---|
connectionId | number | |
instrument | InstrumentAddress | |
triggerId | string | number | Числовий id тригера з accountOrders().triggers. |
kind | TriggerType | |
triggerPrice | Decimal | |
sideнеобов’язковий | Side | Лише для stop. |
ruleнеобов’язковий | TriggerRule | Лише для stop. |
leverage()
leverage(options: InstrumentCommandOptions): Promise<Leverage>GET /v1/account/leverage (account:read): плече і режим маржі
ф’ючерсного інструмента з кешу термінала. Інструмент, якого термінал ще
не торкався, — це not_active (409): відкрийте його у вікні або
викличте setLeverage — так він потрапляє в кеш.
Операція HTTP: GET /v1/account/leverage
| Опції | Тип | Опис |
|---|---|---|
connectionId | number | |
instrument | InstrumentAddress |
setLeverage()
setLeverage(options: SetLeverageOptions): Promise<Accepted>POST /v1/account/leverage (trading:write): встановити плече так, як
це робить вікно — рівно одне з leverage (ціле число ≥ 1) і mode
(max, smart). Застосоване значення видно в leverage після
відповіді біржі.
Операція HTTP: POST /v1/account/leverage
| Опції | Тип | Опис |
|---|---|---|
connectionId | number | |
instrument | InstrumentAddress | |
leverageнеобов’язковий | number | Ціле число, не менше за 1. |
modeнеобов’язковий | "max" | "smart" |
setMarginMode()
setMarginMode(options: SetMarginModeOptions): Promise<Accepted>POST /v1/account/margin-mode (trading:write): cross або isolated.
Зміну з відкритою позицією біржа відхиляє, як і у вікні; відповідь
accepted цього ще не знає.
Операція HTTP: POST /v1/account/margin-mode
| Опції | Тип | Опис |
|---|---|---|
connectionId | number | |
instrument | InstrumentAddress | |
marginMode | MarginMode |
workspace()
workspace(): Promise<Workspace>GET /v1/workspace (workspace:read): усі вікна з їхніми вкладками,
стеками та графіками, зі знімка, який вікно публікує на кожну структурну
зміну. Ідентифікатори внутрішні для цього запуску термінала.
Операція HTTP: GET /v1/workspace
workspaceWindow()
workspaceWindow(options: WindowOptions): Promise<WorkspaceWindow>GET /v1/workspace/windows/{id} (workspace:read): одне вікно; невідомий id — це not_found.
Операція HTTP: GET /v1/workspace/windows/{id}
| Опції | Тип | Опис |
|---|---|---|
windowId | number |
openStack()
openStack(options: OpenStackOptions): Promise<WorkspaceOutcome>POST /v1/workspace/stacks (workspace:write): стек інструмента в новій
вкладці або новому вікні, з графіком над ним, якщо задано chart.
Відповідь називає вікно, вкладку й нові віджети. Інструмент, якого немає
в довіднику термінала, — це invalid_request.
Операція HTTP: POST /v1/workspace/stacks
| Опції | Тип | Опис |
|---|---|---|
instrument | InstrumentAddress | |
connectionIdнеобов’язковий | number | Без нього вибирається за загальним правилом. |
chartнеобов’язковий | boolean | Графік того самого інструмента над стеком. |
targetнеобов’язковий | OpenTarget | new_tab (типово) або new_window. |
windowIdнеобов’язковий | number | Вікно для нової вкладки; без нього — вікно у фокусі. |
activateнеобов’язковий | boolean | false відкриває вкладку у фоні; нове вікно завжди отримує фокус. |
openTab()
openTab(options: OpenTabOptions): Promise<WorkspaceOutcome>POST /v1/workspace/tabs (workspace:write): вкладка з колонкою на
кожен елемент — стек і, з chart, графік над ним — у новій вкладці або
новому вікні. Без name назва — це єдиний інструмент або перший плюс
кількість інших. Відмова називає елемент (items[1]: …), і до вікна не
доходить нічого.
Операція HTTP: POST /v1/workspace/tabs
| Опції | Тип | Опис |
|---|---|---|
items | Array<TabItemOptions | InstrumentAddress> | Колонки по порядку, від однієї до п’ятдесяти; сама адреса — це стек без графіка. |
nameнеобов’язковий | string | До 64 символів; без неї термінал називає вкладку за інструментами. |
targetнеобов’язковий | OpenTarget | new_tab (типово) або new_window. |
windowIdнеобов’язковий | number | Вікно для нової вкладки; без нього — вікно у фокусі. |
activateнеобов’язковий | boolean | false відкриває вкладку у фоні; нове вікно завжди отримує фокус. |
addStacks()
addStacks(options: AddStacksOptions): Promise<WorkspaceOutcome>POST /v1/workspace/windows/{id}/tabs/{tab}/stacks (workspace:write):
ті самі колонки після останньої колонки вкладки; вкладка зберігає назву
й ширини колонок. Відповідь перелічує лише додані віджети.
Операція HTTP: POST /v1/workspace/windows/{id}/tabs/{tab}/stacks
| Опції | Тип | Опис |
|---|---|---|
windowId | number | |
tabId | number | |
items | Array<TabItemOptions | InstrumentAddress> | Колонки по порядку, від однієї до п’ятдесяти; сама адреса — це стек без графіка. |
openMultiview()
openMultiview(options: OpenMultiviewOptions): Promise<WorkspaceOutcome>POST /v1/workspace/multiview (workspace:write): монета на всіх біржах
«Розкладки бірж», той самий план, що й у кнопки «Мультив’ю» вікна. Жодної
комірки для монети — not_found.
Операція HTTP: POST /v1/workspace/multiview
| Опції | Тип | Опис |
|---|---|---|
base | string | Монета (BTC) або пара (BTC/USDT). |
targetнеобов’язковий | OpenTarget | Без нього вирішує налаштування «Відкривати» мультив’ю. |
windowIdнеобов’язковий | number | |
activateнеобов’язковий | boolean |
setStackInstrument()
setStackInstrument(options: StackInstrumentOptions): Promise<WorkspaceOutcome>PATCH /v1/workspace/stacks/{widget_id} (workspace:write): інший інструмент у стеку та його графіках.
Операція HTTP: PATCH /v1/workspace/stacks/{widget_id}
| Опції | Тип | Опис |
|---|---|---|
widgetId | number | |
instrument | InstrumentAddress | |
connectionIdнеобов’язковий | number |
closeStack()
closeStack(options: StackOptions): Promise<WorkspaceOutcome>DELETE /v1/workspace/stacks/{widget_id} (workspace:write): закрити один стек, як це робить його кнопка закриття.
Операція HTTP: DELETE /v1/workspace/stacks/{widget_id}
| Опції | Тип | Опис |
|---|---|---|
widgetId | number |
closeTab()
closeTab(options: TabOptions): Promise<WorkspaceOutcome>DELETE /v1/workspace/windows/{id}/tabs/{tab} (workspace:write): єдина вкладка вікна — це invalid_request.
Операція HTTP: DELETE /v1/workspace/windows/{id}/tabs/{tab}
| Опції | Тип | Опис |
|---|---|---|
windowId | number | |
tabId | number |
activateTab()
activateTab(options: TabOptions): Promise<WorkspaceOutcome>POST /v1/workspace/windows/{id}/tabs/{tab}/activate (workspace:write): вибрати вкладку; фокус вікна не змінюється.
Операція HTTP: POST /v1/workspace/windows/{id}/tabs/{tab}/activate
| Опції | Тип | Опис |
|---|---|---|
windowId | number | |
tabId | number |
closeWindow()
closeWindow(options: WindowOptions): Promise<WorkspaceOutcome>DELETE /v1/workspace/windows/{id} (workspace:write): головне вікно — це invalid_request.
Операція HTTP: DELETE /v1/workspace/windows/{id}
| Опції | Тип | Опис |
|---|---|---|
windowId | number |
activateWindow()
activateWindow(options: WindowOptions): Promise<WorkspaceOutcome>POST /v1/workspace/windows/{id}/activate (workspace:write): відновити, якщо згорнуте, і вивести на передній план.
Операція HTTP: POST /v1/workspace/windows/{id}/activate
| Опції | Тип | Опис |
|---|---|---|
windowId | number |
settings()
settings(options: SettingsOptions = {}): Promise<Settings>GET /v1/settings (settings:read): рядки так, як вони зберігаються, без
підставлених типових значень. Без параметрів — глобальні рядки без
підключення. Кожен рядок каже, чи він writable через updateSettings.
Операція HTTP: GET /v1/settings
| Опції | Тип | Опис |
|---|---|---|
scopeнеобов’язковий | "global" | "order_book" | global (типово) або order_book. |
categoryнеобов’язковий | string | |
keyнеобов’язковий | string | |
connectionIdнеобов’язковий | number | Рядки підключення; без нього — рядки без підключення. |
instrumentнеобов’язковий | InstrumentAddress | Рядки пари (область order_book). |
orderbookSettings()
orderbookSettings(options: InstrumentCommandOptions): Promise<OrderbookSettings>GET /v1/settings/orderbook (settings:read): налаштування стека
інструмента такими, як їх бачить його стек на підключенні — рядок пари,
типове значення підключення, рядок пари без підключення, глобальне типове
значення — з resolved_from у кожного ключа.
Операція HTTP: GET /v1/settings/orderbook
| Опції | Тип | Опис |
|---|---|---|
connectionId | number | |
instrument | InstrumentAddress |
updateSettings()
updateSettings(changes: SettingChange[]): Promise<SettingsApplied>PATCH /v1/settings (settings:write): записати налаштування так, як це
робить Settings App. Кожна зміна спершу перевіряється за словником
термінала (invalid_request із назвою changes[i], нічого не
записується; плече тут — unsupported, використовуйте setLeverage),
потім зміни застосовуються по порядку: той самий рядок, подія вікну й
службові кеші, що й у Settings App. Перша зміна, яку не вдалося
застосувати, відхиляє виклик; попередні лишаються застосованими.
Операція HTTP: PATCH /v1/settings
stream()
stream(options: StreamOptions = {}): Promise<Stream>Відкрити /v1/stream. Лише в Node: токен передається в заголовку рукостискання.
| Опції | Тип | Опис |
|---|---|---|
timeoutMsнеобов’язковий | number | Тайм-аут рукостискання; типово — timeoutMs клієнта. |
StreamProtocol
Половина протоколу стріму без сокета: видає ідентифікатори запитів,
тримає запити, що чекають на відповідь, завершує їх кадрами subscribed /
unsubscribed / error і перетворює все інше на кадри, які перебирає
споживач. Чиста, тому тестується без сервера.
nextRequestId()
nextRequestId(): stringНовий request_id, унікальний у межах цього стріму.
expect()
expect(requestId: string): Promise<ReplyFrame>Зареєструвати запит і отримати проміс, який завершить його відповідь.
pendingCount
pendingCount: numberЗапити, які ще чекають на відповідь.
route()
route(raw: unknown): StreamFrame | undefinedКласифікувати декодований кадр. Відповіді на наші запити завершують
відповідний проміс і повертають undefined; event, gap і помилки
підписок повертаються споживачу; все невідоме або пошкоджене відкидається.
abortAll()
abortAll(error: Error): voidВідхилити всі запити, що чекають, наприклад коли сокет закривається.
Stream
class Stream extends AsyncIterable<StreamFrame>Живе з’єднання /v1/stream.
Отримайте його через terminal.stream(). Підпишіться через subscribe,
потім перебирайте: for await (const frame of stream) видає події,
пропуски й помилки підписок у порядку надходження, буферизовані без
обмеження, поки споживач зайнятий (сервер захищає себе сам: клієнт, який
відстає довше ніж на 5 с, закривається з 4008). Перебирає один споживач
за раз; другий одночасний next() просто чекає своєї черги.
Коли з’єднання закриває сервер, перебір завершується; для 1001, 4008,
4029 і втраченого з’єднання (1006) він завершується викиданням
StreamClosedError. closeCode і closeReason встановлюються в
будь-якому разі. Закриття з боку клієнта (close або break із циклу)
завершує перебір штатно.
connect()
static connect(options: StreamConnectOptions): Promise<Stream>Відкрити WebSocket і завершити рукостискання. Відхиляється з
TerminalUnreachableError, коли термінал його не приймає: WebSocket
Node повідомляє про відхилене рукостискання (термінал не запущено, API
вимкнено, токен відхилено) однією загальною помилкою, тож ці три випадки
не розрізняються.
| Опції | Тип | Опис |
|---|---|---|
url | string | ws://127.0.0.1:48180/v1/stream. |
token | string | |
timeoutMsнеобов’язковий | number | Тайм-аут рукостискання; типово 10 000. |
url
url: stringURL стріму (ніколи не містить токена).
closed
closed: booleantrue, щойно сокет закрито, хоч би хто його закрив.
closeCode
closeCode: number | undefinedКод закриття WebSocket, після закриття.
closeReason
closeReason: string | undefinedПричина закриття WebSocket, після закриття.
subscribe()
subscribe(options: SubscribeOptions): Promise<Subscribed>Підписатися на топік інструмента або на топік рахунку підключення.
Виконується з кадром subscribed сервера (плюс запитаний topic і, для
ринкових топіків, instrument) і відхиляється зі StreamRequestError на
відповідь error сервера; події інших підписок тим часом надходять далі.
Зважайте на ліміт термінала на нові підписки на біржах на секунду
(/v1/meta); топіки рахунку не звертаються до біржі й не надсилають кадру
зі знімком — спершу прочитайте поточний стан операціями /v1/account/*.
| Опції | Тип | Опис |
|---|---|---|
topic | Topic | |
instrumentнеобов’язковий | InstrumentAddress | Обов’язковий для ринкових топіків; для account.* ігнорується. |
connectionIdнеобов’язковий | number | Обов’язковий для account.*; для ринкових топіків без нього вибирається за загальним правилом. |
paramsнеобов’язковий | BookTopParams | Їх читає лише book.top; назви як на дроті (depth, interval_ms). |
unsubscribe()
unsubscribe(subscription: Subscribed | SubscribedFrame | string): Promise<void>Зняти підписку негайно. Приймає значення, з яким виконався subscribe,
або сам ідентифікатор sub. Виконується на unsubscribed сервера.
close()
close(code: number = CLOSE_NORMAL, reason?: string): Promise<void>Закрити стрім. Сервер завершує рукостискання закриття кодом клієнта; проміс виконується, коли це сталося, або після короткої паузи, якщо цього так і не сталося. Повторний виклик безпечний.
Пошук термінала
| Константи | Значення | Опис |
|---|---|---|
DEFAULT_PORT | 48180 | Порт, який слухає термінал, якщо SPECTRE_LOCAL_API_PORT не задає інший. |
TOKEN_ENV | "SPECTRE_LOCAL_API_TOKEN" | Змінна середовища, з якої читається токен. |
instancePath()
function instancePath(options: DiscoveryEnvironment = {}): stringШлях до instance.json термінала, за ОС:
- Linux:
$XDG_DATA_HOME/spectre-terminal/instance.json, інакше~/.local/share/spectre-terminal/instance.json; - macOS:
~/Library/Application Support/spectre-terminal/instance.json; - Windows:
%LOCALAPPDATA%\spectre-terminal\instance.json, інакше%USERPROFILE%\AppData\Local\....
Це повторює власний каталог даних термінала (dirs::data_local_dir).
readPort()
function readPort(options: ReadPortOptions = {}): Promise<number | undefined>Порт Local API, опублікований в instance.json.
Повертає undefined, коли файлу немає або його не вдалося прочитати
(термінал не запущено, або термінал не публікує це поле): тоді той, хто
викликав, бере DEFAULT_PORT. Кидає LocalApiDisabledError, коли файл
є, але local_api_port дорівнює null або відсутній — термінал
запущено, а API вимкнено. Читає лише це одне поле.
tokenFromEnv()
function tokenFromEnv(env: Record<string, string | undefined> = process.env): string | undefinedТокен зі SPECTRE_LOCAL_API_TOKEN або undefined, якщо змінну не задано чи вона порожня.
Помилки
SpectreTerminalError
class SpectreTerminalError extends ErrorБазовий клас усіх помилок, які кидає цей пакет.
ApiError
class ApiError extends SpectreTerminalErrorТермінал відповів статусом не 2xx.
code — стабільний код із конверта помилки контракту (unauthorized,
not_found, rate_limited, …); status — HTTP-статус. Тіло не 2xx, яке
не є конвертом, дає код "unknown".
| Поле | Тип | Опис |
|---|---|---|
code | string | Стабільний код помилки з контракту або "unknown". |
status | number | HTTP-статус відповіді. |
detail | string | Повідомлення сервера для людини, без префікса. |
TerminalUnreachableError
class TerminalUnreachableError extends SpectreTerminalErrorHTTP-відповіді немає взагалі: з’єднання відхилено, запит перевищив
тайм-аут, несподіване перенаправлення або рукостискання WebSocket не
завершилося. Початкова помилка — у cause.
LocalApiDisabledError
class LocalApiDisabledError extends SpectreTerminalErrorinstance.json існує, але не публікує порту Local API: термінал запущено
з вимкненим API, або файл лишився від термінала, який не завершив роботу
штатно. У будь-якому разі порту для підключення немає, поки API не
ввімкнено в Settings App (Загальні → Local API).
TokenMissingError
class TokenMissingError extends SpectreTerminalErrorНі параметр token, ні SPECTRE_LOCAL_API_TOKEN не дали токена.
IncompatibleTerminalError
class IncompatibleTerminalError extends SpectreTerminalError/v1/meta повідомив версію API, якою цей клієнт не говорить.
| Поле | Тип | Опис |
|---|---|---|
apiVersion | string | api_version, яку повідомив термінал. |
appVersion | string | app_version, яку повідомив термінал. |
StreamRequestError
class StreamRequestError extends SpectreTerminalErrorСтрім відповів на запит subscribe або unsubscribe кадром error.
code — код помилки з контракту (not_found, rate_limited,
invalid_request, …). Інші підписки надходять далі.
| Поле | Тип | Опис |
|---|---|---|
code | string | Стабільний код помилки з контракту. |
detail | string | Повідомлення сервера для людини, без префікса. |
StreamClosedError
class StreamClosedError extends SpectreTerminalErrorСервер закрив стрім із причини, на яку споживач має відреагувати: 1001
— API вимкнено або токен перевипущено; 4008 — цей клієнт читав надто
повільно; 4029 — ліміт з’єднань на токен. Також кидається для 1006,
коли з’єднання обірвалося без кадру закриття, і з subscribe /
unsubscribe на вже закритому стрімі.
| Поле | Тип | Опис |
|---|---|---|
code | number | Код закриття WebSocket. |
reason | string | Причина закриття, надіслана сервером; може бути порожньою. |
Зібрано з коду @spectre-trade/terminal, коміт 2d1c324.