@pear-protocol/market-sdk 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chart/collector/helpers.js +2 -1
- package/dist/chart/collector/lighter.d.ts +4 -2
- package/dist/chart/collector/lighter.js +8 -8
- package/dist/chart/ws/index.js +1 -0
- package/dist/funding-rate/fetcher/index.js +2 -1
- package/dist/funding-rate/fetcher/lighter.d.ts +3 -2
- package/dist/funding-rate/fetcher/lighter.js +3 -3
- package/dist/orderbook/ws/index.js +1 -0
- package/dist/shared/lighter-hosts.d.ts +18 -0
- package/dist/shared/lighter-hosts.js +10 -0
- package/dist/transport/index.js +2 -1
- package/dist/transport/lighter.d.ts +9 -5
- package/dist/transport/lighter.js +10 -5
- package/package.json +2 -2
|
@@ -17,7 +17,8 @@ async function fetchHistoricalCandles(connector, symbol, startTime, endTime, int
|
|
|
17
17
|
case "okx":
|
|
18
18
|
return fetchHistoricalCandles$2(symbol, startTime, endTime, interval);
|
|
19
19
|
case "lighter":
|
|
20
|
-
|
|
20
|
+
case "lighter_rhc":
|
|
21
|
+
return fetchHistoricalCandles$1(connector, symbol, startTime, endTime, interval, authToken);
|
|
21
22
|
default:
|
|
22
23
|
throw new Error(`Unsupported connector: ${connector}`);
|
|
23
24
|
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { LighterConnector } from '../../shared/lighter-hosts.js';
|
|
1
2
|
import { CandleInterval, CandleData } from '../types.js';
|
|
2
|
-
import '../../transport/index.js';
|
|
3
3
|
import '@pear-protocol/types';
|
|
4
|
+
import '../../transport/index.js';
|
|
4
5
|
import '../../shared/types.js';
|
|
5
6
|
import '../../transport/base-transport.js';
|
|
6
7
|
import 'partysocket';
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
/** Reads one deployment's candles for a range, synthesizing the resolutions it does not serve. */
|
|
10
|
+
declare function fetchHistoricalCandles(connector: LighterConnector, symbol: string, startTime: number, endTime: number, interval: CandleInterval, authToken?: string): Promise<CandleData[]>;
|
|
9
11
|
|
|
10
12
|
export { fetchHistoricalCandles };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import { LIGHTER_BASE_URLS } from '../../shared/lighter-hosts';
|
|
1
2
|
import { getIntervalSeconds } from '../utils';
|
|
2
3
|
import { getWeekStart, aggregateDailyCandlesToWeekly } from '../weekly';
|
|
3
4
|
|
|
4
5
|
var __defProp = Object.defineProperty;
|
|
5
6
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
-
const BASE_URL = "https://mainnet.zklighter.elliot.ai";
|
|
7
7
|
const MAX_LIMIT = 500;
|
|
8
8
|
const DAY_MS = getIntervalSeconds("1d") * 1e3;
|
|
9
9
|
const RESOLUTION_MAP = {
|
|
@@ -16,25 +16,25 @@ const RESOLUTION_MAP = {
|
|
|
16
16
|
"12h": "12h",
|
|
17
17
|
"1d": "1d"
|
|
18
18
|
};
|
|
19
|
-
async function fetchHistoricalCandles(symbol, startTime, endTime, interval, authToken) {
|
|
19
|
+
async function fetchHistoricalCandles(connector, symbol, startTime, endTime, interval, authToken) {
|
|
20
20
|
if (interval === "1w") {
|
|
21
|
-
const dailyCandles = await fetchDailyCandlesChunked(symbol, getWeekStart(startTime), endTime, authToken);
|
|
21
|
+
const dailyCandles = await fetchDailyCandlesChunked(connector, symbol, getWeekStart(startTime), endTime, authToken);
|
|
22
22
|
return aggregateDailyCandlesToWeekly(dailyCandles);
|
|
23
23
|
}
|
|
24
|
-
return fetchResolutionCandles(symbol, startTime, endTime, interval, authToken);
|
|
24
|
+
return fetchResolutionCandles(connector, symbol, startTime, endTime, interval, authToken);
|
|
25
25
|
}
|
|
26
26
|
__name(fetchHistoricalCandles, "fetchHistoricalCandles");
|
|
27
|
-
async function fetchDailyCandlesChunked(symbol, startTime, endTime, authToken) {
|
|
27
|
+
async function fetchDailyCandlesChunked(connector, symbol, startTime, endTime, authToken) {
|
|
28
28
|
const chunkMs = MAX_LIMIT * DAY_MS;
|
|
29
29
|
const chunkStarts = [];
|
|
30
30
|
for (let chunkStart = startTime; chunkStart < endTime; chunkStart += chunkMs) {
|
|
31
31
|
chunkStarts.push(chunkStart);
|
|
32
32
|
}
|
|
33
|
-
const chunks = await Promise.all(chunkStarts.map((chunkStart) => fetchResolutionCandles(symbol, chunkStart, Math.min(chunkStart + chunkMs, endTime), "1d", authToken)));
|
|
33
|
+
const chunks = await Promise.all(chunkStarts.map((chunkStart) => fetchResolutionCandles(connector, symbol, chunkStart, Math.min(chunkStart + chunkMs, endTime), "1d", authToken)));
|
|
34
34
|
return chunks.flat();
|
|
35
35
|
}
|
|
36
36
|
__name(fetchDailyCandlesChunked, "fetchDailyCandlesChunked");
|
|
37
|
-
async function fetchResolutionCandles(symbol, startTime, endTime, interval, authToken) {
|
|
37
|
+
async function fetchResolutionCandles(connector, symbol, startTime, endTime, interval, authToken) {
|
|
38
38
|
const resolution = RESOLUTION_MAP[interval];
|
|
39
39
|
if (!resolution) throw new Error(`Lighter does not support the '${interval}' interval`);
|
|
40
40
|
const intervalMs = getIntervalSeconds(interval) * 1e3;
|
|
@@ -46,7 +46,7 @@ async function fetchResolutionCandles(symbol, startTime, endTime, interval, auth
|
|
|
46
46
|
end_timestamp: String(endTime),
|
|
47
47
|
count_back: String(countBack)
|
|
48
48
|
});
|
|
49
|
-
const response = await fetch(`${
|
|
49
|
+
const response = await fetch(`${LIGHTER_BASE_URLS[connector]}/api/v1/candles?${params}`, authToken ? {
|
|
50
50
|
headers: {
|
|
51
51
|
authorization: authToken
|
|
52
52
|
}
|
package/dist/chart/ws/index.js
CHANGED
|
@@ -18,6 +18,7 @@ function createCandleWs(transport, connector, onCandle) {
|
|
|
18
18
|
case "okx":
|
|
19
19
|
return new OkxCandleWs(transport, onCandle);
|
|
20
20
|
case "lighter":
|
|
21
|
+
case "lighter_rhc":
|
|
21
22
|
return new LighterCandleWs(transport, onCandle);
|
|
22
23
|
default: {
|
|
23
24
|
const _exhaustive = connector;
|
|
@@ -17,7 +17,8 @@ async function fetchHistoricalFundingRates(connector, symbol, startTime, endTime
|
|
|
17
17
|
case "okx":
|
|
18
18
|
return fetchHistoricalFundingRates$2(symbol, startTime, endTime);
|
|
19
19
|
case "lighter":
|
|
20
|
-
|
|
20
|
+
case "lighter_rhc":
|
|
21
|
+
return fetchHistoricalFundingRates$1(connector, symbol, startTime, endTime, duration, authToken);
|
|
21
22
|
default:
|
|
22
23
|
throw new Error(`Unsupported connector: ${connector}`);
|
|
23
24
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { LighterConnector } from '../../shared/lighter-hosts.js';
|
|
1
2
|
import { FundingRateDuration, FundingRateEntry } from '../types.js';
|
|
2
|
-
import '../../transport/index.js';
|
|
3
3
|
import '@pear-protocol/types';
|
|
4
|
+
import '../../transport/index.js';
|
|
4
5
|
import '../../shared/types.js';
|
|
5
6
|
import '../../transport/base-transport.js';
|
|
6
7
|
import 'partysocket';
|
|
7
8
|
|
|
8
|
-
declare function fetchHistoricalFundingRates(symbol: string, startTime: number, endTime: number, _duration: FundingRateDuration, authToken?: string): Promise<FundingRateEntry[]>;
|
|
9
|
+
declare function fetchHistoricalFundingRates(connector: LighterConnector, symbol: string, startTime: number, endTime: number, _duration: FundingRateDuration, authToken?: string): Promise<FundingRateEntry[]>;
|
|
9
10
|
|
|
10
11
|
export { fetchHistoricalFundingRates };
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import BigNumber from 'bignumber.js';
|
|
2
|
+
import { LIGHTER_BASE_URLS } from '../../shared/lighter-hosts';
|
|
2
3
|
import { httpGet } from './http-client';
|
|
3
4
|
|
|
4
5
|
var __defProp = Object.defineProperty;
|
|
5
6
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
-
const BASE_URL = "https://mainnet.zklighter.elliot.ai";
|
|
7
7
|
const MAX_LIMIT = 500;
|
|
8
|
-
async function fetchHistoricalFundingRates(symbol, startTime, endTime, _duration, authToken) {
|
|
8
|
+
async function fetchHistoricalFundingRates(connector, symbol, startTime, endTime, _duration, authToken) {
|
|
9
9
|
const intervalMs = 60 * 60 * 1e3;
|
|
10
10
|
const allRates = [];
|
|
11
11
|
let cursor = startTime;
|
|
12
12
|
while (cursor < endTime) {
|
|
13
13
|
const countBack = Math.min(Math.ceil((endTime - cursor) / intervalMs) + 1, MAX_LIMIT);
|
|
14
|
-
const data = await httpGet(`${
|
|
14
|
+
const data = await httpGet(`${LIGHTER_BASE_URLS[connector]}/api/v1/fundings`, {
|
|
15
15
|
market_id: symbol,
|
|
16
16
|
resolution: "1h",
|
|
17
17
|
start_timestamp: String(cursor),
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Connector } from '@pear-protocol/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The connector values that are deployments of the Lighter stack. The deployments share the
|
|
5
|
+
* protocol but nothing else — hosts and market indices are per-deployment, so every Lighter code
|
|
6
|
+
* path in this SDK resolves its host from the connector value.
|
|
7
|
+
*/
|
|
8
|
+
type LighterConnector = Extract<Connector, 'lighter' | 'lighter_rhc'>;
|
|
9
|
+
/**
|
|
10
|
+
* REST host per Lighter deployment.
|
|
11
|
+
*/
|
|
12
|
+
declare const LIGHTER_BASE_URLS: Record<LighterConnector, string>;
|
|
13
|
+
/**
|
|
14
|
+
* WebSocket stream URL per Lighter deployment.
|
|
15
|
+
*/
|
|
16
|
+
declare const LIGHTER_WS_URLS: Record<LighterConnector, string>;
|
|
17
|
+
|
|
18
|
+
export { LIGHTER_BASE_URLS, LIGHTER_WS_URLS, type LighterConnector };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const LIGHTER_BASE_URLS = {
|
|
2
|
+
lighter: "https://mainnet.zklighter.elliot.ai",
|
|
3
|
+
lighter_rhc: "https://api.rh.lighter.xyz"
|
|
4
|
+
};
|
|
5
|
+
const LIGHTER_WS_URLS = {
|
|
6
|
+
lighter: "wss://mainnet.zklighter.elliot.ai/stream",
|
|
7
|
+
lighter_rhc: "wss://api.rh.lighter.xyz/stream"
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export { LIGHTER_BASE_URLS, LIGHTER_WS_URLS };
|
package/dist/transport/index.js
CHANGED
|
@@ -18,7 +18,8 @@ function CreateTransport(connector, options) {
|
|
|
18
18
|
case "hyperliquid":
|
|
19
19
|
return new HyperliquidTransport();
|
|
20
20
|
case "lighter":
|
|
21
|
-
|
|
21
|
+
case "lighter_rhc":
|
|
22
|
+
return new LighterTransport(connector, options?.authToken);
|
|
22
23
|
default: {
|
|
23
24
|
const _exhaustive = connector;
|
|
24
25
|
throw new Error(`Unsupported connector: ${String(_exhaustive)}`);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LighterConnector } from '../shared/lighter-hosts.js';
|
|
2
2
|
import { AuthTokenProvider, WsMessage } from '../shared/types.js';
|
|
3
3
|
import { BaseTransport } from './base-transport.js';
|
|
4
|
+
import '@pear-protocol/types';
|
|
4
5
|
import 'partysocket';
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -10,14 +11,17 @@ import 'partysocket';
|
|
|
10
11
|
*/
|
|
11
12
|
|
|
12
13
|
declare class LighterTransport extends BaseTransport {
|
|
13
|
-
readonly connector:
|
|
14
|
+
readonly connector: LighterConnector;
|
|
14
15
|
private readonly authTokenProvider;
|
|
15
16
|
private cachedAuthToken;
|
|
16
17
|
private authRefreshTimer;
|
|
17
18
|
private mintInFlight;
|
|
18
19
|
private wantsConnection;
|
|
19
|
-
/**
|
|
20
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Takes the deployment this transport streams from, and the caller's minter; without a minter
|
|
22
|
+
* this transport stays anonymous for its whole life.
|
|
23
|
+
*/
|
|
24
|
+
constructor(connector: LighterConnector, authTokenProvider?: AuthTokenProvider);
|
|
21
25
|
/** Holds the socket until a first token lands, so the opening subscriptions carry it. */
|
|
22
26
|
connect(): void;
|
|
23
27
|
/** Tears the socket down and drops the identity that belonged to it. */
|
|
@@ -26,7 +30,7 @@ declare class LighterTransport extends BaseTransport {
|
|
|
26
30
|
get authToken(): string | undefined;
|
|
27
31
|
/** Refreshes the cached token; the caller's provider owns expiry and request coalescing. */
|
|
28
32
|
retrieveAuthToken(): Promise<string | undefined>;
|
|
29
|
-
/** The
|
|
33
|
+
/** The deployment's public market-data stream, which serves both authenticated and anonymous traffic. */
|
|
30
34
|
protected getWsUrl(): string;
|
|
31
35
|
/** How often the socket must speak to stay open. */
|
|
32
36
|
protected getPingIntervalMs(): number;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { LIGHTER_WS_URLS } from '../shared/lighter-hosts';
|
|
1
2
|
import { BaseTransport } from './base-transport';
|
|
2
3
|
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
@@ -7,15 +8,19 @@ class LighterTransport extends BaseTransport {
|
|
|
7
8
|
static {
|
|
8
9
|
__name(this, "LighterTransport");
|
|
9
10
|
}
|
|
10
|
-
connector
|
|
11
|
+
connector;
|
|
11
12
|
authTokenProvider;
|
|
12
13
|
cachedAuthToken;
|
|
13
14
|
authRefreshTimer = null;
|
|
14
15
|
mintInFlight = false;
|
|
15
16
|
wantsConnection = false;
|
|
16
|
-
/**
|
|
17
|
-
|
|
17
|
+
/**
|
|
18
|
+
* Takes the deployment this transport streams from, and the caller's minter; without a minter
|
|
19
|
+
* this transport stays anonymous for its whole life.
|
|
20
|
+
*/
|
|
21
|
+
constructor(connector, authTokenProvider) {
|
|
18
22
|
super();
|
|
23
|
+
this.connector = connector;
|
|
19
24
|
this.authTokenProvider = authTokenProvider;
|
|
20
25
|
}
|
|
21
26
|
/** Holds the socket until a first token lands, so the opening subscriptions carry it. */
|
|
@@ -61,9 +66,9 @@ class LighterTransport extends BaseTransport {
|
|
|
61
66
|
}
|
|
62
67
|
return this.cachedAuthToken;
|
|
63
68
|
}
|
|
64
|
-
/** The
|
|
69
|
+
/** The deployment's public market-data stream, which serves both authenticated and anonymous traffic. */
|
|
65
70
|
getWsUrl() {
|
|
66
|
-
return
|
|
71
|
+
return LIGHTER_WS_URLS[this.connector];
|
|
67
72
|
}
|
|
68
73
|
/** How often the socket must speak to stay open. */
|
|
69
74
|
getPingIntervalMs() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pear-protocol/market-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Pear Protocol Market SDK",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"typecheck": "tsc --noEmit"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@pear-protocol/types": "^2.
|
|
29
|
+
"@pear-protocol/types": "^2.2.0",
|
|
30
30
|
"bignumber.js": "^9.1.2",
|
|
31
31
|
"partysocket": "^1.0.3"
|
|
32
32
|
},
|