@pear-protocol/exchanges-sdk 0.0.18 → 0.1.1
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/README.md +73 -137
- package/dist/client/base-ws.d.ts +30 -0
- package/dist/client/base-ws.js +113 -0
- package/dist/client/binance/exchange-ws.d.ts +19 -0
- package/dist/client/binance/exchange-ws.js +26 -0
- package/dist/{account/exchanges → client}/binance/rest.d.ts +2 -6
- package/dist/{account/exchanges → client}/binance/rest.js +4 -11
- package/dist/client/binance/types.d.ts +68 -0
- package/dist/client/binance/types.js +1 -0
- package/dist/client/binance/ws.d.ts +30 -0
- package/dist/client/binance/ws.js +54 -0
- package/dist/client/bybit/exchange-ws.d.ts +20 -0
- package/dist/client/bybit/exchange-ws.js +28 -0
- package/dist/{account/exchanges → client}/bybit/rest.js +3 -2
- package/dist/{account/exchanges → client}/bybit/types.d.ts +1 -9
- package/dist/client/bybit/types.js +1 -0
- package/dist/client/bybit/ws.d.ts +17 -0
- package/dist/client/bybit/ws.js +50 -0
- package/dist/client/exchange-ws.d.ts +12 -0
- package/dist/client/exchange-ws.js +10 -0
- package/dist/client/hyperliquid/exchange-ws.d.ts +15 -0
- package/dist/client/hyperliquid/exchange-ws.js +21 -0
- package/dist/client/hyperliquid/rest.d.ts +3 -0
- package/dist/client/hyperliquid/rest.js +12 -0
- package/dist/{account/exchanges → client}/hyperliquid/types.d.ts +18 -39
- package/dist/client/hyperliquid/types.js +1 -0
- package/dist/client/hyperliquid/ws.d.ts +10 -0
- package/dist/client/hyperliquid/ws.js +16 -0
- package/dist/client/index.d.ts +31 -0
- package/dist/client/index.js +47 -0
- package/dist/client/lighter/constants.d.ts +4 -0
- package/dist/client/lighter/constants.js +4 -0
- package/dist/client/lighter/exchange-ws.d.ts +15 -0
- package/dist/client/lighter/exchange-ws.js +21 -0
- package/dist/client/lighter/rest.d.ts +56 -0
- package/dist/client/lighter/rest.js +27 -0
- package/dist/client/lighter/types.d.ts +32 -0
- package/dist/client/lighter/types.js +1 -0
- package/dist/client/lighter/ws.d.ts +10 -0
- package/dist/client/lighter/ws.js +17 -0
- package/dist/client/okx/exchange-ws.d.ts +20 -0
- package/dist/client/okx/exchange-ws.js +28 -0
- package/dist/{account/exchanges → client}/okx/rest.js +2 -2
- package/dist/{account/exchanges → client}/okx/types.d.ts +1 -10
- package/dist/client/okx/types.js +1 -0
- package/dist/client/okx/ws.d.ts +17 -0
- package/dist/client/okx/ws.js +61 -0
- package/dist/helper/factory.d.ts +10 -0
- package/dist/helper/factory.js +12 -0
- package/dist/helper/index.d.ts +7 -0
- package/dist/helper/index.js +2 -0
- package/dist/helper/lighter/ethereum/abi.d.ts +66 -0
- package/dist/helper/lighter/ethereum/abi.js +40 -0
- package/dist/helper/lighter/ethereum/index.d.ts +8 -0
- package/dist/helper/lighter/ethereum/index.js +34 -0
- package/dist/helper/lighter/ethereum/types.d.ts +23 -0
- package/dist/helper/lighter/ethereum/types.js +1 -0
- package/dist/helper/lighter/helper.d.ts +9 -0
- package/dist/helper/lighter/helper.js +67 -0
- package/dist/helper/lighter/index.d.ts +6 -0
- package/dist/helper/lighter/index.js +2 -0
- package/dist/helper/lighter/types.d.ts +63 -0
- package/dist/helper/lighter/types.js +35 -0
- package/dist/helper/types.d.ts +11 -0
- package/dist/helper/types.js +1 -0
- package/dist/index.d.ts +37 -24
- package/dist/index.js +6 -21
- package/dist/sdk.d.ts +43 -0
- package/dist/sdk.js +52 -0
- package/dist/syncer/base.d.ts +33 -0
- package/dist/syncer/base.js +14 -0
- package/dist/syncer/index.d.ts +18 -0
- package/dist/syncer/index.js +1 -0
- package/dist/tracker/base.d.ts +79 -0
- package/dist/tracker/base.js +120 -0
- package/dist/tracker/binance/const.d.ts +4 -0
- package/dist/tracker/binance/const.js +4 -0
- package/dist/{account/exchanges → tracker}/binance/mapper.d.ts +4 -1
- package/dist/{account/exchanges → tracker}/binance/mapper.js +7 -6
- package/dist/tracker/binance/tracker.d.ts +60 -0
- package/dist/tracker/binance/tracker.js +181 -0
- package/dist/tracker/binance/types.d.ts +6 -0
- package/dist/{account/exchanges → tracker}/bybit/mapper.d.ts +5 -3
- package/dist/{account/exchanges → tracker}/bybit/mapper.js +11 -10
- package/dist/tracker/bybit/tracker.d.ts +51 -0
- package/dist/tracker/bybit/tracker.js +138 -0
- package/dist/tracker/bybit/types.d.ts +7 -0
- package/dist/{account/exchanges → tracker}/hyperliquid/mapper.d.ts +6 -4
- package/dist/{account/exchanges → tracker}/hyperliquid/mapper.js +18 -16
- package/dist/tracker/hyperliquid/tracker.d.ts +62 -0
- package/dist/tracker/hyperliquid/tracker.js +219 -0
- package/dist/tracker/hyperliquid/types.d.ts +23 -0
- package/dist/tracker/index.d.ts +38 -0
- package/dist/tracker/index.js +81 -0
- package/dist/tracker/lighter/const.d.ts +3 -0
- package/dist/tracker/lighter/const.js +3 -0
- package/dist/tracker/lighter/mapper.d.ts +16 -0
- package/dist/tracker/lighter/mapper.js +77 -0
- package/dist/tracker/lighter/tracker.d.ts +53 -0
- package/dist/tracker/lighter/tracker.js +150 -0
- package/dist/tracker/lighter/types.d.ts +16 -0
- package/dist/tracker/lighter/types.js +6 -0
- package/dist/{account/exchanges → tracker}/okx/mapper.d.ts +5 -3
- package/dist/{account/exchanges → tracker}/okx/mapper.js +11 -10
- package/dist/tracker/okx/tracker.d.ts +51 -0
- package/dist/tracker/okx/tracker.js +134 -0
- package/dist/tracker/okx/types.d.ts +8 -0
- package/dist/tracker/types.d.ts +63 -0
- package/dist/{account → tracker}/types.js +6 -4
- package/dist/tracker/utils.d.ts +11 -0
- package/dist/{account → tracker}/utils.js +0 -2
- package/dist/types.d.ts +50 -0
- package/dist/types.js +1 -0
- package/package.json +8 -4
- package/dist/account/account-manager.d.ts +0 -31
- package/dist/account/account-manager.js +0 -119
- package/dist/account/exchange-account.d.ts +0 -35
- package/dist/account/exchange-account.js +0 -158
- package/dist/account/exchanges/base.d.ts +0 -48
- package/dist/account/exchanges/base.js +0 -41
- package/dist/account/exchanges/binance/asset-tracker.d.ts +0 -26
- package/dist/account/exchanges/binance/asset-tracker.js +0 -38
- package/dist/account/exchanges/binance/const.d.ts +0 -10
- package/dist/account/exchanges/binance/const.js +0 -10
- package/dist/account/exchanges/binance/orchestrator.d.ts +0 -31
- package/dist/account/exchanges/binance/orchestrator.js +0 -91
- package/dist/account/exchanges/binance/state-handler.d.ts +0 -33
- package/dist/account/exchanges/binance/state-handler.js +0 -113
- package/dist/account/exchanges/binance/types.d.ts +0 -5
- package/dist/account/exchanges/binance/ws.d.ts +0 -23
- package/dist/account/exchanges/binance/ws.js +0 -69
- package/dist/account/exchanges/bybit/asset-tracker.d.ts +0 -26
- package/dist/account/exchanges/bybit/asset-tracker.js +0 -37
- package/dist/account/exchanges/bybit/const.d.ts +0 -7
- package/dist/account/exchanges/bybit/const.js +0 -7
- package/dist/account/exchanges/bybit/orchestrator.d.ts +0 -22
- package/dist/account/exchanges/bybit/orchestrator.js +0 -66
- package/dist/account/exchanges/bybit/state-handler.d.ts +0 -23
- package/dist/account/exchanges/bybit/state-handler.js +0 -70
- package/dist/account/exchanges/bybit/ws.d.ts +0 -19
- package/dist/account/exchanges/bybit/ws.js +0 -83
- package/dist/account/exchanges/hyperliquid/asset-tracker.d.ts +0 -35
- package/dist/account/exchanges/hyperliquid/asset-tracker.js +0 -83
- package/dist/account/exchanges/hyperliquid/orchestrator.d.ts +0 -26
- package/dist/account/exchanges/hyperliquid/orchestrator.js +0 -102
- package/dist/account/exchanges/hyperliquid/state-handler.d.ts +0 -25
- package/dist/account/exchanges/hyperliquid/state-handler.js +0 -104
- package/dist/account/exchanges/index.d.ts +0 -11
- package/dist/account/exchanges/index.js +0 -32
- package/dist/account/exchanges/okx/asset-tracker.d.ts +0 -26
- package/dist/account/exchanges/okx/asset-tracker.js +0 -34
- package/dist/account/exchanges/okx/const.d.ts +0 -7
- package/dist/account/exchanges/okx/const.js +0 -7
- package/dist/account/exchanges/okx/orchestrator.d.ts +0 -22
- package/dist/account/exchanges/okx/orchestrator.js +0 -57
- package/dist/account/exchanges/okx/state-handler.d.ts +0 -24
- package/dist/account/exchanges/okx/state-handler.js +0 -78
- package/dist/account/exchanges/okx/ws.d.ts +0 -20
- package/dist/account/exchanges/okx/ws.js +0 -103
- package/dist/account/index.d.ts +0 -11
- package/dist/account/index.js +0 -4
- package/dist/account/types.d.ts +0 -5
- package/dist/account/utils.d.ts +0 -10
- package/dist/credentials.d.ts +0 -28
- package/dist/credentials.js +0 -46
- package/dist/types-Caz2X4h0.d.ts +0 -151
- package/dist/utils/ws.d.ts +0 -10
- package/dist/utils/ws.js +0 -42
- /package/dist/{account/exchanges → client}/bybit/rest.d.ts +0 -0
- /package/dist/{utils → client}/hmac.d.ts +0 -0
- /package/dist/{utils → client}/hmac.js +0 -0
- /package/dist/{account/exchanges → client}/okx/rest.d.ts +0 -0
- /package/dist/{account/exchanges → tracker}/binance/types.js +0 -0
- /package/dist/{account/exchanges → tracker}/bybit/types.js +0 -0
- /package/dist/{account/exchanges → tracker}/hyperliquid/const.d.ts +0 -0
- /package/dist/{account/exchanges → tracker}/hyperliquid/const.js +0 -0
- /package/dist/{account/exchanges → tracker}/hyperliquid/types.js +0 -0
- /package/dist/{account/exchanges → tracker}/okx/types.js +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Connector } from '@pear-protocol/types';
|
|
2
|
+
import { ExchangeWsByConnector } from '../client/index.js';
|
|
3
|
+
import { SupportedCredentials } from '../types.js';
|
|
4
|
+
import { AccountTrackerConfig, AccountTracker } from './base.js';
|
|
5
|
+
export { BaseAccountTracker } from './base.js';
|
|
6
|
+
export { BinanceAccountTracker, BinanceAccountTrackerConfig } from './binance/tracker.js';
|
|
7
|
+
export { BinanceAccountType } from './binance/types.js';
|
|
8
|
+
export { BybitAccountTracker, BybitAccountTrackerConfig } from './bybit/tracker.js';
|
|
9
|
+
export { BybitAccountType } from './bybit/types.js';
|
|
10
|
+
export { HyperliquidAccountTracker, HyperliquidAccountTrackerConfig } from './hyperliquid/tracker.js';
|
|
11
|
+
export { HyperliquidAccountType } from './hyperliquid/types.js';
|
|
12
|
+
export { LighterAccountTracker, LighterAccountTrackerConfig } from './lighter/tracker.js';
|
|
13
|
+
export { LighterAccountType } from './lighter/types.js';
|
|
14
|
+
export { OkxAccountTracker, OkxAccountTrackerConfig } from './okx/tracker.js';
|
|
15
|
+
export { OkxAccountType } from './okx/types.js';
|
|
16
|
+
export { ACCOUNT_TYPE_LABELS, AccountBalance, AccountPosition, AccountType, AssetBalance, BalanceCallback, ExchangeState, MarginMode, PositionsCallback, StateUpdate, TrackedAssetCallback, TrackedAssetInfo } from './types.js';
|
|
17
|
+
import '../client/binance/exchange-ws.js';
|
|
18
|
+
import '../client/base-ws.js';
|
|
19
|
+
import 'partysocket';
|
|
20
|
+
import '../client/exchange-ws.js';
|
|
21
|
+
import '../client/binance/ws.js';
|
|
22
|
+
import '../client/bybit/exchange-ws.js';
|
|
23
|
+
import '../client/bybit/ws.js';
|
|
24
|
+
import '../client/hyperliquid/exchange-ws.js';
|
|
25
|
+
import '../client/hyperliquid/ws.js';
|
|
26
|
+
import '../client/lighter/exchange-ws.js';
|
|
27
|
+
import '../client/lighter/ws.js';
|
|
28
|
+
import '../client/okx/exchange-ws.js';
|
|
29
|
+
import '../client/okx/ws.js';
|
|
30
|
+
import '@pear-protocol/core-sdk';
|
|
31
|
+
|
|
32
|
+
type CreateAccountTrackerConfig<E extends Connector> = AccountTrackerConfig & {
|
|
33
|
+
credentials: SupportedCredentials;
|
|
34
|
+
ws: ExchangeWsByConnector[E];
|
|
35
|
+
};
|
|
36
|
+
declare function createAccountTracker<E extends Connector>(exchange: E, config: CreateAccountTrackerConfig<E>): AccountTracker;
|
|
37
|
+
|
|
38
|
+
export { AccountTracker, AccountTrackerConfig, type CreateAccountTrackerConfig, createAccountTracker };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { BinanceAccountTracker } from './binance/tracker';
|
|
2
|
+
export { BinanceAccountTracker } from './binance/tracker';
|
|
3
|
+
import { BybitAccountTracker } from './bybit/tracker';
|
|
4
|
+
export { BybitAccountTracker } from './bybit/tracker';
|
|
5
|
+
import { HyperliquidAccountTracker } from './hyperliquid/tracker';
|
|
6
|
+
export { HyperliquidAccountTracker } from './hyperliquid/tracker';
|
|
7
|
+
import { LighterAccountTracker } from './lighter/tracker';
|
|
8
|
+
export { LighterAccountTracker } from './lighter/tracker';
|
|
9
|
+
import { OkxAccountTracker } from './okx/tracker';
|
|
10
|
+
export { OkxAccountTracker } from './okx/tracker';
|
|
11
|
+
export { BaseAccountTracker } from './base';
|
|
12
|
+
export { BinanceAccountType } from './binance/types';
|
|
13
|
+
export { BybitAccountType } from './bybit/types';
|
|
14
|
+
export { HyperliquidAccountType } from './hyperliquid/types';
|
|
15
|
+
export { LighterAccountType } from './lighter/types';
|
|
16
|
+
export { OkxAccountType } from './okx/types';
|
|
17
|
+
export * from './types';
|
|
18
|
+
|
|
19
|
+
function createAccountTracker(exchange, config) {
|
|
20
|
+
let tracker;
|
|
21
|
+
switch (exchange) {
|
|
22
|
+
case "binance": {
|
|
23
|
+
const ws = config.ws;
|
|
24
|
+
tracker = new BinanceAccountTracker({
|
|
25
|
+
demo: config.demo,
|
|
26
|
+
onError: config.onError,
|
|
27
|
+
credentials: config.credentials,
|
|
28
|
+
userDataWs: ws.userData,
|
|
29
|
+
wsApiWs: ws.wsApi
|
|
30
|
+
});
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
case "bybit": {
|
|
34
|
+
const ws = config.ws;
|
|
35
|
+
tracker = new BybitAccountTracker({
|
|
36
|
+
demo: config.demo,
|
|
37
|
+
onError: config.onError,
|
|
38
|
+
credentials: config.credentials,
|
|
39
|
+
ws
|
|
40
|
+
});
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
case "okx": {
|
|
44
|
+
const ws = config.ws;
|
|
45
|
+
tracker = new OkxAccountTracker({
|
|
46
|
+
demo: config.demo,
|
|
47
|
+
onError: config.onError,
|
|
48
|
+
credentials: config.credentials,
|
|
49
|
+
ws
|
|
50
|
+
});
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
case "hyperliquid": {
|
|
54
|
+
const ws = config.ws;
|
|
55
|
+
tracker = new HyperliquidAccountTracker({
|
|
56
|
+
demo: config.demo,
|
|
57
|
+
onError: config.onError,
|
|
58
|
+
credentials: config.credentials,
|
|
59
|
+
ws: ws.main
|
|
60
|
+
});
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
case "lighter": {
|
|
64
|
+
const ws = config.ws;
|
|
65
|
+
tracker = new LighterAccountTracker({
|
|
66
|
+
demo: config.demo,
|
|
67
|
+
onError: config.onError,
|
|
68
|
+
credentials: config.credentials,
|
|
69
|
+
ws: ws.main
|
|
70
|
+
});
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
default: {
|
|
74
|
+
const _exhaustive = exchange;
|
|
75
|
+
throw new Error(`Unsupported exchange: ${String(_exhaustive)}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return tracker;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export { createAccountTracker };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { RawAsset, RawPosition } from '../../client/lighter/types.js';
|
|
2
|
+
import { AccountBalance, AccountPosition, TrackedAssetInfo } from '../types.js';
|
|
3
|
+
import { AggregatedLighterSummary } from './types.js';
|
|
4
|
+
import '../binance/types.js';
|
|
5
|
+
import '../bybit/types.js';
|
|
6
|
+
import '../hyperliquid/types.js';
|
|
7
|
+
import '../okx/types.js';
|
|
8
|
+
|
|
9
|
+
declare function mapBalance(summary: AggregatedLighterSummary, assetsByAssetId: Map<string, RawAsset>): AccountBalance;
|
|
10
|
+
declare function mapPositions(raw: Record<string, RawPosition>): {
|
|
11
|
+
positions: Map<string, AccountPosition>;
|
|
12
|
+
trackedAssets: Map<string, TrackedAssetInfo>;
|
|
13
|
+
};
|
|
14
|
+
declare function leverageFromImf(imfPct: string): string;
|
|
15
|
+
|
|
16
|
+
export { leverageFromImf, mapBalance, mapPositions };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import BigNumber from 'bignumber.js';
|
|
2
|
+
import { positionKey } from '../utils';
|
|
3
|
+
import { QUOTE_ASSET } from './const';
|
|
4
|
+
import { LighterAccountType } from './types';
|
|
5
|
+
|
|
6
|
+
function mapBalance(summary, assetsByAssetId) {
|
|
7
|
+
const free = {};
|
|
8
|
+
const used = {};
|
|
9
|
+
const total = {};
|
|
10
|
+
const assets = [];
|
|
11
|
+
for (const a of assetsByAssetId.values()) {
|
|
12
|
+
const balBN = new BigNumber(a.balance || "0");
|
|
13
|
+
const lockedBN = new BigNumber(a.locked_balance || "0");
|
|
14
|
+
const totalAmt = balBN.plus(lockedBN).toFixed();
|
|
15
|
+
free[a.symbol] = a.balance;
|
|
16
|
+
used[a.symbol] = a.locked_balance;
|
|
17
|
+
total[a.symbol] = totalAmt;
|
|
18
|
+
assets.push({
|
|
19
|
+
asset: a.symbol,
|
|
20
|
+
free: a.balance,
|
|
21
|
+
used: a.locked_balance,
|
|
22
|
+
total: totalAmt,
|
|
23
|
+
walletBalance: totalAmt,
|
|
24
|
+
usdValue: a.symbol === QUOTE_ASSET ? totalAmt : "0"
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
const portfolioValueBN = new BigNumber(summary.portfolioValue);
|
|
28
|
+
const marginUsageFrac = new BigNumber(summary.marginUsagePct).div(100);
|
|
29
|
+
const unrealizedPnl = portfolioValueBN.minus(summary.collateral).toFixed(6);
|
|
30
|
+
const initialMarginUsed = marginUsageFrac.multipliedBy(portfolioValueBN).toFixed(6);
|
|
31
|
+
const marginRatio = marginUsageFrac.toFixed(4);
|
|
32
|
+
return {
|
|
33
|
+
accountType: LighterAccountType.BASIC,
|
|
34
|
+
free,
|
|
35
|
+
used,
|
|
36
|
+
total,
|
|
37
|
+
availableToTrade: summary.availableToTrade,
|
|
38
|
+
totalEquity: summary.portfolioValue,
|
|
39
|
+
walletBalance: summary.collateral,
|
|
40
|
+
unrealizedPnl,
|
|
41
|
+
initialMarginUsed,
|
|
42
|
+
maintenanceMargin: "0",
|
|
43
|
+
marginRatio,
|
|
44
|
+
assets,
|
|
45
|
+
timestamp: Date.now()
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function mapPositions(raw) {
|
|
49
|
+
const positions = /* @__PURE__ */ new Map();
|
|
50
|
+
const trackedAssets = /* @__PURE__ */ new Map();
|
|
51
|
+
for (const p of Object.values(raw)) {
|
|
52
|
+
const sizeBN = new BigNumber(p.position || "0");
|
|
53
|
+
const side = p.sign === -1 ? "short" : "long";
|
|
54
|
+
const leverage = leverageFromImf(p.initial_margin_fraction);
|
|
55
|
+
const marginType = p.margin_mode === 1 ? "isolated" : "cross";
|
|
56
|
+
const marketId = String(p.market_id);
|
|
57
|
+
positions.set(positionKey(p.symbol, side), {
|
|
58
|
+
symbol: p.symbol,
|
|
59
|
+
side,
|
|
60
|
+
size: sizeBN.isFinite() && !sizeBN.isZero() ? sizeBN.toFixed() : "0",
|
|
61
|
+
entryPrice: p.avg_entry_price || "0",
|
|
62
|
+
unrealizedPnl: p.unrealized_pnl || "0",
|
|
63
|
+
leverage,
|
|
64
|
+
marginType,
|
|
65
|
+
liquidationPrice: p.liquidation_price && p.liquidation_price !== "0" ? p.liquidation_price : null
|
|
66
|
+
});
|
|
67
|
+
trackedAssets.set(marketId, { coin: p.symbol, leverage, marginType });
|
|
68
|
+
}
|
|
69
|
+
return { positions, trackedAssets };
|
|
70
|
+
}
|
|
71
|
+
function leverageFromImf(imfPct) {
|
|
72
|
+
const pct = new BigNumber(imfPct);
|
|
73
|
+
if (!pct.isFinite() || pct.lte(0)) return "1";
|
|
74
|
+
return new BigNumber(100).div(pct).integerValue(BigNumber.ROUND_FLOOR).toFixed();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export { leverageFromImf, mapBalance, mapPositions };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { LighterWs } from '../../client/lighter/ws.js';
|
|
2
|
+
import { SupportedCredentials } from '../../types.js';
|
|
3
|
+
import { BaseAccountTracker, AccountTrackerConfig } from '../base.js';
|
|
4
|
+
import '../../client/base-ws.js';
|
|
5
|
+
import 'partysocket';
|
|
6
|
+
import '@pear-protocol/core-sdk';
|
|
7
|
+
import '@pear-protocol/types';
|
|
8
|
+
import '../../client/binance/exchange-ws.js';
|
|
9
|
+
import '../../client/exchange-ws.js';
|
|
10
|
+
import '../../client/binance/ws.js';
|
|
11
|
+
import '../../client/bybit/exchange-ws.js';
|
|
12
|
+
import '../../client/bybit/ws.js';
|
|
13
|
+
import '../../client/hyperliquid/exchange-ws.js';
|
|
14
|
+
import '../../client/hyperliquid/ws.js';
|
|
15
|
+
import '../../client/lighter/exchange-ws.js';
|
|
16
|
+
import '../../client/okx/exchange-ws.js';
|
|
17
|
+
import '../../client/okx/ws.js';
|
|
18
|
+
import '../types.js';
|
|
19
|
+
import '../binance/types.js';
|
|
20
|
+
import '../bybit/types.js';
|
|
21
|
+
import '../hyperliquid/types.js';
|
|
22
|
+
import './types.js';
|
|
23
|
+
import '../okx/types.js';
|
|
24
|
+
|
|
25
|
+
type LighterAccountTrackerConfig = AccountTrackerConfig & {
|
|
26
|
+
credentials: SupportedCredentials;
|
|
27
|
+
ws: LighterWs;
|
|
28
|
+
};
|
|
29
|
+
declare class LighterAccountTracker extends BaseAccountTracker {
|
|
30
|
+
private readonly accountIdentifier;
|
|
31
|
+
private readonly ws;
|
|
32
|
+
private messageListenerId;
|
|
33
|
+
private openListenerId;
|
|
34
|
+
private pollTimer;
|
|
35
|
+
private assetsByAssetId;
|
|
36
|
+
private summary;
|
|
37
|
+
private hasAssets;
|
|
38
|
+
constructor(config: LighterAccountTrackerConfig);
|
|
39
|
+
start(): Promise<void>;
|
|
40
|
+
protected cleanupConnections(): Promise<void>;
|
|
41
|
+
get isConnected(): boolean;
|
|
42
|
+
protected ensureAssetTracked(_coin: string): void;
|
|
43
|
+
protected releaseAsset(_coin: string): void;
|
|
44
|
+
private sendStaticSubs;
|
|
45
|
+
private routeRaw;
|
|
46
|
+
private handle;
|
|
47
|
+
private onAccountAll;
|
|
48
|
+
private onUserStats;
|
|
49
|
+
private buildBalance;
|
|
50
|
+
private pollAccount;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { LighterAccountTracker, type LighterAccountTrackerConfig };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import BigNumber from 'bignumber.js';
|
|
2
|
+
import { fetchOrderBookDetails, fetchAccount } from '../../client/lighter/rest';
|
|
3
|
+
import { BaseAccountTracker } from '../base';
|
|
4
|
+
import { leverageFromImf, mapPositions, mapBalance } from './mapper';
|
|
5
|
+
|
|
6
|
+
class LighterAccountTracker extends BaseAccountTracker {
|
|
7
|
+
accountIdentifier;
|
|
8
|
+
ws;
|
|
9
|
+
messageListenerId = null;
|
|
10
|
+
openListenerId = null;
|
|
11
|
+
pollTimer = null;
|
|
12
|
+
assetsByAssetId = /* @__PURE__ */ new Map();
|
|
13
|
+
summary = null;
|
|
14
|
+
hasAssets = false;
|
|
15
|
+
constructor(config) {
|
|
16
|
+
super(config);
|
|
17
|
+
const creds = config.credentials;
|
|
18
|
+
this.credentials = config.credentials;
|
|
19
|
+
this.accountIdentifier = creds.accountIdentifier;
|
|
20
|
+
this.ws = config.ws;
|
|
21
|
+
}
|
|
22
|
+
async start() {
|
|
23
|
+
const markets = await fetchOrderBookDetails();
|
|
24
|
+
const trackedAssets = /* @__PURE__ */ new Map();
|
|
25
|
+
for (const m of markets) {
|
|
26
|
+
trackedAssets.set(String(m.market_id), {
|
|
27
|
+
coin: m.symbol,
|
|
28
|
+
leverage: leverageFromImf(new BigNumber(m.default_initial_margin_fraction).div(100).toFixed()),
|
|
29
|
+
marginType: "cross"
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
this.onStateUpdate({ trackedAssets });
|
|
33
|
+
this.messageListenerId = this.ws.addMessageListener((raw) => this.routeRaw(raw));
|
|
34
|
+
this.openListenerId = this.ws.addOpenListener(() => this.sendStaticSubs());
|
|
35
|
+
this.sendStaticSubs();
|
|
36
|
+
this.pollAccount();
|
|
37
|
+
this.pollTimer = setInterval(() => this.pollAccount(), 2e3);
|
|
38
|
+
}
|
|
39
|
+
async cleanupConnections() {
|
|
40
|
+
if (this.pollTimer) {
|
|
41
|
+
clearInterval(this.pollTimer);
|
|
42
|
+
this.pollTimer = null;
|
|
43
|
+
}
|
|
44
|
+
if (this.messageListenerId) {
|
|
45
|
+
this.ws.removeMessageListener(this.messageListenerId);
|
|
46
|
+
this.messageListenerId = null;
|
|
47
|
+
}
|
|
48
|
+
if (this.openListenerId) {
|
|
49
|
+
this.ws.removeOpenListener(this.openListenerId);
|
|
50
|
+
this.openListenerId = null;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
get isConnected() {
|
|
54
|
+
return this.ws.connected;
|
|
55
|
+
}
|
|
56
|
+
ensureAssetTracked(_coin) {
|
|
57
|
+
}
|
|
58
|
+
releaseAsset(_coin) {
|
|
59
|
+
}
|
|
60
|
+
sendStaticSubs() {
|
|
61
|
+
this.ws.send({
|
|
62
|
+
type: "subscribe",
|
|
63
|
+
channel: `account_all/${this.accountIdentifier}`
|
|
64
|
+
});
|
|
65
|
+
this.ws.send({
|
|
66
|
+
type: "subscribe",
|
|
67
|
+
channel: `user_stats/${this.accountIdentifier}`
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
routeRaw(raw) {
|
|
71
|
+
try {
|
|
72
|
+
const msg = JSON.parse(raw);
|
|
73
|
+
if (!msg.type) return;
|
|
74
|
+
if (msg.type === "subscribed/account_all" || msg.type === "update/account_all") {
|
|
75
|
+
this.handle({ kind: "account_all", data: msg });
|
|
76
|
+
} else if (msg.type === "subscribed/user_stats" || msg.type === "update/user_stats") {
|
|
77
|
+
this.handle({ kind: "user_stats", data: msg });
|
|
78
|
+
}
|
|
79
|
+
} catch (err) {
|
|
80
|
+
this.onError(err instanceof Error ? err : new Error(String(err)));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
handle(event) {
|
|
84
|
+
if (event.kind === "account_all") {
|
|
85
|
+
this.onAccountAll(event.data);
|
|
86
|
+
} else {
|
|
87
|
+
this.onUserStats(event.data);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
onAccountAll(data) {
|
|
91
|
+
const update = {};
|
|
92
|
+
if (data.assets) {
|
|
93
|
+
for (const [id, asset] of Object.entries(data.assets)) {
|
|
94
|
+
this.assetsByAssetId.set(id, asset);
|
|
95
|
+
}
|
|
96
|
+
this.hasAssets = true;
|
|
97
|
+
}
|
|
98
|
+
if (data.positions && Object.keys(data.positions).length > 0) {
|
|
99
|
+
const { positions, trackedAssets } = mapPositions(data.positions);
|
|
100
|
+
update.positions = positions;
|
|
101
|
+
update.trackedAssets = trackedAssets;
|
|
102
|
+
}
|
|
103
|
+
const balance = this.buildBalance();
|
|
104
|
+
if (balance) update.balance = balance;
|
|
105
|
+
if (Object.keys(update).length > 0) this.onStateUpdate(update);
|
|
106
|
+
}
|
|
107
|
+
onUserStats(data) {
|
|
108
|
+
const s = data.stats;
|
|
109
|
+
this.summary = {
|
|
110
|
+
collateral: s.collateral || "0",
|
|
111
|
+
portfolioValue: s.portfolio_value || "0",
|
|
112
|
+
availableToTrade: s.available_balance || "0",
|
|
113
|
+
marginUsagePct: s.margin_usage || "0"
|
|
114
|
+
};
|
|
115
|
+
const balance = this.buildBalance();
|
|
116
|
+
if (balance) this.onStateUpdate({ balance });
|
|
117
|
+
}
|
|
118
|
+
buildBalance() {
|
|
119
|
+
if (!this.summary || !this.hasAssets) return null;
|
|
120
|
+
return mapBalance(this.summary, this.assetsByAssetId);
|
|
121
|
+
}
|
|
122
|
+
async pollAccount() {
|
|
123
|
+
try {
|
|
124
|
+
const accountIndex = Number(this.accountIdentifier);
|
|
125
|
+
const data = await fetchAccount(accountIndex);
|
|
126
|
+
const account = data.accounts[0];
|
|
127
|
+
if (!account?.positions?.length) return;
|
|
128
|
+
const posRecord = {};
|
|
129
|
+
for (const p of account.positions) {
|
|
130
|
+
posRecord[String(p.market_id)] = {
|
|
131
|
+
market_id: p.market_id,
|
|
132
|
+
symbol: p.symbol,
|
|
133
|
+
initial_margin_fraction: p.initial_margin_fraction,
|
|
134
|
+
sign: p.sign,
|
|
135
|
+
position: p.position,
|
|
136
|
+
avg_entry_price: p.avg_entry_price,
|
|
137
|
+
unrealized_pnl: p.unrealized_pnl,
|
|
138
|
+
liquidation_price: p.liquidation_price,
|
|
139
|
+
margin_mode: p.margin_mode
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
const { positions, trackedAssets } = mapPositions(posRecord);
|
|
143
|
+
this.onStateUpdate({ positions, trackedAssets });
|
|
144
|
+
} catch (err) {
|
|
145
|
+
this.onError(err instanceof Error ? err : new Error(String(err)));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export { LighterAccountTracker };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
declare enum LighterAccountType {
|
|
2
|
+
BASIC = "basic"
|
|
3
|
+
}
|
|
4
|
+
interface LighterCoinBalance {
|
|
5
|
+
symbol: string;
|
|
6
|
+
balance: string;
|
|
7
|
+
lockedBalance: string;
|
|
8
|
+
}
|
|
9
|
+
interface AggregatedLighterSummary {
|
|
10
|
+
collateral: string;
|
|
11
|
+
portfolioValue: string;
|
|
12
|
+
availableToTrade: string;
|
|
13
|
+
marginUsagePct: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { type AggregatedLighterSummary, LighterAccountType, type LighterCoinBalance };
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import '
|
|
1
|
+
import { OkxRawBalance, OkxRawBalanceDetail, OkxRawPosition } from '../../client/okx/types.js';
|
|
2
|
+
import { AccountBalance, AccountPosition } from '../types.js';
|
|
3
|
+
import { OkxAccountType } from './types.js';
|
|
4
|
+
import '../binance/types.js';
|
|
4
5
|
import '../bybit/types.js';
|
|
5
6
|
import '../hyperliquid/types.js';
|
|
7
|
+
import '../lighter/types.js';
|
|
6
8
|
|
|
7
9
|
declare function mergeRawCoins(existing: Map<string, OkxRawBalanceDetail>, incoming: OkxRawBalanceDetail[]): Map<string, OkxRawBalanceDetail>;
|
|
8
10
|
declare function buildBalance(raw: OkxRawBalance, coins: Map<string, OkxRawBalanceDetail>, accountType: OkxAccountType | null): AccountBalance | null;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import BigNumber from 'bignumber.js';
|
|
2
|
+
import { positionKey } from '../utils';
|
|
2
3
|
import { OkxAccountType } from './types';
|
|
3
4
|
|
|
4
5
|
function mergeRawCoins(existing, incoming) {
|
|
@@ -15,18 +16,18 @@ function buildBalance(raw, coins, accountType) {
|
|
|
15
16
|
const used = {};
|
|
16
17
|
const total = {};
|
|
17
18
|
const assets = [];
|
|
18
|
-
let walletBalanceSum = 0;
|
|
19
|
+
let walletBalanceSum = new BigNumber(0);
|
|
19
20
|
for (const [, d] of coins) {
|
|
20
21
|
const eq = d.eq ?? "0";
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
22
|
+
const eqBN = new BigNumber(eq);
|
|
23
|
+
const cashBN = new BigNumber(d.cashBal ?? "0");
|
|
24
|
+
if (eqBN.isZero() && cashBN.isZero()) continue;
|
|
24
25
|
const coinFree = isSpot ? d.availBal ?? "0" : d.availEq || d.availBal || "0";
|
|
25
|
-
const coinUsed = (
|
|
26
|
+
const coinUsed = eqBN.minus(coinFree).toString();
|
|
26
27
|
free[d.ccy] = coinFree;
|
|
27
28
|
used[d.ccy] = coinUsed;
|
|
28
29
|
total[d.ccy] = eq;
|
|
29
|
-
walletBalanceSum
|
|
30
|
+
walletBalanceSum = walletBalanceSum.plus(cashBN);
|
|
30
31
|
assets.push({
|
|
31
32
|
asset: d.ccy,
|
|
32
33
|
free: coinFree,
|
|
@@ -44,7 +45,7 @@ function buildBalance(raw, coins, accountType) {
|
|
|
44
45
|
total,
|
|
45
46
|
availableToTrade,
|
|
46
47
|
totalEquity: raw.totalEq ?? "0",
|
|
47
|
-
walletBalance: walletBalanceSum.
|
|
48
|
+
walletBalance: walletBalanceSum.toFixed(),
|
|
48
49
|
unrealizedPnl: raw.upl || "0",
|
|
49
50
|
initialMarginUsed: raw.imr || "0",
|
|
50
51
|
maintenanceMargin: raw.mmr || "0",
|
|
@@ -54,11 +55,11 @@ function buildBalance(raw, coins, accountType) {
|
|
|
54
55
|
};
|
|
55
56
|
}
|
|
56
57
|
function mapSinglePosition(p) {
|
|
57
|
-
const
|
|
58
|
+
const posBN = new BigNumber(p.pos ?? "0");
|
|
58
59
|
let side;
|
|
59
60
|
if (p.posSide === "long") side = "long";
|
|
60
61
|
else if (p.posSide === "short") side = "short";
|
|
61
|
-
else side =
|
|
62
|
+
else side = posBN.isNegative() ? "short" : "long";
|
|
62
63
|
const rawSize = p.pos ?? "0";
|
|
63
64
|
let size;
|
|
64
65
|
if (rawSize === "0" || rawSize === "") {
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { OkxExchangeWs } from '../../client/okx/exchange-ws.js';
|
|
2
|
+
import { SupportedCredentials } from '../../types.js';
|
|
3
|
+
import { BaseAccountTracker, AccountTrackerConfig } from '../base.js';
|
|
4
|
+
import '@pear-protocol/types';
|
|
5
|
+
import '../../client/base-ws.js';
|
|
6
|
+
import 'partysocket';
|
|
7
|
+
import '../../client/exchange-ws.js';
|
|
8
|
+
import '../../client/okx/ws.js';
|
|
9
|
+
import '@pear-protocol/core-sdk';
|
|
10
|
+
import '../../client/binance/exchange-ws.js';
|
|
11
|
+
import '../../client/binance/ws.js';
|
|
12
|
+
import '../../client/bybit/exchange-ws.js';
|
|
13
|
+
import '../../client/bybit/ws.js';
|
|
14
|
+
import '../../client/hyperliquid/exchange-ws.js';
|
|
15
|
+
import '../../client/hyperliquid/ws.js';
|
|
16
|
+
import '../../client/lighter/exchange-ws.js';
|
|
17
|
+
import '../../client/lighter/ws.js';
|
|
18
|
+
import '../types.js';
|
|
19
|
+
import '../binance/types.js';
|
|
20
|
+
import '../bybit/types.js';
|
|
21
|
+
import '../hyperliquid/types.js';
|
|
22
|
+
import '../lighter/types.js';
|
|
23
|
+
import './types.js';
|
|
24
|
+
|
|
25
|
+
type OkxAccountTrackerConfig = AccountTrackerConfig & {
|
|
26
|
+
credentials: SupportedCredentials;
|
|
27
|
+
ws: OkxExchangeWs;
|
|
28
|
+
};
|
|
29
|
+
declare class OkxAccountTracker extends BaseAccountTracker {
|
|
30
|
+
private readonly creds;
|
|
31
|
+
private readonly ws;
|
|
32
|
+
private messageListenerId;
|
|
33
|
+
private openListenerId;
|
|
34
|
+
private rawCoins;
|
|
35
|
+
private lastBalance;
|
|
36
|
+
private accountType;
|
|
37
|
+
private trackedAssetInfos;
|
|
38
|
+
constructor(config: OkxAccountTrackerConfig);
|
|
39
|
+
start(): Promise<void>;
|
|
40
|
+
protected cleanupConnections(): Promise<void>;
|
|
41
|
+
get isConnected(): boolean;
|
|
42
|
+
protected ensureAssetTracked(instId: string): void;
|
|
43
|
+
protected releaseAsset(instId: string): void;
|
|
44
|
+
private subscribe;
|
|
45
|
+
private handleInitialData;
|
|
46
|
+
private routeRaw;
|
|
47
|
+
private handleMessage;
|
|
48
|
+
private handleBalanceUpdate;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export { OkxAccountTracker, type OkxAccountTrackerConfig };
|