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.
clientOrderIdis mandatory; re-using a live one is rejected (no duplicate orders). Decibel TP/SL viatpTriggerPrice/slTriggerPrice.
- Name
placeBatch({ venue, orders })- Type
- Promise<Array<OrderStatus | TriaError>>
- Description
Up to 20 orders in one venue action. Per-row outcome:
OrderStatuson success,TriaErroron per-order rejection.
- Name
cancelOrder(args)- Type
- Promise<CancelResult>
- Description
Cancel by
orderIdorclientOrderId. 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/limitwindowing.
- 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.