@pear-protocol/exchanges-sdk 0.0.17 → 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,134 @@
|
|
|
1
|
+
import { fetchAccountConfig, fetchBalance, fetchPositions, fetchLeverageInfo } from '../../client/okx/rest';
|
|
2
|
+
import { BaseAccountTracker } from '../base';
|
|
3
|
+
import { acctLvToAccountType, mergeRawCoins, buildBalance, mapPositions, mapPositionUpdates } from './mapper';
|
|
4
|
+
|
|
5
|
+
class OkxAccountTracker extends BaseAccountTracker {
|
|
6
|
+
creds;
|
|
7
|
+
ws;
|
|
8
|
+
messageListenerId = null;
|
|
9
|
+
openListenerId = null;
|
|
10
|
+
rawCoins = /* @__PURE__ */ new Map();
|
|
11
|
+
lastBalance = null;
|
|
12
|
+
accountType = null;
|
|
13
|
+
trackedAssetInfos = /* @__PURE__ */ new Map();
|
|
14
|
+
constructor(config) {
|
|
15
|
+
super(config);
|
|
16
|
+
this.credentials = config.credentials;
|
|
17
|
+
this.creds = config.credentials;
|
|
18
|
+
this.ws = config.ws;
|
|
19
|
+
}
|
|
20
|
+
async start() {
|
|
21
|
+
const [config, balance, positions] = await Promise.all([
|
|
22
|
+
fetchAccountConfig(this.creds, this.demo),
|
|
23
|
+
fetchBalance(this.creds, this.demo),
|
|
24
|
+
fetchPositions(this.creds, this.demo)
|
|
25
|
+
]);
|
|
26
|
+
this.accountType = acctLvToAccountType(config.acctLv);
|
|
27
|
+
this.handleInitialData(balance, positions);
|
|
28
|
+
this.messageListenerId = this.ws.main.addMessageListener((raw) => this.routeRaw(raw));
|
|
29
|
+
this.openListenerId = this.ws.main.addOpenListener(() => {
|
|
30
|
+
this.ws.login().then(() => this.subscribe()).catch((err) => this.onError(err));
|
|
31
|
+
});
|
|
32
|
+
this.subscribe();
|
|
33
|
+
}
|
|
34
|
+
async cleanupConnections() {
|
|
35
|
+
if (this.messageListenerId) {
|
|
36
|
+
this.ws.main.removeMessageListener(this.messageListenerId);
|
|
37
|
+
this.messageListenerId = null;
|
|
38
|
+
}
|
|
39
|
+
if (this.openListenerId) {
|
|
40
|
+
this.ws.main.removeOpenListener(this.openListenerId);
|
|
41
|
+
this.openListenerId = null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
get isConnected() {
|
|
45
|
+
return this.ws.isConnected;
|
|
46
|
+
}
|
|
47
|
+
ensureAssetTracked(instId) {
|
|
48
|
+
if (this.trackedAssetInfos.has(instId)) return;
|
|
49
|
+
fetchLeverageInfo(this.creds, instId, this.demo).then((info) => {
|
|
50
|
+
const leverage = info?.lever || "0";
|
|
51
|
+
const marginType = info?.mgnMode;
|
|
52
|
+
const trackedAssetInfo = { coin: instId, leverage, marginType };
|
|
53
|
+
this.trackedAssetInfos.set(instId, trackedAssetInfo);
|
|
54
|
+
const trackedAssets = /* @__PURE__ */ new Map([[instId, trackedAssetInfo]]);
|
|
55
|
+
this.onStateUpdate({ trackedAssets });
|
|
56
|
+
}).catch((err) => this.onError(err instanceof Error ? err : new Error(String(err))));
|
|
57
|
+
}
|
|
58
|
+
releaseAsset(instId) {
|
|
59
|
+
this.trackedAssetInfos.delete(instId);
|
|
60
|
+
this.onStateUpdate({ trackedAssets: new Map(this.trackedAssetInfos) });
|
|
61
|
+
}
|
|
62
|
+
subscribe() {
|
|
63
|
+
this.ws.main.send({
|
|
64
|
+
op: "subscribe",
|
|
65
|
+
args: [{ channel: "account" }, { channel: "positions", instType: "SWAP" }]
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
handleInitialData(balance, positions) {
|
|
69
|
+
this.lastBalance = balance;
|
|
70
|
+
this.rawCoins = mergeRawCoins(/* @__PURE__ */ new Map(), balance.details ?? []);
|
|
71
|
+
const built = buildBalance(balance, this.rawCoins, this.accountType);
|
|
72
|
+
if (built) this.onStateUpdate({ balance: built });
|
|
73
|
+
this.onStateUpdate({ positions: mapPositions(positions) });
|
|
74
|
+
}
|
|
75
|
+
routeRaw(raw) {
|
|
76
|
+
if (raw === "pong") return;
|
|
77
|
+
try {
|
|
78
|
+
const msg = JSON.parse(raw);
|
|
79
|
+
if (msg.event) return;
|
|
80
|
+
if (msg.arg && msg.data) {
|
|
81
|
+
this.handleMessage(msg);
|
|
82
|
+
}
|
|
83
|
+
} catch (err) {
|
|
84
|
+
this.onError(err instanceof Error ? err : new Error(String(err)));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
handleMessage(msg) {
|
|
88
|
+
if (msg.arg.channel === "account") {
|
|
89
|
+
const raw = msg.data[0];
|
|
90
|
+
if (raw) this.handleBalanceUpdate(raw);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (msg.arg.channel === "positions") {
|
|
94
|
+
const posMsg = msg;
|
|
95
|
+
const action = posMsg.action ?? "update";
|
|
96
|
+
const rawPositions = posMsg.data;
|
|
97
|
+
const positions = action === "snapshot" ? mapPositions(rawPositions) : mapPositionUpdates(rawPositions);
|
|
98
|
+
if (positions.size === 0 && action !== "snapshot") return;
|
|
99
|
+
const trackedAssets = /* @__PURE__ */ new Map();
|
|
100
|
+
for (const p of rawPositions) {
|
|
101
|
+
const existing = this.trackedAssetInfos.get(p.instId);
|
|
102
|
+
if (existing) {
|
|
103
|
+
const leverage = p.lever || existing.leverage;
|
|
104
|
+
const marginType = p.mgnMode;
|
|
105
|
+
const updated = { ...existing, leverage, marginType };
|
|
106
|
+
this.trackedAssetInfos.set(p.instId, updated);
|
|
107
|
+
trackedAssets.set(p.instId, updated);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
this.onStateUpdate({
|
|
111
|
+
positions,
|
|
112
|
+
...trackedAssets.size > 0 ? { trackedAssets } : {}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
handleBalanceUpdate(raw) {
|
|
117
|
+
this.rawCoins = mergeRawCoins(this.rawCoins, raw.details ?? []);
|
|
118
|
+
const merged = this.lastBalance ? {
|
|
119
|
+
totalEq: raw.totalEq || this.lastBalance.totalEq,
|
|
120
|
+
adjEq: raw.adjEq || this.lastBalance.adjEq,
|
|
121
|
+
availEq: raw.availEq || this.lastBalance.availEq,
|
|
122
|
+
mmr: raw.mmr || this.lastBalance.mmr,
|
|
123
|
+
imr: raw.imr || this.lastBalance.imr,
|
|
124
|
+
upl: raw.upl || this.lastBalance.upl,
|
|
125
|
+
mgnRatio: raw.mgnRatio || this.lastBalance.mgnRatio,
|
|
126
|
+
details: raw.details ?? this.lastBalance.details
|
|
127
|
+
} : raw;
|
|
128
|
+
this.lastBalance = merged;
|
|
129
|
+
const built = buildBalance(merged, this.rawCoins, this.accountType);
|
|
130
|
+
if (built) this.onStateUpdate({ balance: built });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export { OkxAccountTracker };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { BinanceAccountType } from './binance/types.js';
|
|
2
|
+
import { BybitAccountType } from './bybit/types.js';
|
|
3
|
+
import { HyperliquidAccountType } from './hyperliquid/types.js';
|
|
4
|
+
import { LighterAccountType } from './lighter/types.js';
|
|
5
|
+
import { OkxAccountType } from './okx/types.js';
|
|
6
|
+
|
|
7
|
+
type MarginMode = 'cross' | 'isolated';
|
|
8
|
+
type AccountType = BinanceAccountType | BybitAccountType | HyperliquidAccountType | LighterAccountType | OkxAccountType;
|
|
9
|
+
declare const ACCOUNT_TYPE_LABELS: Record<AccountType, string>;
|
|
10
|
+
interface AssetBalance {
|
|
11
|
+
asset: string;
|
|
12
|
+
free: string;
|
|
13
|
+
used: string;
|
|
14
|
+
total: string;
|
|
15
|
+
walletBalance: string;
|
|
16
|
+
usdValue: string;
|
|
17
|
+
}
|
|
18
|
+
interface AccountBalance {
|
|
19
|
+
accountType: AccountType;
|
|
20
|
+
free: Record<string, string>;
|
|
21
|
+
used: Record<string, string>;
|
|
22
|
+
total: Record<string, string>;
|
|
23
|
+
availableToTrade: string;
|
|
24
|
+
totalEquity: string;
|
|
25
|
+
walletBalance: string;
|
|
26
|
+
unrealizedPnl: string;
|
|
27
|
+
initialMarginUsed: string;
|
|
28
|
+
maintenanceMargin: string;
|
|
29
|
+
marginRatio: string;
|
|
30
|
+
assets: AssetBalance[];
|
|
31
|
+
timestamp: number;
|
|
32
|
+
}
|
|
33
|
+
interface AccountPosition {
|
|
34
|
+
symbol: string;
|
|
35
|
+
side: 'long' | 'short' | 'both';
|
|
36
|
+
size: string;
|
|
37
|
+
entryPrice: string;
|
|
38
|
+
unrealizedPnl: string;
|
|
39
|
+
leverage: string;
|
|
40
|
+
marginType: MarginMode;
|
|
41
|
+
liquidationPrice: string | null;
|
|
42
|
+
}
|
|
43
|
+
interface TrackedAssetInfo {
|
|
44
|
+
coin: string;
|
|
45
|
+
leverage: string;
|
|
46
|
+
marginType: MarginMode;
|
|
47
|
+
}
|
|
48
|
+
interface ExchangeState {
|
|
49
|
+
balance: AccountBalance | null;
|
|
50
|
+
positions: Map<string, AccountPosition>;
|
|
51
|
+
lastUpdated: number;
|
|
52
|
+
initialized: boolean;
|
|
53
|
+
}
|
|
54
|
+
type BalanceCallback = (balance: AccountBalance) => void;
|
|
55
|
+
type PositionsCallback = (positions: AccountPosition[]) => void;
|
|
56
|
+
type TrackedAssetCallback = (info: TrackedAssetInfo) => void;
|
|
57
|
+
interface StateUpdate {
|
|
58
|
+
balance?: AccountBalance;
|
|
59
|
+
positions?: Map<string, AccountPosition>;
|
|
60
|
+
trackedAssets?: Map<string, TrackedAssetInfo>;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { ACCOUNT_TYPE_LABELS, type AccountBalance, type AccountPosition, type AccountType, type AssetBalance, type BalanceCallback, type ExchangeState, type MarginMode, type PositionsCallback, type StateUpdate, type TrackedAssetCallback, type TrackedAssetInfo };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { BinanceAccountType } from './
|
|
2
|
-
import { BybitAccountType } from './
|
|
3
|
-
import { HyperliquidAccountType } from './
|
|
4
|
-
import {
|
|
1
|
+
import { BinanceAccountType } from './binance/types';
|
|
2
|
+
import { BybitAccountType } from './bybit/types';
|
|
3
|
+
import { HyperliquidAccountType } from './hyperliquid/types';
|
|
4
|
+
import { LighterAccountType } from './lighter/types';
|
|
5
|
+
import { OkxAccountType } from './okx/types';
|
|
5
6
|
|
|
6
7
|
const ACCOUNT_TYPE_LABELS = {
|
|
7
8
|
[BinanceAccountType.SINGLE_ASSET]: "Single-Asset Mode",
|
|
@@ -14,6 +15,7 @@ const ACCOUNT_TYPE_LABELS = {
|
|
|
14
15
|
[HyperliquidAccountType.DEX_ABSTRACTION]: "Standard (Shared HIP-3 Balance)",
|
|
15
16
|
[HyperliquidAccountType.PORTFOLIO_MARGIN]: "Portfolio Margin",
|
|
16
17
|
[HyperliquidAccountType.UNIFIED_ACCOUNT]: "Unified Account",
|
|
18
|
+
[LighterAccountType.BASIC]: "Standard",
|
|
17
19
|
[OkxAccountType.SPOT]: "Spot Mode",
|
|
18
20
|
[OkxAccountType.SINGLE_CURRENCY_MARGIN]: "Single-Currency Margin",
|
|
19
21
|
[OkxAccountType.MULTI_CURRENCY_MARGIN]: "Multi-Currency Margin",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ExchangeState } from './types.js';
|
|
2
|
+
import './binance/types.js';
|
|
3
|
+
import './bybit/types.js';
|
|
4
|
+
import './hyperliquid/types.js';
|
|
5
|
+
import './lighter/types.js';
|
|
6
|
+
import './okx/types.js';
|
|
7
|
+
|
|
8
|
+
declare function createEmptyState(): ExchangeState;
|
|
9
|
+
declare function positionKey(symbol: string, side: string): string;
|
|
10
|
+
|
|
11
|
+
export { createEmptyState, positionKey };
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import PearSDK from '@pear-protocol/core-sdk';
|
|
2
|
+
import { BinanceCredentialsDTO, BybitCredentialsDTO, HyperliquidCredentialsDTO, LighterCredentialsDTO, OkxCredentialsDTO } from '@pear-protocol/types';
|
|
3
|
+
import { BinanceExchangeWs } from './client/binance/exchange-ws.js';
|
|
4
|
+
import { BybitExchangeWs } from './client/bybit/exchange-ws.js';
|
|
5
|
+
import { HyperliquidExchangeWs } from './client/hyperliquid/exchange-ws.js';
|
|
6
|
+
import { LighterExchangeWs } from './client/lighter/exchange-ws.js';
|
|
7
|
+
import { OkxExchangeWs } from './client/okx/exchange-ws.js';
|
|
8
|
+
import './client/base-ws.js';
|
|
9
|
+
import 'partysocket';
|
|
10
|
+
import './client/exchange-ws.js';
|
|
11
|
+
import './client/binance/ws.js';
|
|
12
|
+
import './client/bybit/ws.js';
|
|
13
|
+
import './client/hyperliquid/ws.js';
|
|
14
|
+
import './client/lighter/ws.js';
|
|
15
|
+
import './client/okx/ws.js';
|
|
16
|
+
|
|
17
|
+
type HyperliquidAccountCredentials = HyperliquidCredentialsDTO & {
|
|
18
|
+
accountIdentifier: string;
|
|
19
|
+
};
|
|
20
|
+
type LighterAccountCredentials = LighterCredentialsDTO & {
|
|
21
|
+
accountIdentifier: string;
|
|
22
|
+
};
|
|
23
|
+
type SupportedCredentials = BinanceCredentialsDTO | BybitCredentialsDTO | HyperliquidAccountCredentials | LighterAccountCredentials | OkxCredentialsDTO;
|
|
24
|
+
type ExchangesSDKConfig = {
|
|
25
|
+
sdk: PearSDK;
|
|
26
|
+
demo?: boolean;
|
|
27
|
+
};
|
|
28
|
+
type ExchangeConnection = {
|
|
29
|
+
exchange: 'binance';
|
|
30
|
+
credentials: BinanceCredentialsDTO;
|
|
31
|
+
ws: BinanceExchangeWs;
|
|
32
|
+
} | {
|
|
33
|
+
exchange: 'bybit';
|
|
34
|
+
credentials: BybitCredentialsDTO;
|
|
35
|
+
ws: BybitExchangeWs;
|
|
36
|
+
} | {
|
|
37
|
+
exchange: 'okx';
|
|
38
|
+
credentials: OkxCredentialsDTO;
|
|
39
|
+
ws: OkxExchangeWs;
|
|
40
|
+
} | {
|
|
41
|
+
exchange: 'hyperliquid';
|
|
42
|
+
credentials: HyperliquidAccountCredentials;
|
|
43
|
+
ws: HyperliquidExchangeWs;
|
|
44
|
+
} | {
|
|
45
|
+
exchange: 'lighter';
|
|
46
|
+
credentials: LighterAccountCredentials;
|
|
47
|
+
ws: LighterExchangeWs;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export type { ExchangeConnection, ExchangesSDKConfig, HyperliquidAccountCredentials, LighterAccountCredentials, SupportedCredentials };
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pear-protocol/exchanges-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Pear Protocol Exchanges SDK",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -25,11 +25,15 @@
|
|
|
25
25
|
"typecheck": "tsc --noEmit"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@pear-protocol/core-sdk": "0.0.
|
|
29
|
-
"@pear-protocol/types": "0.0.
|
|
30
|
-
"@pear-protocol/utils": "0.0.
|
|
28
|
+
"@pear-protocol/core-sdk": "0.0.18",
|
|
29
|
+
"@pear-protocol/types": "0.0.16",
|
|
30
|
+
"@pear-protocol/utils": "0.0.16",
|
|
31
|
+
"bignumber.js": "9.3.1",
|
|
31
32
|
"partysocket": "^1.0.3"
|
|
32
33
|
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"viem": "^2.38.0"
|
|
36
|
+
},
|
|
33
37
|
"devDependencies": {
|
|
34
38
|
"@backend/typescript-config": "workspace:*",
|
|
35
39
|
"tsup": "8.5.1",
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import PearSDK from '@pear-protocol/core-sdk';
|
|
2
|
-
import { Connector } from '@pear-protocol/types';
|
|
3
|
-
import { Credentials } from '../credentials.js';
|
|
4
|
-
import { B as BalanceCallback, i as Tracker, a as AccountBalance, P as PositionsCallback, c as AccountPosition, T as TrackedAssetCallback, h as TrackedAssetInfo } from '../types-Caz2X4h0.js';
|
|
5
|
-
import './exchanges/bybit/types.js';
|
|
6
|
-
import './exchanges/hyperliquid/types.js';
|
|
7
|
-
import './exchanges/okx/types.js';
|
|
8
|
-
|
|
9
|
-
declare class AccountManager {
|
|
10
|
-
private credentials;
|
|
11
|
-
private sdk;
|
|
12
|
-
private demo;
|
|
13
|
-
private activeAccount;
|
|
14
|
-
private balanceListeners;
|
|
15
|
-
private positionListeners;
|
|
16
|
-
private assetListeners;
|
|
17
|
-
constructor(credentials: Credentials, sdk: PearSDK, demo?: boolean);
|
|
18
|
-
connect(tradeAccountId: string, exchange: Connector): Promise<void>;
|
|
19
|
-
trackBalance(cb: BalanceCallback): Tracker<AccountBalance | null>;
|
|
20
|
-
trackPositions(cb: PositionsCallback): Tracker<AccountPosition[]>;
|
|
21
|
-
trackAsset(coin: string, cb: TrackedAssetCallback): Tracker<TrackedAssetInfo | null>;
|
|
22
|
-
getLeverage(symbol: string): string | null;
|
|
23
|
-
disconnect(): Promise<void>;
|
|
24
|
-
destroy(): Promise<void>;
|
|
25
|
-
get isConnected(): boolean;
|
|
26
|
-
get isInitialized(): boolean;
|
|
27
|
-
private resolveCredentials;
|
|
28
|
-
private startWs;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export { AccountManager };
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { ExchangeAccount } from './exchange-account';
|
|
2
|
-
|
|
3
|
-
class AccountManager {
|
|
4
|
-
credentials;
|
|
5
|
-
sdk;
|
|
6
|
-
demo;
|
|
7
|
-
activeAccount = null;
|
|
8
|
-
balanceListeners = /* @__PURE__ */ new Map();
|
|
9
|
-
positionListeners = /* @__PURE__ */ new Map();
|
|
10
|
-
assetListeners = /* @__PURE__ */ new Map();
|
|
11
|
-
constructor(credentials, sdk, demo = false) {
|
|
12
|
-
this.credentials = credentials;
|
|
13
|
-
this.sdk = sdk;
|
|
14
|
-
this.demo = demo;
|
|
15
|
-
}
|
|
16
|
-
async connect(tradeAccountId, exchange) {
|
|
17
|
-
await this.disconnect();
|
|
18
|
-
const creds = await this.resolveCredentials(tradeAccountId, exchange);
|
|
19
|
-
await this.startWs(exchange, creds);
|
|
20
|
-
}
|
|
21
|
-
trackBalance(cb) {
|
|
22
|
-
const id = Math.random().toString(36).slice(2);
|
|
23
|
-
this.balanceListeners.set(id, cb);
|
|
24
|
-
if (this.activeAccount) {
|
|
25
|
-
this.activeAccount.trackBalance(cb, id);
|
|
26
|
-
}
|
|
27
|
-
return {
|
|
28
|
-
get: () => this.activeAccount?.getBalance() ?? null,
|
|
29
|
-
untrack: () => {
|
|
30
|
-
this.balanceListeners.delete(id);
|
|
31
|
-
this.activeAccount?.untrackBalance(id);
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
trackPositions(cb) {
|
|
36
|
-
const id = Math.random().toString(36).slice(2);
|
|
37
|
-
this.positionListeners.set(id, cb);
|
|
38
|
-
if (this.activeAccount) {
|
|
39
|
-
this.activeAccount.trackPositions(cb, id);
|
|
40
|
-
}
|
|
41
|
-
return {
|
|
42
|
-
get: () => this.activeAccount?.getPositions() ?? [],
|
|
43
|
-
untrack: () => {
|
|
44
|
-
this.positionListeners.delete(id);
|
|
45
|
-
this.activeAccount?.untrackPositions(id);
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
trackAsset(coin, cb) {
|
|
50
|
-
const id = Math.random().toString(36).slice(2);
|
|
51
|
-
this.assetListeners.set(id, { coin, cb });
|
|
52
|
-
if (this.activeAccount) {
|
|
53
|
-
this.activeAccount.trackAsset(coin, cb, id);
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
get: () => this.activeAccount?.getTrackedAsset(coin) ?? null,
|
|
57
|
-
untrack: () => {
|
|
58
|
-
this.assetListeners.delete(id);
|
|
59
|
-
this.activeAccount?.untrackAsset(id);
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
getLeverage(symbol) {
|
|
64
|
-
return this.activeAccount?.getLeverage(symbol) ?? null;
|
|
65
|
-
}
|
|
66
|
-
async disconnect() {
|
|
67
|
-
if (this.activeAccount) {
|
|
68
|
-
await this.activeAccount.disconnect();
|
|
69
|
-
this.activeAccount = null;
|
|
70
|
-
}
|
|
71
|
-
this.balanceListeners.clear();
|
|
72
|
-
this.positionListeners.clear();
|
|
73
|
-
this.assetListeners.clear();
|
|
74
|
-
}
|
|
75
|
-
async destroy() {
|
|
76
|
-
await this.disconnect();
|
|
77
|
-
this.credentials.clear();
|
|
78
|
-
}
|
|
79
|
-
get isConnected() {
|
|
80
|
-
return this.activeAccount?.isConnected ?? false;
|
|
81
|
-
}
|
|
82
|
-
get isInitialized() {
|
|
83
|
-
return this.activeAccount?.isInitialized ?? false;
|
|
84
|
-
}
|
|
85
|
-
async resolveCredentials(tradeAccountId, exchange) {
|
|
86
|
-
const creds = await this.credentials.getOrFetch(tradeAccountId);
|
|
87
|
-
if (exchange === "hyperliquid") {
|
|
88
|
-
const { accounts } = await this.sdk.core.accounts.list();
|
|
89
|
-
const account = accounts.find((a) => a.id === tradeAccountId);
|
|
90
|
-
if (!account) {
|
|
91
|
-
throw new Error(`Trade account ${tradeAccountId} not found`);
|
|
92
|
-
}
|
|
93
|
-
if (!account.exchangeIdentifier) {
|
|
94
|
-
throw new Error(`Trade account ${tradeAccountId} has no Hyperliquid address`);
|
|
95
|
-
}
|
|
96
|
-
return {
|
|
97
|
-
...creds,
|
|
98
|
-
address: account.exchangeIdentifier
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
return creds;
|
|
102
|
-
}
|
|
103
|
-
async startWs(exchange, creds) {
|
|
104
|
-
const account = new ExchangeAccount({ exchange, demo: this.demo });
|
|
105
|
-
await account.connect(creds);
|
|
106
|
-
this.activeAccount = account;
|
|
107
|
-
for (const [id, cb] of this.balanceListeners.entries()) {
|
|
108
|
-
account.trackBalance(cb, id);
|
|
109
|
-
}
|
|
110
|
-
for (const [id, cb] of this.positionListeners.entries()) {
|
|
111
|
-
account.trackPositions(cb, id);
|
|
112
|
-
}
|
|
113
|
-
for (const [id, { coin, cb }] of this.assetListeners.entries()) {
|
|
114
|
-
account.trackAsset(coin, cb, id);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export { AccountManager };
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { b as AccountConfig, g as SupportedCredentials, B as BalanceCallback, a as AccountBalance, P as PositionsCallback, c as AccountPosition, T as TrackedAssetCallback, h as TrackedAssetInfo } from '../types-Caz2X4h0.js';
|
|
2
|
-
import '@pear-protocol/types';
|
|
3
|
-
import './exchanges/bybit/types.js';
|
|
4
|
-
import './exchanges/hyperliquid/types.js';
|
|
5
|
-
import './exchanges/okx/types.js';
|
|
6
|
-
|
|
7
|
-
declare class ExchangeAccount {
|
|
8
|
-
private exchange;
|
|
9
|
-
private demo;
|
|
10
|
-
private orchestrator;
|
|
11
|
-
private state;
|
|
12
|
-
private balanceListeners;
|
|
13
|
-
private positionListeners;
|
|
14
|
-
private assetListeners;
|
|
15
|
-
private onAuthError?;
|
|
16
|
-
constructor(config: AccountConfig);
|
|
17
|
-
connect(credentials: SupportedCredentials): Promise<void>;
|
|
18
|
-
disconnect(): Promise<void>;
|
|
19
|
-
get isConnected(): boolean;
|
|
20
|
-
get isInitialized(): boolean;
|
|
21
|
-
get hasListeners(): boolean;
|
|
22
|
-
trackBalance(cb: BalanceCallback, id?: string): string;
|
|
23
|
-
untrackBalance(id: string): void;
|
|
24
|
-
getBalance(): AccountBalance | null;
|
|
25
|
-
trackPositions(cb: PositionsCallback, id?: string): string;
|
|
26
|
-
untrackPositions(id: string): void;
|
|
27
|
-
getPositions(): AccountPosition[];
|
|
28
|
-
trackAsset(coin: string, cb: TrackedAssetCallback, id: string): string;
|
|
29
|
-
untrackAsset(id: string): void;
|
|
30
|
-
getTrackedAsset(coin: string): TrackedAssetInfo | null;
|
|
31
|
-
getLeverage(symbol: string): string | null;
|
|
32
|
-
private applyStateUpdate;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export { ExchangeAccount };
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import { createOrchestrator } from './exchanges';
|
|
2
|
-
import { createEmptyState } from './utils';
|
|
3
|
-
|
|
4
|
-
class ExchangeAccount {
|
|
5
|
-
exchange;
|
|
6
|
-
demo;
|
|
7
|
-
orchestrator = null;
|
|
8
|
-
state;
|
|
9
|
-
balanceListeners = /* @__PURE__ */ new Map();
|
|
10
|
-
positionListeners = /* @__PURE__ */ new Map();
|
|
11
|
-
assetListeners = /* @__PURE__ */ new Map();
|
|
12
|
-
onAuthError;
|
|
13
|
-
constructor(config) {
|
|
14
|
-
this.exchange = config.exchange;
|
|
15
|
-
this.demo = config.demo ?? false;
|
|
16
|
-
this.onAuthError = config.onAuthError;
|
|
17
|
-
this.state = createEmptyState();
|
|
18
|
-
}
|
|
19
|
-
async connect(credentials) {
|
|
20
|
-
await this.disconnect();
|
|
21
|
-
this.state = createEmptyState();
|
|
22
|
-
this.orchestrator = createOrchestrator(
|
|
23
|
-
this.exchange,
|
|
24
|
-
{
|
|
25
|
-
onError: (error) => {
|
|
26
|
-
console.warn(`[ExchangeAccount] ${this.exchange} error:`, error.message);
|
|
27
|
-
if (error.message.includes("auth") || error.message.includes("login")) {
|
|
28
|
-
this.onAuthError?.();
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
onStateUpdate: (update) => this.applyStateUpdate(update),
|
|
32
|
-
demo: this.demo
|
|
33
|
-
},
|
|
34
|
-
credentials
|
|
35
|
-
);
|
|
36
|
-
await this.orchestrator.start();
|
|
37
|
-
}
|
|
38
|
-
async disconnect() {
|
|
39
|
-
this.balanceListeners.clear();
|
|
40
|
-
this.positionListeners.clear();
|
|
41
|
-
this.assetListeners.clear();
|
|
42
|
-
if (this.orchestrator) {
|
|
43
|
-
await this.orchestrator.stop();
|
|
44
|
-
this.orchestrator = null;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
get isConnected() {
|
|
48
|
-
return this.orchestrator?.isConnected ?? false;
|
|
49
|
-
}
|
|
50
|
-
get isInitialized() {
|
|
51
|
-
return this.state.initialized;
|
|
52
|
-
}
|
|
53
|
-
get hasListeners() {
|
|
54
|
-
return this.balanceListeners.size > 0 || this.positionListeners.size > 0 || this.assetListeners.size > 0;
|
|
55
|
-
}
|
|
56
|
-
trackBalance(cb, id) {
|
|
57
|
-
id ??= Math.random().toString(36).slice(2);
|
|
58
|
-
this.balanceListeners.set(id, cb);
|
|
59
|
-
if (this.state.balance) {
|
|
60
|
-
cb(this.state.balance);
|
|
61
|
-
}
|
|
62
|
-
return id;
|
|
63
|
-
}
|
|
64
|
-
untrackBalance(id) {
|
|
65
|
-
this.balanceListeners.delete(id);
|
|
66
|
-
}
|
|
67
|
-
getBalance() {
|
|
68
|
-
return this.state.balance;
|
|
69
|
-
}
|
|
70
|
-
trackPositions(cb, id) {
|
|
71
|
-
id ??= Math.random().toString(36).slice(2);
|
|
72
|
-
this.positionListeners.set(id, cb);
|
|
73
|
-
if (this.state.initialized) {
|
|
74
|
-
cb(Array.from(this.state.positions.values()));
|
|
75
|
-
}
|
|
76
|
-
return id;
|
|
77
|
-
}
|
|
78
|
-
untrackPositions(id) {
|
|
79
|
-
this.positionListeners.delete(id);
|
|
80
|
-
}
|
|
81
|
-
getPositions() {
|
|
82
|
-
return Array.from(this.state.positions.values());
|
|
83
|
-
}
|
|
84
|
-
trackAsset(coin, cb, id) {
|
|
85
|
-
this.assetListeners.set(id, { coin, cb });
|
|
86
|
-
this.orchestrator?.trackAsset(coin);
|
|
87
|
-
const existing = this.state.trackedAssets.get(coin);
|
|
88
|
-
if (existing) {
|
|
89
|
-
cb(existing);
|
|
90
|
-
}
|
|
91
|
-
return id;
|
|
92
|
-
}
|
|
93
|
-
untrackAsset(id) {
|
|
94
|
-
const entry = this.assetListeners.get(id);
|
|
95
|
-
if (!entry) return;
|
|
96
|
-
this.assetListeners.delete(id);
|
|
97
|
-
const hasOtherListeners = Array.from(this.assetListeners.values()).some((l) => l.coin === entry.coin);
|
|
98
|
-
if (!hasOtherListeners) {
|
|
99
|
-
this.orchestrator?.untrackAsset(entry.coin);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
getTrackedAsset(coin) {
|
|
103
|
-
return this.state.trackedAssets.get(coin) ?? null;
|
|
104
|
-
}
|
|
105
|
-
getLeverage(symbol) {
|
|
106
|
-
const setting = this.state.leverageSettings.get(symbol);
|
|
107
|
-
if (setting !== void 0) return setting;
|
|
108
|
-
for (const pos of this.state.positions.values()) {
|
|
109
|
-
if (pos.symbol === symbol) return pos.leverage;
|
|
110
|
-
}
|
|
111
|
-
return null;
|
|
112
|
-
}
|
|
113
|
-
applyStateUpdate(update) {
|
|
114
|
-
if (update.balance) {
|
|
115
|
-
this.state.balance = update.balance;
|
|
116
|
-
for (const cb of this.balanceListeners.values()) {
|
|
117
|
-
try {
|
|
118
|
-
cb(update.balance);
|
|
119
|
-
} catch {
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
if (update.positions) {
|
|
124
|
-
for (const [key, pos] of update.positions) {
|
|
125
|
-
if (pos.size === "0") {
|
|
126
|
-
this.state.positions.delete(key);
|
|
127
|
-
} else {
|
|
128
|
-
this.state.positions.set(key, pos);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
const positions = Array.from(this.state.positions.values());
|
|
132
|
-
for (const cb of this.positionListeners.values()) {
|
|
133
|
-
cb(positions);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
if (update.leverageSettings) {
|
|
137
|
-
for (const [symbol, lev] of update.leverageSettings) {
|
|
138
|
-
this.state.leverageSettings.set(symbol, lev);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
if (update.trackedAssets) {
|
|
142
|
-
for (const [coin, info] of update.trackedAssets) {
|
|
143
|
-
this.state.trackedAssets.set(coin, info);
|
|
144
|
-
for (const listener of this.assetListeners.values()) {
|
|
145
|
-
if (listener.coin === coin) {
|
|
146
|
-
listener.cb(info);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
this.state.lastUpdated = Date.now();
|
|
152
|
-
if (!this.state.initialized) {
|
|
153
|
-
this.state.initialized = true;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export { ExchangeAccount };
|