strix-sdk
v0.1.2
Published
TypeScript SDK for the Strix prediction market platform — authenticate, stream orderbooks, and trade programmatically.
Maintainers
Readme
strix-sdk
TypeScript SDK for the Strix prediction market platform.
Authenticate, stream live orderbooks, and trade programmatically using HMAC API keys.
Installation
npm install strix-sdkNode.js 18+ required. The SDK uses native
fetch(Node 18+) and thewspackage for WebSocket support in Node 18–20. Node 21+ uses the built-in WebSocket.
Quick Start
import { StrixClient } from 'strix-sdk';
const client = new StrixClient({
baseUrl: 'https://api-staging.strixlab.io/api', // testnet staging — omit to use this default
apiKey: process.env.STRIX_API_KEY!,
apiSecret: process.env.STRIX_API_SECRET!,
apiPassphrase: process.env.STRIX_API_PASSPHRASE!,
});Note: Public endpoints (event listing, orderbooks) work without any credentials.
Trading, portfolio, and the private WebSocket channel require HMAC API keys.
Network: The SDK currently defaults to the Sepolia testnet staging environment (
api-staging.strixlab.io).
For local development usehttp://localhost:8080/api.
When the platform launches on Base mainnet, a new version will default tohttps://api.strixlab.io.
Getting API Keys
- Log into the Strix app with your wallet.
- Go to Settings → API Keys → Generate New Key.
- Copy your
apiKey,apiSecret, andapiPassphrase— the secret is shown only once. - Store them in environment variables (never commit them to source control).
API Reference
Events & Markets (public)
// List all open events (paginated)
const { items, total } = await client.events.list({ status: 'open', pageSize: 20 });
// Get a single event by ID or slug
const event = await client.events.get('event-id-or-slug');
// Each event contains markets, each market contains outcomes with tokenIds:
const tokenId = event.markets[0].outcomes[0].tokenId;Orderbook (public)
// REST snapshot (one-shot)
const book = await client.orderbook.snapshot(tokenId, { depth: 20 });
console.log(book.bids, book.asks);
// Live stream (WebSocket) — see WebSocket section belowOrders (requires HMAC credentials)
// Place a limit order
const order = await client.orders.place({
tokenId,
side: 'BUY', // 'BUY' | 'SELL'
price: 0.65, // tick size 0.01 or 0.001 depending on market (represents probability, i.e. 65¢)
quantity: 100, // number of shares
orderType: 'GTC', // 'GTC' | 'GTD' | 'FOK' | 'FAK'
});
// Cancel a single order
await client.orders.cancel(order.orderHash);
// Cancel all open orders (rate-limit-exempt — use as a safety kill-switch)
await client.orders.cancelAll();
// Cancel orders for a specific token or market
await client.orders.cancelAll({ tokenId });
await client.orders.cancelAll({ marketId: 'market-id' });
// List your open orders
const openOrders = await client.orders.list({ marketId: 'market-id' });Portfolio (requires HMAC credentials)
const summary = await client.portfolio.summary();
const positions = await client.portfolio.positions();
const trades = await client.portfolio.trades({ limit: 100 });
const deposits = await client.portfolio.deposits();
// Per-market positions
const marketPos = await client.portfolio.positionsForMarket('market-id');Conditional Token Operations (requires HMAC credentials)
// Split USDC into YES + NO tokens
await client.positions.split({ marketId: 'market-id', collateralAmount: 100 });
// Merge equal YES + NO back into USDC
await client.positions.merge({ marketId: 'market-id', shareAmount: 100 });
// Redeem winning tokens after resolution
await client.positions.redeem({ marketId: 'market-id' });Public Utilities
// Price chart (OHLCV)
const candles = await client.public.kline({ tokenId, interval: '1h' });
// Activity feed & leaderboard
const activity = await client.public.activity();
const leaderboard = await client.public.leaderboard();WebSocket
All channels share a single WebSocket connection to /ws.
Orderbook stream (public)
const unsub = client.ws.orderbook.subscribe(['token-id-1', 'token-id-2'], {
depth: 20,
onSnapshot: ({ marketId, levels, ts }) => {
console.log('Full book:', levels.bids, levels.asks);
},
onDelta: ({ marketId, side, price, size, ts }) => {
// Incremental update — size=0 means remove the level
console.log(`Delta: ${side} ${price} → ${size}`);
},
onLastPrice: ({ marketId, price }) => console.log('Last:', price),
onStatusUpdate: ({ marketId, status }) => console.log('Status:', status),
});
// Unsubscribe when done
unsub();Public trades feed
const unsub = client.ws.trades.subscribe(['token-id'], (trade) => {
console.log(`${trade.side} ${trade.size} @ ${trade.price}`);
});Private user channel (requires HMAC credentials)
// Connect and authenticate — happens automatically
client.ws.user.connect();
// Register handlers (returns an unsubscribe function)
const off = client.ws.user.on('order.update', (update) => {
console.log(`Order ${update.orderId} → ${update.status}`);
});
client.ws.user.on('trade.settled', (trade) => {
console.log(`Fill: ${trade.side} ${trade.quantity} @ ${trade.price} — txHash: ${trade.txHash}`);
});
client.ws.user.on('trade.failed', (fail) => {
console.error('Trade failed:', fail.reason);
});
client.ws.user.on('position.update', (delta) => {
console.log(`Position delta: ${delta.sharesDelta > 0 ? '+' : ''}${delta.sharesDelta} shares`);
});
client.ws.user.on('portfolio.summary_update', (summary) => {
console.log('Portfolio value:', summary.totalValue);
});
// Handle server-side errors (e.g. invalid HMAC credentials)
// If no error handler is registered, the SDK logs to console.error automatically.
client.ws.user.on('error', (err) => {
console.error('WebSocket auth error:', err.message);
// err.raw contains the full server message object for debugging
});
// Remove a specific handler
off();Cleanup
Always call client.destroy() when your program exits to close the WebSocket connection and cancel all timers.
process.on('SIGINT', () => {
client.destroy();
process.exit(0);
});Error Handling
import { StrixApiError, StrixAuthError } from 'strix-sdk';
try {
await client.orders.place({ ... });
} catch (err) {
if (err instanceof StrixAuthError) {
// Missing or incomplete credentials
console.error(err.message);
} else if (err instanceof StrixApiError) {
// API returned a non-success response
console.error(`HTTP ${err.status}: ${err.message}`);
// Rate limit — err.retryAfter is the number of seconds to wait (when provided by the server)
if (err.status === 429 && err.retryAfter) {
console.warn(`Rate limited — retry after ${err.retryAfter}s`);
}
} else {
throw err;
}
}Automatic 429 retry
Pass retryOn429: true to let the SDK handle one retry automatically after the
Retry-After delay (capped at 60 s). Disabled by default so bots managing their
own rate limits are not surprised by hidden delays.
const client = new StrixClient({
baseUrl: 'https://api-staging.strixlab.io/api',
retryOn429: true, // wait for Retry-After then retry once before throwing
// ...
});Null instead of throwing
Pass nullOnError: true to receive null on API failures instead of an exception.
Useful in tight polling loops where you prefer explicit null-checks.
const client = new StrixClient({ nullOnError: true, /* ... */ });
const order = await client.orders.place({ ... });
if (!order) { /* handle failure */ }HMAC Authentication Details
Every authenticated request must include these headers:
| Header | Value |
|--------|-------|
| STRIX-API-KEY | Your API key |
| STRIX-TIMESTAMP | Unix seconds |
| STRIX-SIGNATURE | HMAC-SHA256(apiSecret, timestamp + METHOD + path + body), base64-encoded |
| STRIX-PASSPHRASE | Your raw passphrase |
For WebSocket auth:
signature = HMAC-SHA256(apiSecret, timestamp + "GET" + "/ws")The signature function is exported if you need it:
import { buildSignature, buildTimestamp } from 'strix-sdk';Examples
# 1. Browse open markets (no auth)
npx tsx examples/01-list-markets.ts
# 2. Place and cancel an order
STRIX_WALLET_ADDRESS=0x... STRIX_API_KEY=... ... npx tsx examples/02-place-order.ts
# 3. Market-maker bot
MM_TOKEN_ID=<tokenId> ... npx tsx examples/03-market-maker-bot.ts
# 4. Live orderbook visualiser (no auth)
MM_TOKEN_ID=<tokenId> npx tsx examples/04-orderbook-stream.tsFuture SDKs
strix-sdk-python— Python clientstrix-sdk-rust— Rust client (high-frequency use cases)
License
MIT
