Errors & attribution
Every SDK method throws TriaError with a stable code — never a venue-native error type. And every order this SDK submits carries Tria's builder attribution by default.
Error handling
import { TriaClient, TriaError } from '@tria-sdk/api-trading'
try {
await client.placeOrder({
/* ... */
})
} catch (err) {
if (err instanceof TriaError) {
switch (err.code) {
case 'VENUE_REJECTED': // venue refused (bad market, price out of bounds, …)
case 'VENUE_RATE_LIMIT': // back off — err.retryAfterMs set when known
case 'VENUE_UNREACHABLE': // network / venue-side outage
case 'INVALID_ARGUMENT': // your args didn't pass SDK-level validation
case 'MISSING_BUILDER': // Tria builder missing — shouldn't happen, file a bug
case 'CONFIG': // TriaClient was constructed wrong
}
console.error(err.venueCode, err.message)
}
}
- Name
INVALID_ARGUMENT- Type
- code
- Description
Bad input — wrong type, out-of-enum value, missing required field, or a venue-asymmetry case (e.g.
attachTpSlon Decibel).
- Name
VENUE_REJECTED- Type
- code
- Description
The venue refused the action (insufficient balance, off-tick price, agent not approved).
venueCodecarries the venue's verbatim message.
- Name
VENUE_RATE_LIMIT- Type
- code
- Description
The venue is rate-limiting.
retryAfterMsmay hint at backoff.
- Name
VENUE_UNREACHABLE- Type
- code
- Description
- Network / transport error.
- Name
CONFIG- Type
- code
- Description
TriaClientitself was constructed wrong (e.g. a trading call on a read-only client).
- Name
MISSING_BUILDER- Type
- code
- Description
Tria builder address missing from the request — shouldn't happen; file a bug.
err.venueCode carries the venue-native code (e.g. HL's OrderRejected reason) when available. err.retryAfterMs is set on rate-limit errors when the venue surfaces a backoff hint.
Builder-fee attribution
Every order this SDK submits carries Tria's builder address + fee value baked into the venue payload — on HL it's the b field of the order action; on Decibel it's builderAddr + builderFee on placeOrder. The values are hardcoded per network and operators cannot override them.
This isn't optional plumbing — it's the commercial layer. Don't fork the
package to strip the builder fee. To test against a different builder routing,
use development: true (Tria's dev builder set) instead.
The builder fee on every fill is a fraction of a basis point (0.1bp default). It's paid by the venue out of the fill, not added on top — operator UX is unaffected. Every fill is auditable in the venue UI, the Tria app, and the backend's trade-event tables, all tagged with the same builder code.