@pear-protocol/exchanges-sdk
v0.0.8
Published
Pear Protocol Exchanges SDK
Readme
@backend/exchanges-sdk
Unified SDK for connecting to cryptocurrency derivative exchanges. Provides real-time account state tracking including balances, positions, and leverage management through a single, exchange-agnostic interface.
Supported Exchanges
| Exchange | Connector Name | Market Type |
|----------|---------------|-------------|
| Binance | binanceusdm | USDM Futures |
| Bybit | bybit | Linear Perpetuals |
| Hyperliquid | hyperliquid | Perpetuals |
Installation
{
"dependencies": {
"@backend/exchanges-sdk": "workspace:*"
}
}Requires @pear-protocol/core-sdk and @backend/shared as peer dependencies.
Quick Start
import PearSDK from '@pear-protocol/core-sdk';
import { ExchangesSDK } from '@backend/exchanges-sdk';
const sdk = new PearSDK({ /* ... */ });
const exchanges = new ExchangesSDK({ sdk });
await exchanges.account.connect(tradeAccountId, 'binanceusdm');
const balanceTracker = exchanges.account.trackBalance((balance) => {
console.log(balance.totalEquity);
});
const positionsTracker = exchanges.account.trackPositions((positions) => {
for (const pos of positions) {
console.log(pos.symbol, pos.side, pos.size);
}
});
// Cleanup
balanceTracker.untrack();
positionsTracker.untrack();
exchanges.destroy();Usage
Initialization
// Production
const exchanges = new ExchangesSDK({ sdk });
// Testnet / demo
const exchanges = new ExchangesSDK({ sdk, demo: true });Connecting to an Exchange
Credentials are fetched automatically from the backend when you call connect.
await exchanges.account.connect(tradeAccountId, 'binanceusdm');
await exchanges.account.connect(tradeAccountId, 'bybit');
await exchanges.account.connect(tradeAccountId, 'hyperliquid');Check connection status:
exchanges.account.isConnected; // WebSocket is active
exchanges.account.isInitialized; // First state snapshot receivedTracking Balance
Subscribe to real-time balance updates. The callback fires on every balance change.
const tracker = exchanges.account.trackBalance((balance) => {
balance.totalEquity; // total account equity
balance.walletBalance; // wallet balance excluding unrealized PnL
balance.unrealizedPnl; // total unrealized PnL
balance.availableToTrade; // available margin for new trades
balance.marginRatio; // current margin ratio
// Per-asset breakdown
for (const asset of balance.assets) {
asset.asset; // "USDT", "BTC", etc.
asset.free; // available amount
asset.used; // amount in use
asset.total; // total amount
asset.walletBalance; // wallet balance
asset.usdValue; // USD equivalent
}
});
// Read the latest value without waiting for a callback
const current = tracker.get();
// Stop receiving updates
tracker.untrack();Tracking Positions
Subscribe to real-time position updates. The callback fires with the full list of open positions on every change.
const tracker = exchanges.account.trackPositions((positions) => {
for (const pos of positions) {
pos.symbol; // "BTCUSDT"
pos.side; // "long" | "short" | "both"
pos.size; // "0.5"
pos.entryPrice; // "65000.00"
pos.unrealizedPnl; // "120.50"
pos.leverage; // "10"
pos.marginType; // "cross" | "isolated"
pos.liquidationPrice; // "58000.00" or null
}
});
const current = tracker.get();
tracker.untrack();Tracking a Specific Asset
Retrieve leverage, margin type, and trade size constraints for a specific coin. Useful when preparing to place a trade.
const tracker = exchanges.account.trackAsset('ETH', (info) => {
info.coin; // "ETH"
info.leverage; // "20"
info.marginType; // "cross" | "isolated"
});
const current = tracker.get();
tracker.untrack();Managing Leverage
await exchanges.account.setLeverage('BTCUSDT', '10');
// Read cached leverage (returns null if not yet fetched)
const leverage = exchanges.account.getLeverage('BTCUSDT');Reading Full State
Access a read-only snapshot of the complete account state at any time.
const state = exchanges.account.getState();
if (state) {
state.balance; // latest balance or null
state.positions; // Map of all open positions
state.leverageSettings; // Map of symbol to leverage
state.trackedAssets; // Map of coin to asset info
state.lastUpdated; // timestamp of last update
state.initialized; // true after first snapshot
}Disconnecting
// Disconnect but keep credentials cached for reconnection
exchanges.account.disconnect();
// Full teardown: disconnect and clear all credentials
exchanges.destroy();Behavior Notes
- The WebSocket connection starts lazily when the first tracker is registered and stops when all trackers are removed.
- On unexpected disconnection, the SDK reconnects automatically with exponential backoff (1s to 30s).
- Reconnection is suppressed after explicit
disconnect()ordestroy()calls. - Credentials are held in memory only and never persisted to disk.
- All numeric values (balances, sizes, prices, PnL) are returned as strings to preserve decimal precision.
