SDK overview & surface

@tria-sdk/api-trading is a pure client library: one TriaClient, two venues, normalized shapes. Every method returns a promise and throws TriaError — never a venue-native error type.

Method surface

Writes

  • Name
    placeOrder(args)
    Type
    Promise<OrderStatus>
    Description

    Submit a single order. clientOrderId is mandatory; re-using a live one is rejected (no duplicate orders). Decibel TP/SL via tpTriggerPrice / slTriggerPrice.

  • Name
    placeBatch({ venue, orders })
    Type
    Promise<Array<OrderStatus | TriaError>>
    Description

    Up to 20 orders in one venue action. Per-row outcome: OrderStatus on success, TriaError on per-order rejection.

  • Name
    cancelOrder(args)
    Type
    Promise<CancelResult>
    Description

    Cancel by orderId or clientOrderId. Idempotent — a second cancel returns { status: "not_found" }.

  • Name
    cancelAllOrders({ venue, market? })
    Type
    Promise<CancelAllResult>
    Description

    Bulk cancel with a per-order success / failure breakdown.

  • Name
    modifyOrder(args)
    Type
    Promise<OrderStatus>
    Description

    Change a resting order's price and/or size. HL: native modify (mints a new orderId). Decibel: emulated as cancel + replace.

  • Name
    attachTpSl(args)
    Type
    Promise<{ tp?, sl? }>
    Description

    Attach reduce-only TP/SL trigger orders to an open position. HL: native. Decibel: throws INVALID_ARGUMENT (TP/SL is at-placement-time only).

  • Name
    closePosition({ venue, market, slippageBps? })
    Type
    Promise<OrderStatus>
    Description

    Flatten a position via a reduce-only IOC at the slippage band (default 2%).

Reads

  • Name
    orderStatus({ venue, orderId })
    Type
    Promise<OrderStatus>
    Description
    Single-order lookup.
  • Name
    openOrders({ venue, market? })
    Type
    Promise<OrderStatus[]>
    Description
    Working orders.
  • Name
    fills(args)
    Type
    Promise<Fill[]>
    Description
    Historical fills with from / to / limit windowing.
  • Name
    positions({ venue, market? })
    Type
    Promise<Position[]>
    Description
    Open positions.
  • Name
    balances({ venue })
    Type
    Promise<Balance[]>
    Description
    Asset balances.
  • Name
    marginState({ venue })
    Type
    Promise<MarginState>
    Description
    Free collateral, margin ratio, max leverage.
  • Name
    account({ venue })
    Type
    Promise<AccountSnapshot>
    Description
    Combined snapshot — balances + margin + leverage + builder + network.

Public market data & streams

markets, orderbook, ticker, candles, recentTrades, and the subscribe* streams are covered on Market data & streams. Risk (scheduledCancel) and errors are on Errors & attribution.

Helpers

import { generateClientOrderId, roundToTickSize } from '@tria-sdk/api-trading'

// HL-format cloid: 0x + 32 lowercase hex chars. Random per call.
const cloid = generateClientOrderId()

// Round a decimal-string price to the market's tick (BigInt-precise).
const markets = await client.markets({ venue: 'hl' })
const btc = markets.find((m) => m.symbol === 'BTC')
const safePrice = roundToTickSize('100.12345', btc!.tickSize)

Normalized shapes

Every numeric field representing a token amount is a decimal string, not a number — JS doubles lose precision past 2⁵³, so the SDK never round-trips through number.

type OrderStatus = {
  orderId: string
  clientOrderId: string
  venue: 'hl' | 'decibel'
  market: string
  side: 'buy' | 'sell'
  size: string
  price: string | null // null for market-style orders
  tif: 'gtc' | 'ioc' | 'alo'
  filled: string
  remaining: string
  state: 'open' | 'partially_filled' | 'filled' | 'cancelled' | 'rejected'
  createdAt?: number // unix ms
}

type Fill = {
  fillId: string
  orderId: string
  clientOrderId: string
  venue: 'hl' | 'decibel'
  market: string
  side: 'buy' | 'sell'
  size: string
  price: string
  fee: string
  feeAsset: string
  timestamp: number // unix ms
}

type Position = {
  venue: 'hl' | 'decibel'
  market: string
  side: 'buy' | 'sell' // sign of position size
  size: string // absolute value
  entryPrice: string
  markPrice: string
  unrealizedPnl: string
  liquidationPrice: string | null
  leverage: string
}

Subpath imports (tree-shaking)

Operators who only need one venue can import from a per-venue subpath and drop the other venue's bundle entirely (typically 100–200 KB minified):

// HL only — drops @decibeltrade/sdk + @aptos-labs/ts-sdk
import { HlVenue } from '@tria-sdk/api-trading/hl'

// Decibel only — drops @nktkas/hyperliquid
import { DecibelVenue } from '@tria-sdk/api-trading/decibel'

The root entry pulls both, which is what you want when you use both venues. A CI smoke build asserts the dropped venue's identifiers don't appear in the output.

Browser support

The package exposes a browser field and ships a tree-shakeable ESM build. It runs in Vite/webpack apps, manifest-v3 browser extensions, and Cloudflare Workers / Vercel Edge runtimes that support fetch + crypto.subtle. Node ≥ 18 covers all platform APIs natively — no polyfills.

Venue notes

Hyperliquid — markets are bare symbols (BTC). $10 minimum notional per order; prices ≤ 5% from reference. TIF: gtc (resting), ioc (taker), alo (post-only).

Decibel — markets use a /USD suffix (BTC/USD). Two distinct Geomi keys: Api (reads, required) and Gs (sponsored writes, optional). Sizes/prices are scaled by the market's sz_decimals / px_decimals internally; you pass human decimal strings.

Was this page helpful?