Skip to content

TypeScript SDK

@tronchartsxyz/api-client wraps the REST surface in typed resources and ships a WebSocket client for /ws/risk.

Terminal window
npm install @tronchartsxyz/api-client

Ships as ESM with bundled type declarations; Node 20 or newer. The package has no runtime dependencies.

The REST surface and the OpenAPI spec remain the stable contract — the SDK is a convenience over them, not a replacement, and anything it does not cover you can call directly.

import { TronCharts } from '@tronchartsxyz/api-client'
const sdk = new TronCharts({
baseUrl: 'https://api.troncharts.xyz',
token: process.env.TRON_CHARTS_TOKEN!,
tenantSlug: 'acme', // required unless you call from a registered origin — see Tenancy
})

tenantSlug is optional in the type signature only. The SDK sends it as X-Tenant-Slug when present, and every /api/v1/* call needs either that header or an origin registered on your tenant — otherwise the request 404s with unknown_tenant_origin before your token is read. See Tenancy.

Mint the token first. There is no unauthenticated mode — token is required by the constructor — but auth.apiToken authenticates from the body, so the minting client can pass an empty string:

const minter = new TronCharts({ baseUrl: 'https://api.troncharts.xyz', token: '' })
const { token } = await minter.auth.apiToken({ apiKey, apiSecret })

The mint path is one of the few exempt from the tenant gate, so the minting client needs no tenantSlug either. Every client you build after it does.

Resource Covers
sdk.auth Bootstrap tokens, bearer minting.
sdk.accounts State, positions, orders, trades, lifecycle.
sdk.oms Compose, cancel, modify, brackets.
sdk.market Quotes, depth (flat + grouped), FX.
sdk.reports Historical reconciliation reads.
sdk.sor Routing decisions and savings summary.
sdk.venues Venue capability discovery.
sdk.propAccounts, sdk.propTemplates, sdk.riskProfiles, sdk.tradingGroups The prop surface.
sdk.firms Firm lifecycle — create, readiness, deploy, status, payouts.
sdk.tenant Your tenant’s config.
sdk.kyc, sdk.referrals, sdk.analytics, sdk.indicators, sdk.backtests, sdk.copyTrading, sdk.sandbox The rest of the surface.

sdk.client is the escape hatch — a raw typed request method for anything the resources don’t cover yet.

const sdk = new TronCharts({ baseUrl, token, tenantSlug })
// Rehearse against a sandbox account first.
const { accountId } = await sdk.sandbox.paperAccount()
const { intentId } = await sdk.oms.composeIntent(
{ venue: 'hyperliquid', symbol: 'BTC.HL', side: 'buy', type: 'limit', qty: '0.01', price: '60000' },
crypto.randomUUID(), // idempotency key
)
await sdk.oms.attachBrackets({ parentIntentId: intentId, tpPrice: 64000, slPrice: 58000 })
const state = await sdk.accounts.state(accountId)

The socket does not take your REST bearer. Mint a single-use handshake token with auth.bootstrap() and pass that:

import { RiskEngineClient } from '@tronchartsxyz/api-client'
const { data } = await sdk.auth.bootstrap()
const ws = new RiskEngineClient({
url: data.riskEngineWss.endpoint,
token: data.riskEngineWss.token,
onFrame: (frame) => {
if (frame.type === 'Position-Update') applyPosition(frame)
},
})
await ws.connect()
ws.send({ type: 'Subscribe', topics: ['Position-Changed', 'Open-Orders'] })

onFrame is required — there is no .on() event API; every server frame goes through that one handler. connect() sends Authenticate and nothing else, so subscribe explicitly for the topics you want. The handshake token is single-use and expires in 60 seconds, so each connect needs a fresh bootstrap().

The WS client speaks JSON only. If you want the msgpack encoding, drive the socket yourself.

The typed resources track the REST surface but are not a complete mirror of it — market candles and the trade tape, for one, are REST-only today. When something is missing, sdk.client.request() reaches it without waiting for an SDK release. The REST reference renders openapi.yaml, which is hand-maintained and does not cover every /api/v1 route either — see Raw specs.