@xyra-trade/perps
v1.0.2
Published
TypeScript SDK for interacting with Xyra Perps
Downloads
60
Readme
@xyra-trade/perps
TypeScript SDK for interacting with Xyra Perps.
Installation
npm install @xyra-trade/perps
# or
pnpm add @xyra-trade/perpsRequirements
- Node.js >= 22
Quick Start
import { XyraPerps } from "@xyra-trade/perps";
const sdk = new XyraPerps({
contractAddress: "0xabc...",
apiBaseUrl: "https://api.xyra.trade/api/v1",
wsBaseUrl: "wss://api.xyra.trade/ws",
tradingAccount: "0xdef...", // optional — required for positions, orders, history
});
await sdk.initialize();
// Build transaction payloads for wallet submission
const payload = sdk.buildLimitOrder("ETH-USD", 0.1, 2500.0, true);
await wallet.signAndSubmitTransaction(payload.toDict());Configuration
const sdk = new XyraPerps({
contractAddress: "0x...", // required
apiBaseUrl: "...", // required
wsBaseUrl: "...", // required
tradingAccount: "0x...", // optional — required for account data
});Clients
| Property | Description |
|----------------------|----------------------------------------------------|
| sdk.rest | HTTP REST client for market data and account |
| sdk.ws | WebSocket client for real-time data streams |
| sdk.payloads | Build unsigned transaction payloads |
| sdk.markets | Cached MarketInfo[] — populated by initialize() |
| sdk.tradingAccount | Trading account address from config (if set) |
Building Transactions
After initialize(), use build* methods to create TransactionPayload objects for wallet submission:
import { TimeInForce } from "@xyra-trade/perps";
// Limit order: buy 0.1 ETH at $2500
const payload = sdk.buildLimitOrder("ETH-USD", 0.1, 2500.0, true);
await wallet.signAndSubmitTransaction(payload.toDict());
// With options
const payload = sdk.buildLimitOrder("ETH-USD", 0.1, 2500.0, true, {
timeInForce: TimeInForce.POST_ONLY,
clientOrderId: "my-order-001",
});
// Market order: sell 0.05 ETH
const payload = sdk.buildMarketOrder("ETH-USD", 0.05, false);
// Stop-limit: sell 0.1 ETH with limit at $2400, trigger at $2450
const payload = sdk.buildStopLimitOrder("ETH-USD", 0.1, 2400.0, false, 2450.0);
// Stop-market
const payload = sdk.buildStopMarketOrder("ETH-USD", 0.1, false, 2450.0);
// Take-profit limit
const payload = sdk.buildTakeLimitOrder("ETH-USD", 0.1, 2700.0, false, 2680.0);
// Take-profit market
const payload = sdk.buildTakeMarketOrder("ETH-USD", 0.1, false, 2680.0);Order Options
interface OrderOptions {
tradingAccount?: string; // override default trading account
timeInForce?: TimeInForce;
reduceOnly?: boolean;
tpTrigger?: bigint | null;
slTrigger?: bigint | null;
clientOrderId?: string | null;
}REST Client (sdk.rest)
Market Data
await sdk.rest.getHealth();
const { markets } = await sdk.rest.getMarkets();
const { market } = await sdk.rest.getMarket("0xmarketAddress");
const { trades } = await sdk.rest.getTrades("0xmarketAddress", { limit: 50 });
const orderbook = await sdk.rest.getOrderbook("0xmarketAddress", { depth: 20 });
const { price } = await sdk.rest.getPrice("0xmarketAddress");
const { funding } = await sdk.rest.getFunding("0xmarketAddress");
const history = await sdk.rest.getFundingHistory("0xmarketAddress", { limit: 100 });
const stats = await sdk.rest.getStats();
const marketStats = await sdk.rest.getMarketStats("0xmarketAddress");Account Data
const address = "0xtrader";
await sdk.rest.getAccount(address);
await sdk.rest.getPositions(address);
await sdk.rest.getOpenOrders(address);
await sdk.rest.getCollateral(address);
await sdk.rest.getOrderHistory(address, { limit: 50, status: "filled" });
await sdk.rest.getTradeHistory(address, { limit: 50, market: "0xmarket" });
await sdk.rest.getAccountFundingHistory(address, { limit: 50 });
await sdk.rest.getCollateralHistory(address, { limit: 50 });WebSocket Client (sdk.ws)
The WebSocket client reconnects automatically and replays subscriptions after reconnect.
await sdk.ws.connect();
// Public channels
await sdk.ws.subscribeTrades("0xmarket", (data, type, txVersion) => console.log(data));
await sdk.ws.subscribeOrderbook("0xmarket", (data, type) => console.log(data), 20);
await sdk.ws.subscribeTicker("0xmarket", (data) => console.log(data));
await sdk.ws.subscribePrices("0xmarket", (data) => console.log(data));
await sdk.ws.subscribeFunding("0xmarket", (data) => console.log(data));
// Private channels (require account address)
await sdk.ws.subscribeOrders("0xtrader", (data, type) => console.log(data));
await sdk.ws.subscribePositions("0xtrader", (data, type) => console.log(data));
await sdk.ws.subscribeCollateral("0xtrader", (data) => console.log(data));
// History channels
await sdk.ws.subscribeOrderHistory("0xtrader", (data, type) => console.log(data));
await sdk.ws.subscribeTradeHistory("0xtrader", (data, type) => console.log(data));
await sdk.ws.subscribeFundingHistory("0xtrader", (data) => console.log(data));
await sdk.ws.subscribeCollateralHistory("0xtrader", (data) => console.log(data));
// Global positions feed
await sdk.ws.subscribeAllPositions((data, type) => console.log(data));
await sdk.ws.unsubscribe("trades", "0xmarket");
sdk.ws.disconnect();Error Handling
import { XyraApiError, XyraWsError } from "@xyra-trade/perps";
try {
await sdk.rest.getMarkets();
} catch (err) {
if (err instanceof XyraApiError) {
console.error("API error:", err.status, err.body);
} else if (err instanceof XyraWsError) {
console.error("WebSocket error:", err.message, err.code);
}
}Market Utilities
import { Market, MarketConfig } from "@xyra-trade/perps";
// After initialize(), Market instances are used internally.
// For manual construction:
const config = new MarketConfig("ETH-USD", 10n, 10000n, 10n, 50n);
const market = new Market(config, "0xmarket");
// Human ↔ on-chain conversions (string-based — no float imprecision)
const lots = market.toLots(0.1); // 0.1 ETH → 1000n lots
const ticks = market.toTicks(2500.0); // $2500 → 25000n ticks
const eth = market.fromLots(1000n); // 1000n lots → 0.1
const usd = market.fromTicks(25000n); // 25000n ticks → 2500.0
// Position estimates
const liqPrice = market.estimateLiquidationPrice(2500, 10, true /* long */);
const margin = market.estimateRequiredMargin(0.1, 2500, 10);
const pnl = market.calculateUnrealizedPnl(2500, 0.1, true, 2600);LLM Documentation
For a token-efficient SDK reference optimized for LLMs and AI coding tools, see llms.txt.
Contributing
See CONTRIBUTING.md for build/test commands and release conventions.
License
MIT
