
Research
/Security News
Miasma Mini Shai-Hulud Hits ImmobiliareLabs npm Packages
Miasma Mini Shai-Hulud hits @immobiliarelabs Backstage plugins, targeting GitLab and LDAP auth packages on npm.
@pear-protocol/market-sdk
Advanced tools
SDK for real-time market data across cryptocurrency derivative exchanges. Provides charting with multiple visualization modes (weighted ratio, price ratio, performance), aggregated order book depth, and historical funding rate analysis through a unified, exchange-agnostic interface.
| Exchange | Connector Name |
|---|---|
| Binance | binance |
| Bybit | bybit |
| Hyperliquid | hyperliquid |
| OKX | okx |
| Lighter | lighter |
npm install @pear-protocol/market-sdk
import { Chart, FundingRate, Orderbook, CreateTransport } from '@pear-protocol/market-sdk';
const transport = CreateTransport('hyperliquid');
// Chart
const chart = new Chart({
transport,
longTokens: [{ symbol: 'BTC', weight: 50 }, { symbol: 'ETH', weight: 50 }],
shortTokens: [{ symbol: 'SOL', weight: 100 }],
candleInterval: '1h',
});
const bars = await chart.getBars('weighted-ratio', startTime, endTime);
const subId = chart.subscribeRealtimeBars('weighted-ratio', (bar) => {
console.log(bar.time, bar.open, bar.high, bar.low, bar.close);
});
// Funding rates
const fundingRate = new FundingRate({
transport,
longTokens: [{ symbol: 'ETH', weight: 0.6 }],
shortTokens: [{ symbol: 'BTC', weight: 0.4 }],
interval: '1d',
});
const rates = await fundingRate.getAssetRates('ETH');
const basketRates = await fundingRate.getBasketRates();
// Order book
const orderbook = new Orderbook({
transport,
symbol: 'BTC',
aggregation: 10,
depth: 15,
});
orderbook.subscribe((snapshot) => {
console.log('bids:', snapshot.bids, 'asks:', snapshot.asks);
});
// Cleanup
chart.unsubscribeRealtimeBars(subId);
chart.destroy();
fundingRate.destroy();
orderbook.destroy();
transport.destroy();
import { Chart, CreateTransport } from '@pear-protocol/market-sdk';
const transport = CreateTransport('binance');
const chart = new Chart({
transport,
longTokens: [{ symbol: 'BTC', weight: 60 }, { symbol: 'ETH', weight: 40 }],
shortTokens: [{ symbol: 'SOL', weight: 100 }],
candleInterval: '1h',
});
ChartConfig| Field | Type | Default | Description |
|---|---|---|---|
transport | Transport | — | WebSocket transport instance |
longTokens | TokenSelection[] | [] | Tokens on the long side with weights |
shortTokens | TokenSelection[] | [] | Tokens on the short side with weights |
candleInterval | CandleInterval | '1h' | Candle timeframe |
TokenSelection{ symbol: string; weight: number }
CandleInterval'1m' | '3m' | '5m' | '15m' | '30m' | '1h' | '2h' | '4h' | '8h' | '12h' | '1d' | '3d' | '1w' | '1M'
Change the tokens or candle interval at any time. Both clear cached data and baseline prices.
chart.setTokens(
[{ symbol: 'BTC', weight: 100 }],
[{ symbol: 'ETH', weight: 100 }],
);
chart.setCandleInterval('15m');
Fetch historical OHLC bars for a given chart type and time range.
const bars = await chart.getBars('weighted-ratio', startTime, endTime);
for (const bar of bars) {
bar.time; // timestamp (ms)
bar.open; // open price
bar.high; // high price
bar.low; // low price
bar.close; // close price
}
| Type | Description |
|---|---|
'weighted-ratio' | Geometric mean ratio using token weights as exponents |
'price-ratio' | Weighted sum of long prices divided by weighted sum of short prices |
'performance' | Percentage performance relative to the earliest bar in the range |
Fetch bars for one specific symbol in the configured token set.
const bars = await chart.getAssetBars('BTC', startTime, endTime);
Subscribe to live bar updates. The WebSocket connection is established automatically on the first subscription.
const subId = chart.subscribeRealtimeBars('weighted-ratio', (bar) => {
console.log(bar.time, bar.open, bar.high, bar.low, bar.close);
});
// Single-asset real-time bars
const assetSubId = chart.subscribeRealtimeAssetBars('ETH', (bar) => {
console.log(bar.time, bar.close);
});
// Stop receiving updates
chart.unsubscribeRealtimeBars(subId);
chart.unsubscribeRealtimeBars(assetSubId);
Get the earliest timestamp for which historical data is available.
const boundary = chart.getEffectiveDataBoundary(); // number | null
// Clear all cached historical data and baseline prices
chart.clearCache();
chart.destroy();
The Orderbook connects to the exchange WebSocket immediately on construction and begins receiving depth updates.
import { Orderbook, CreateTransport } from '@pear-protocol/market-sdk';
const transport = CreateTransport('hyperliquid');
const orderbook = new Orderbook({
transport,
symbol: 'BTC',
aggregation: 10,
depth: 15,
});
OrderbookConfig| Field | Type | Default | Description |
|---|---|---|---|
transport | Transport | — | WebSocket transport instance |
symbol | string | — | Trading pair symbol |
aggregation | number | 0 | Bucket size for price aggregation (0 = no aggregation) |
depth | number | 10 | Number of price levels per side |
snapshottedPrice | number | — | Current mid-price for server-side aggregation params |
Subscribe to real-time order book snapshots. The callback fires on every depth update from the exchange.
const subId = orderbook.subscribe((snapshot) => {
snapshot.symbol; // "BTC"
snapshot.aggregation; // active bucket size
snapshot.ts; // last update timestamp (ms)
for (const bid of snapshot.bids) { // price-descending
bid.price; // price level
bid.size; // base-asset quantity
}
for (const ask of snapshot.asks) { // price-ascending
ask.price;
ask.size;
}
});
// Stop receiving updates
orderbook.unsubscribe(subId);
Access the latest order book state without subscribing. Returns null if no data has been received yet.
const snapshot = orderbook.getSnapshot();
if (snapshot) {
console.log(snapshot.bids, snapshot.asks);
}
Change the price aggregation bucket size at any time. Listeners are notified immediately with a re-aggregated snapshot.
orderbook.setAggregation(100); // aggregate to $100 buckets
orderbook.setAggregation(0); // disable aggregation
const current = orderbook.getAggregation();
Access the current best bid, best ask, spread, and spread percentage. Returns null values when the book has not loaded yet.
const { bestBid, bestAsk, spread, spreadPct } = orderbook.bbo;
// bestBid: "65000.5" | null
// bestAsk: "65001.0" | null
// spread: "0.5" | null
// spreadPct: "0.00077" | null
Compute recommended aggregation bucket sizes for a given connector and price level.
import { getAvailableAggregations } from '@pear-protocol/market-sdk';
// CEX exchanges (Binance, Bybit, OKX) — uses tick size
const levels = getAvailableAggregations('binance', { tickSize: 0.1, midPrice: 65000 });
// e.g. [0.1, 1, 10, 100, 1000]
// Hyperliquid — uses max decimal places
const levels = getAvailableAggregations('hyperliquid', { maxDecimals: 2, midPrice: 65000 });
Update the mid-price used for server-side aggregation parameters (e.g. Hyperliquid).
orderbook.setSnapshottedPrice(65250.5);
orderbook.destroy();
The underlying transport is owned by the caller and must be destroyed separately.
import { FundingRate, CreateTransport } from '@pear-protocol/market-sdk';
const transport = CreateTransport('hyperliquid');
const fundingRate = new FundingRate({
transport,
longTokens: [{ symbol: 'ETH', weight: 0.6 }],
shortTokens: [{ symbol: 'BTC', weight: 0.4 }],
});
FundingRateConfig| Field | Type | Default | Description |
|---|---|---|---|
transport | Transport | — | Transport instance (used to determine the exchange) |
longTokens | TokenSelection[] | [] | Tokens on the long side with weights |
shortTokens | TokenSelection[] | [] | Tokens on the short side with weights |
Aggregation level and lookback duration are passed per call to getAssetRates and getBasketRates.
FundingRateAggregation'none' | '1d' | '1w' | '1M'
When set to 'none', raw funding rates are returned at each exchange's native settlement frequency (1h for Hyperliquid, 8h for Binance/Bybit/OKX). For '1d', '1w', and '1M', rates are summed within each period.
FundingRateDuration'1w' | '1m' | '1y'
The lookback window for fetching data, ending at the current time.
To avoid returning too few data points, each aggregation level enforces a minimum duration. If the requested duration is shorter than the minimum, it is automatically bumped up.
| Aggregation | Minimum Duration |
|---|---|
'none' | '1w' |
'1d' | '1m' |
'1w' | '1y' |
'1M' | '1y' |
Fetch funding rates for a single token.
// Defaults: aggregation='none', duration='1m'
const rates = await fundingRate.getAssetRates('ETH');
// Daily aggregation over the last year
const dailyRates = await fundingRate.getAssetRates('ETH', '1d', '1y');
getAssetRates(
symbol: string,
aggregation?: FundingRateAggregation, // default: 'none'
duration?: FundingRateDuration, // default: '1m'
): Promise<FundingRateEntry[]>
Compute the weighted net funding rate across all configured tokens. Positive rate = user earns funding, negative = user pays.
const basketRates = await fundingRate.getBasketRates();
const monthlyBasket = await fundingRate.getBasketRates('1M', '1y');
The net rate at each time point is calculated as:
netRate = sum(shortWeight × rate) - sum(longWeight × rate)
Only time points where all tokens have data are included.
getBasketRates(
aggregation?: FundingRateAggregation, // default: 'none'
duration?: FundingRateDuration, // default: '1m'
): Promise<FundingRateEntry[]>
FundingRateEntry{
time: number; // bucket start timestamp (ms)
rate: number; // summed rate for the bucket (raw rate when aggregation='none')
annualizedRate?: number; // rate annualized to a yearly figure
}
For fixed aggregations the annualization multiplier is 365 (1d), 52 (1w), or 12 (1M). For 'none', the multiplier is inferred from the average gap between raw entries (MS_PER_YEAR / avgGapMs); if there are fewer than two entries to infer from, annualizedRate is omitted.
fundingRate.setTokens(
[{ symbol: 'ETH', weight: 0.5 }, { symbol: 'SOL', weight: 0.5 }],
[{ symbol: 'BTC', weight: 1.0 }],
);
fundingRate.destroy();
FAQs
Pear Protocol Market SDK
The npm package @pear-protocol/market-sdk receives a total of 38 weekly downloads. As such, @pear-protocol/market-sdk popularity was classified as not popular.
We found that @pear-protocol/market-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 4 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
/Security News
Miasma Mini Shai-Hulud hits @immobiliarelabs Backstage plugins, targeting GitLab and LDAP auth packages on npm.

Security News
Rolldown paused Rust React Compiler integration after a 5MB binary size increase raised concerns about shipping React-specific code to all Vite users.

Security News
/Research
Mini Shai-Hulud expands into the Go ecosystem after hitting LeoPlatform npm packages and targeting GitHub Actions workflows.