β οΈ Disclaimer: This is an unofficial TypeScript SDK for Lighter Protocol, built by the community. It is not officially maintained by the Lighter Protocol team.
A complete TypeScript SDK for Lighter Protocol - trade perpetual futures with built-in stop-loss and take-profit orders, position management, and comprehensive error handling.
npm install lighter-ts-sdk
# or
yarn add lighter-ts-sdkThe Lighter TypeScript SDK provides everything you need to:
- Trade perpetual futures on Lighter Protocol
- Create orders (Market, Limit, TWAP) with automatic SL/TP
- Manage positions (open, close, update leverage)
- Transfer funds between accounts
- Monitor transactions with built-in status tracking
- Handle errors automatically with retry logic
Create a .env file in your project root:
# Required credentials
API_PRIVATE_KEY=your_private_key_here
ACCOUNT_INDEX=0
API_KEY_INDEX=0
BASE_URL=https://mainnet.zklighter.elliot.ai
# Optional: for specific examples
MARKET_ID=0
SUB_ACCOUNT_INDEX=1
DEPOSIT_AMOUNT=1npm install lighter-ts-sdkimport { SignerClient, OrderType } from 'lighter-ts-sdk';
import dotenv from 'dotenv';
dotenv.config();
async function placeOrder() {
// Initialize the client
const signerClient = new SignerClient({
url: process.env.BASE_URL!,
privateKey: process.env.API_PRIVATE_KEY!,
accountIndex: parseInt(process.env.ACCOUNT_INDEX!),
apiKeyIndex: parseInt(process.env.API_KEY_INDEX!)
});
// Initialize WASM signer (required)
await signerClient.initialize();
await signerClient.ensureWasmClient();
// Create a market order with SL/TP
const result = await signerClient.createUnifiedOrder({
marketIndex: 0, // ETH market
clientOrderIndex: Date.now(), // Unique ID
baseAmount: 10000, // 0.01 ETH (scaled: 1 ETH = 1,000,000)
isAsk: false, // BUY (true = SELL)
orderType: OrderType.MARKET,
// Slip page protection
idealPrice: 400000, // Ideal price ($4000)
maxSlippage: 0.001, // Max 0.1% slippage
// Automatic stop-loss and take-profit
stopLoss: {
triggerPrice: 380000, // Stop loss at $3800
isLimit: false // Market SL
},
takeProfit: {
triggerPrice: 420000, // Take profit at $4200
isLimit: false // Market TP
}
});
// Check if order succeeded
if (!result.success) {
console.error('β Order failed:', result.mainOrder.error);
return;
}
console.log('β
Order created!');
console.log('Main order hash:', result.mainOrder.hash);
console.log('SL order hash:', result.stopLoss?.hash);
console.log('TP order hash:', result.takeProfit?.hash);
// Wait for transaction confirmation
await signerClient.waitForTransaction(result.mainOrder.hash, 30000);
await signerClient.close();
}
placeOrder().catch(console.error);Lighter uses fixed decimal scaling:
- ETH amounts: 1 ETH = 1,000,000 units
- Prices: $1 = 100 units
// To buy 0.01 ETH at $4000:
baseAmount: 10000 // 0.01 ETH (10,000 / 1,000,000)
price: 400000 // $4000 (400,000 / 100)OrderType.MARKET // Executes immediately at market price
OrderType.LIMIT // Executes at your specified price
OrderType.TWAP // Executes gradually over timeisAsk: false // BUY - You're buying ETH
isAsk: true // SELL - You're selling ETHSL/TP orders are automatically reduce-only - they only close positions:
stopLoss: {
triggerPrice: 380000, // When price hits this, close position
isLimit: false // false = market SL, true = limit SL
},
takeProfit: {
triggerPrice: 420000, // When price hits this, take profit
isLimit: false // false = market TP, true = limit TP
}Important: SL/TP orders require an existing position. For Market orders, this works immediately. For Limit orders, SL/TP are created in the same batch.
Note for TWAP orders: TWAP orders execute over time, creating positions gradually. SL/TP cannot be created in the same batch as TWAP orders. You should create SL/TP orders separately after the TWAP has started creating positions.
const result = await signerClient.createUnifiedOrder({
marketIndex: 0,
clientOrderIndex: Date.now(),
baseAmount: 10000, // Amount (0.01 ETH)
idealPrice: 400000, // Your target price ($4000)
maxSlippage: 0.001, // 0.1% max slippage
isAsk: false, // BUY
orderType: OrderType.MARKET
});
if (!result.success) {
console.error('Failed:', result.mainOrder.error);
return;
}const result = await signerClient.createUnifiedOrder({
marketIndex: 0,
clientOrderIndex: Date.now(),
baseAmount: 10000, // Amount (0.01 ETH)
price: 400000, // Limit price ($4000)
isAsk: false, // BUY
orderType: OrderType.LIMIT,
orderExpiry: Date.now() + (60 * 60 * 1000) // Expires in 1 hour
});
// Wait for it to fill
if (result.success) {
await signerClient.waitForTransaction(result.mainOrder.hash);
}const [tx, hash, error] = await signerClient.cancelOrder({
marketIndex: 0,
orderIndex: 12345 // Your order's index
});
if (error) {
console.error('Cancel failed:', error);
return;
}
await signerClient.waitForTransaction(hash);
console.log('β
Order cancelled');const [tx, hash, error] = await signerClient.createMarketOrder({
marketIndex: 0,
clientOrderIndex: Date.now(),
baseAmount: 10000, // Position size to close
avgExecutionPrice: 400000,
isAsk: false, // Opposite of position
reduceOnly: true // IMPORTANT: Only closes, doesn't open new
});
if (error) {
console.error('Close failed:', error);
return;
}
await signerClient.waitForTransaction(hash);
console.log('β
Position closed');const status = await signerClient.getTransaction(txHash);
console.log('Status:', status.status); // 0=pending, 1=queued, 2=committed, 3=executed// Create a unified order (main order + SL/TP)
createUnifiedOrder(params) -> Promise<UnifiedOrderResult>
// Create a single order
createOrder(params) -> Promise<[txInfo, txHash, error]>
// Cancel a specific order
cancelOrder(params) -> Promise<[txInfo, txHash, error]>
// Cancel all orders
cancelAllOrders(timeInForce, time) -> Promise<[txInfo, txHash, error]>// Close specific position
createMarketOrder({ reduceOnly: true }) -> Promise<[txInfo, txHash, error]>
// Close all positions
closeAllPositions() -> Promise<[txs[], responses[], errors[]]>// Get transaction details
getTransaction(txHash) -> Promise<Transaction>
// Wait for transaction (with timeout)
waitForTransaction(txHash, maxWaitTime, pollInterval) -> Promise<Transaction>interface UnifiedOrderParams {
marketIndex: number; // Market ID (0 = ETH)
clientOrderIndex: number; // Unique ID (use Date.now())
baseAmount: number; // Amount in units (1 ETH = 1,000,000)
isAsk: boolean; // true = SELL, false = BUY
orderType: OrderType; // MARKET, LIMIT, or TWAP
// For market orders
idealPrice?: number; // Target price
maxSlippage?: number; // Max slippage (e.g., 0.001 = 0.1%)
// For limit orders
price?: number; // Limit price
// Optional SL/TP (automatically reduce-only)
stopLoss?: {
triggerPrice: number;
isLimit?: boolean;
};
takeProfit?: {
triggerPrice: number;
isLimit?: boolean;
};
// Optional
orderExpiry?: number; // Expiry timestamp (milliseconds)
}// β DON'T hardcode credentials
const privateKey = '0xabc123...';
// β
DO use environment variables
const privateKey = process.env.API_PRIVATE_KEY;try {
const result = await signerClient.createUnifiedOrder(params);
if (!result.success) {
console.error('Order failed:', result.mainOrder.error);
return; // Exit early
}
// Success path
console.log('Order created:', result.mainOrder.hash);
} catch (error) {
console.error('Unexpected error:', error);
}// Wait for transaction to be confirmed
try {
await signerClient.waitForTransaction(txHash, 30000, 2000);
console.log('β
Transaction confirmed');
} catch (error) {
console.error('β Transaction failed:', error.message);
}try {
// ... use signerClient
} finally {
await signerClient.close(); // Always close when done
}The examples/ directory contains working examples for every feature:
# Run examples
npx ts-node examples/create_market_order.ts # Market order with SL/TP
npx ts-node examples/create_limit_order.ts # Limit order with SL/TP
npx ts-node examples/cancel_order.ts # Cancel orders
npx ts-node examples/close_position.ts # Close positions
npx ts-node examples/deposit_to_subaccount.ts # Fund transfers- Start Here:
examples/create_market_order.ts- Simplest order creation - Next:
examples/create_limit_order.ts- Learn about limit orders - Then:
examples/cancel_order.ts- Learn about order management - Advanced:
examples/send_tx_batch.ts- Batch transactions
- β
Never commit
.envfiles - β Use environment variables for all credentials
- β Test with small amounts first
- β Monitor all transactions
- β Use proper error handling
- Check the examples in
examples/directory - Read error messages carefully - they're informative
- Ensure environment variables are set correctly
- Start with
examples/create_market_order.ts
MIT License - see LICENSE file for details.