@limitless-exchange/sdk
v0.0.3
Published
TypeScript SDK for Limitless Exchange CLOB and NegRisk trading
Maintainers
Readme
Limitless Exchange TypeScript SDK
A TypeScript SDK for interacting with the Limitless Exchange platform, providing type-safe access to CLOB and NegRisk prediction markets.
⚠️ Disclaimer
USE AT YOUR OWN RISK
This SDK is provided "as-is" without any warranties or guarantees. Trading on prediction markets involves financial risk. By using this SDK, you acknowledge that:
- You are responsible for testing the SDK thoroughly before using it in production
- The SDK authors are not liable for any financial losses or damages
- You should review and understand the code before executing any trades
- It is recommended to test all functionality on testnet or with small amounts first
- The SDK may contain bugs or unexpected behavior despite best efforts
ALWAYS TEST BEFORE USING IN PRODUCTION WITH REAL FUNDS
For production use, we strongly recommend:
- Running comprehensive tests with your specific use case
- Starting with small transaction amounts
- Monitoring all transactions carefully
- Having proper error handling and recovery mechanisms
Features
- ✅ Authentication: Simple wallet-based authentication with session management
- ✅ Order Management: Create, cancel, and manage orders on CLOB and NegRisk markets
- ✅ Market Data: Access real-time market data and orderbooks
- ✅ NegRisk Markets: Full support for group markets with multiple outcomes
- ✅ Error Handling & Retry: Automatic retry logic for rate limits and transient failures
- ✅ Type Safety: Full TypeScript support with comprehensive type definitions
- ✅ TSDoc Documentation: Complete API documentation with examples
- ✅ WebSocket: Real-time price and position updates
Installation
npm install @limitless-exchange/sdk
# or
yarn add @limitless-exchange/sdk
# or
pnpm add @limitless-exchange/sdkQuick Start
Fetching Active Markets (No Authentication Required)
import { HttpClient, MarketFetcher } from '@limitless-exchange/sdk';
// Create HTTP client (no authentication needed)
const httpClient = new HttpClient({
baseURL: 'https://api.limitless.exchange',
// Optional: Add custom headers to all requests
additionalHeaders: {
'X-Custom-Header': 'my-value',
'X-API-Version': 'v1',
},
});
const marketFetcher = new MarketFetcher(httpClient);
// Get markets sorted by LP rewards
const markets = await marketFetcher.getActiveMarkets({
limit: 8,
sortBy: 'lp_rewards', // 'lp_rewards' | 'ending_soon' | 'newest' | 'high_value'
});
console.log(`Found ${markets.data.length} of ${markets.totalMarketsCount} markets`);
// Pagination (page-based)
const page2 = await marketFetcher.getActiveMarkets({
limit: 8,
page: 2,
sortBy: 'ending_soon',
});See examples/project-integration/src/active-markets.ts for more examples.
Authentication
import { ethers } from 'ethers';
import { HttpClient, MessageSigner, Authenticator } from '@limitless-exchange/sdk';
// Create wallet from private key
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY);
// Initialize SDK components
const httpClient = new HttpClient({
baseURL: 'https://api.limitless.exchange',
});
const signer = new MessageSigner(wallet);
const authenticator = new Authenticator(httpClient, signer);
// Authenticate
const result = await authenticator.authenticate({
client: 'eoa', // 'eoa', 'base', or 'etherspot'
});
console.log('Session cookie:', result.sessionCookie);
console.log('Profile:', result.profile);ETHERSPOT Authentication (Smart Wallet)
const result = await authenticator.authenticate({
client: 'etherspot',
smartWallet: '0x...', // Your smart wallet address
});Token Approvals
Important: Before placing orders, you must approve tokens for the exchange contracts. This is a one-time setup per wallet.
Required Approvals
CLOB Markets:
- BUY orders: Approve USDC →
market.venue.exchange - SELL orders: Approve Conditional Tokens →
market.venue.exchange
NegRisk Markets:
- BUY orders: Approve USDC →
market.venue.exchange - SELL orders: Approve Conditional Tokens → both
market.venue.exchangeANDmarket.venue.adapter
Quick Setup
Run the approval setup script:
# Copy .env.example and configure your wallet
cp docs/code-samples/.env.example docs/code-samples/.env
# Edit .env and set your PRIVATE_KEY and market slug
# Then run the approval script
npx tsx docs/code-samples/setup-approvals.tsManual Approval Example
import { ethers } from 'ethers';
import { MarketFetcher, getContractAddress } from '@limitless-exchange/sdk';
// 1. Fetch market to get venue addresses
const market = await marketFetcher.getMarket('market-slug');
// 2. Create contract instances
const usdc = new ethers.Contract(
getContractAddress('USDC'),
['function approve(address spender, uint256 amount) returns (bool)'],
wallet
);
const ctf = new ethers.Contract(
getContractAddress('CTF'),
['function setApprovalForAll(address operator, bool approved)'],
wallet
);
// 3. Approve USDC for BUY orders
await usdc.approve(market.venue.exchange, ethers.MaxUint256);
// 4. Approve CT for SELL orders
await ctf.setApprovalForAll(market.venue.exchange, true);
// 5. For NegRisk SELL orders, also approve adapter
if (market.negRiskRequestId) {
await ctf.setApprovalForAll(market.venue.adapter, true);
}For complete examples, see docs/code-samples/setup-approvals.ts.
Trading on NegRisk Markets
NegRisk markets are group markets with multiple related outcomes. Here's a quick example:
import { OrderClient, MarketFetcher, Side, OrderType } from '@limitless-exchange/sdk';
// 1. Fetch NegRisk group market
const marketFetcher = new MarketFetcher(httpClient);
const groupMarket = await marketFetcher.getMarket('largest-company-end-of-2025-1746118069282');
// 2. Select a submarket (e.g., Apple)
const appleMarket = groupMarket.markets[0];
const marketDetails = await marketFetcher.getMarket(appleMarket.slug);
// 3. Create order client (contract address from venue)
const orderClient = new OrderClient({
httpClient,
wallet,
userData: {
userId: (authResult.profile as any).id,
feeRateBps: (authResult.profile as any).rank?.feeRateBps || 300,
},
});
// 4. Place order on submarket (not group!)
const order = await orderClient.createOrder({
tokenId: marketDetails.tokens.yes,
price: 0.5,
size: 10,
side: Side.BUY,
orderType: OrderType.GTC,
marketSlug: appleMarket.slug, // Use submarket slug
});Important: Always use the submarket slug for NegRisk orders, not the group market slug!
For more details, see the NegRisk Trading Guide.
Error Handling & Retry
The SDK provides automatic retry logic for handling transient failures like rate limits and server errors:
import { withRetry, retryOnErrors } from '@limitless-exchange/sdk';
// Option 1: Wrapper function approach
const result = await withRetry(async () => await orderClient.createOrder(orderData), {
statusCodes: [429, 500, 503], // Retry on rate limits and server errors
maxRetries: 3,
delays: [2, 5, 10], // Wait 2s, then 5s, then 10s
onRetry: (attempt, error, delay) => {
console.log(`Retry ${attempt + 1} after ${delay}s: ${error.message}`);
},
});
// Option 2: Decorator approach (requires experimentalDecorators: true)
class TradingService {
@retryOnErrors({
statusCodes: [429, 500, 503],
maxRetries: 3,
exponentialBase: 2, // Exponential backoff: 1s, 2s, 4s
maxDelay: 30,
})
async placeOrder(orderData: any) {
return await this.orderClient.createOrder(orderData);
}
}Key Features:
- Automatic retry on configurable status codes (429, 500, 502, 503, 504)
- Fixed delays or exponential backoff strategies
- Callback hooks for monitoring retry attempts
- Three approaches: decorator, wrapper function, or global client wrapper
For detailed documentation, see the Error Handling & Retry Guide.
API Documentation
Authentication
MessageSigner
Handles message signing for authentication.
const signer = new MessageSigner(wallet);
// Create authentication headers
const headers = await signer.createAuthHeaders(signingMessage);
// Sign EIP-712 typed data
const signature = await signer.signTypedData(domain, types, value);Authenticator
Manages the authentication flow.
const authenticator = new Authenticator(httpClient, signer);
// Get signing message
const message = await authenticator.getSigningMessage();
// Authenticate
const result = await authenticator.authenticate({ client: 'eoa' });
// Verify authentication
const address = await authenticator.verifyAuth(sessionCookie);
// Logout
await authenticator.logout(sessionCookie);HttpClient
HTTP client with cookie management.
const httpClient = new HttpClient({
baseURL: 'https://api.limitless.exchange',
timeout: 30000,
});
// Set session cookie for authenticated requests
httpClient.setSessionCookie(sessionCookie);
// Make requests
const data = await httpClient.get('/endpoint');
await httpClient.post('/endpoint', { data });Documentation
For detailed documentation, see the docs directory:
- Complete Documentation - Full SDK documentation
- Authentication Guide - Authentication and session management
- Trading & Orders - Order creation, management, and NegRisk markets
- Market Data - Market discovery and orderbook access
- Portfolio & Positions - Position tracking and balances
- WebSocket Streaming - Real-time data updates
- Error Handling & Retry - API error handling and retry mechanisms
- Logging - Logging configuration
Code Examples
Production-ready code samples are available in docs/code-samples:
Authentication Examples
basic-auth.ts- Simple EOA authenticationsmart-wallet.ts- Etherspot smart wallet integrationwith-logging.ts- Authentication with custom loggingauth-retry.ts- Authentication with retry logicerror-handling.ts- Comprehensive error handling
Trading Examples
CLOB Markets:
clob-fok-order.ts- Fill-or-Kill market ordersclob-gtc-order.ts- Good-Til-Cancelled limit orders
NegRisk Markets:
negrisk-fok-order.ts- FOK orders on group marketsnegrisk-gtc-trading-example.ts- Complete NegRisk trading workflow
Market Data Examples
get-active-markets.ts- Fetching active markets with sorting and paginationorderbook.ts- Fetching and analyzing orderbookspositions.ts- Portfolio and position trackingtrading.ts- Complete trading workflow
Real-Time Examples
websocket-trading.ts- Real-time order monitoringwebsocket-orderbook.ts- Live orderbook streaming
Development
Build
pnpm install
pnpm buildTest
pnpm test
pnpm test:coverageLint
pnpm lint
pnpm formatProject Structure
src/
├── types/ # TypeScript type definitions
│ ├── markets.ts # Market and active markets types
│ ├── orders.ts # Order types
│ ├── auth.ts # Authentication types
│ └── ...
├── auth/ # Authentication modules
│ ├── signer.ts # Message signing
│ └── authenticator.ts
├── markets/ # Market data modules
│ ├── fetcher.ts # Market and orderbook fetching
│ └── index.ts
├── orders/ # Order management
│ └── client.ts # Order creation and management
├── portfolio/ # Portfolio and positions
│ └── fetcher.ts
├── websocket/ # Real-time data streaming
│ └── client.ts
├── api/ # HTTP client and API utilities
│ ├── http.ts # HTTP client
│ └── errors.ts # API error handling
└── utils/ # Shared utilities and constants
tests/
├── auth/ # Authentication tests
└── markets/ # Market fetcher tests
└── fetcher.test.ts //etc.
docs/
├── code-samples/ # Production-ready examples
│ ├── get-active-markets.ts
│ ├── clob-fok-order.ts
│ └── ...
└── */ # Documentation guides
License
MIT - See LICENSE file for details
