@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.
Files changed (178) hide show
  1. package/README.md +73 -137
  2. package/dist/client/base-ws.d.ts +30 -0
  3. package/dist/client/base-ws.js +113 -0
  4. package/dist/client/binance/exchange-ws.d.ts +19 -0
  5. package/dist/client/binance/exchange-ws.js +26 -0
  6. package/dist/{account/exchanges → client}/binance/rest.d.ts +2 -6
  7. package/dist/{account/exchanges → client}/binance/rest.js +4 -11
  8. package/dist/client/binance/types.d.ts +68 -0
  9. package/dist/client/binance/types.js +1 -0
  10. package/dist/client/binance/ws.d.ts +30 -0
  11. package/dist/client/binance/ws.js +54 -0
  12. package/dist/client/bybit/exchange-ws.d.ts +20 -0
  13. package/dist/client/bybit/exchange-ws.js +28 -0
  14. package/dist/{account/exchanges → client}/bybit/rest.js +3 -2
  15. package/dist/{account/exchanges → client}/bybit/types.d.ts +1 -9
  16. package/dist/client/bybit/types.js +1 -0
  17. package/dist/client/bybit/ws.d.ts +17 -0
  18. package/dist/client/bybit/ws.js +50 -0
  19. package/dist/client/exchange-ws.d.ts +12 -0
  20. package/dist/client/exchange-ws.js +10 -0
  21. package/dist/client/hyperliquid/exchange-ws.d.ts +15 -0
  22. package/dist/client/hyperliquid/exchange-ws.js +21 -0
  23. package/dist/client/hyperliquid/rest.d.ts +3 -0
  24. package/dist/client/hyperliquid/rest.js +12 -0
  25. package/dist/{account/exchanges → client}/hyperliquid/types.d.ts +18 -39
  26. package/dist/client/hyperliquid/types.js +1 -0
  27. package/dist/client/hyperliquid/ws.d.ts +10 -0
  28. package/dist/client/hyperliquid/ws.js +16 -0
  29. package/dist/client/index.d.ts +31 -0
  30. package/dist/client/index.js +47 -0
  31. package/dist/client/lighter/constants.d.ts +4 -0
  32. package/dist/client/lighter/constants.js +4 -0
  33. package/dist/client/lighter/exchange-ws.d.ts +15 -0
  34. package/dist/client/lighter/exchange-ws.js +21 -0
  35. package/dist/client/lighter/rest.d.ts +56 -0
  36. package/dist/client/lighter/rest.js +27 -0
  37. package/dist/client/lighter/types.d.ts +32 -0
  38. package/dist/client/lighter/types.js +1 -0
  39. package/dist/client/lighter/ws.d.ts +10 -0
  40. package/dist/client/lighter/ws.js +17 -0
  41. package/dist/client/okx/exchange-ws.d.ts +20 -0
  42. package/dist/client/okx/exchange-ws.js +28 -0
  43. package/dist/{account/exchanges → client}/okx/rest.js +2 -2
  44. package/dist/{account/exchanges → client}/okx/types.d.ts +1 -10
  45. package/dist/client/okx/types.js +1 -0
  46. package/dist/client/okx/ws.d.ts +17 -0
  47. package/dist/client/okx/ws.js +61 -0
  48. package/dist/helper/factory.d.ts +10 -0
  49. package/dist/helper/factory.js +12 -0
  50. package/dist/helper/index.d.ts +7 -0
  51. package/dist/helper/index.js +2 -0
  52. package/dist/helper/lighter/ethereum/abi.d.ts +66 -0
  53. package/dist/helper/lighter/ethereum/abi.js +40 -0
  54. package/dist/helper/lighter/ethereum/index.d.ts +8 -0
  55. package/dist/helper/lighter/ethereum/index.js +34 -0
  56. package/dist/helper/lighter/ethereum/types.d.ts +23 -0
  57. package/dist/helper/lighter/ethereum/types.js +1 -0
  58. package/dist/helper/lighter/helper.d.ts +9 -0
  59. package/dist/helper/lighter/helper.js +67 -0
  60. package/dist/helper/lighter/index.d.ts +6 -0
  61. package/dist/helper/lighter/index.js +2 -0
  62. package/dist/helper/lighter/types.d.ts +63 -0
  63. package/dist/helper/lighter/types.js +35 -0
  64. package/dist/helper/types.d.ts +11 -0
  65. package/dist/helper/types.js +1 -0
  66. package/dist/index.d.ts +37 -24
  67. package/dist/index.js +6 -21
  68. package/dist/sdk.d.ts +43 -0
  69. package/dist/sdk.js +52 -0
  70. package/dist/syncer/base.d.ts +33 -0
  71. package/dist/syncer/base.js +14 -0
  72. package/dist/syncer/index.d.ts +18 -0
  73. package/dist/syncer/index.js +1 -0
  74. package/dist/tracker/base.d.ts +79 -0
  75. package/dist/tracker/base.js +120 -0
  76. package/dist/tracker/binance/const.d.ts +4 -0
  77. package/dist/tracker/binance/const.js +4 -0
  78. package/dist/{account/exchanges → tracker}/binance/mapper.d.ts +4 -1
  79. package/dist/{account/exchanges → tracker}/binance/mapper.js +7 -6
  80. package/dist/tracker/binance/tracker.d.ts +60 -0
  81. package/dist/tracker/binance/tracker.js +181 -0
  82. package/dist/tracker/binance/types.d.ts +6 -0
  83. package/dist/{account/exchanges → tracker}/bybit/mapper.d.ts +5 -3
  84. package/dist/{account/exchanges → tracker}/bybit/mapper.js +11 -10
  85. package/dist/tracker/bybit/tracker.d.ts +51 -0
  86. package/dist/tracker/bybit/tracker.js +138 -0
  87. package/dist/tracker/bybit/types.d.ts +7 -0
  88. package/dist/{account/exchanges → tracker}/hyperliquid/mapper.d.ts +6 -4
  89. package/dist/{account/exchanges → tracker}/hyperliquid/mapper.js +18 -16
  90. package/dist/tracker/hyperliquid/tracker.d.ts +62 -0
  91. package/dist/tracker/hyperliquid/tracker.js +219 -0
  92. package/dist/tracker/hyperliquid/types.d.ts +23 -0
  93. package/dist/tracker/index.d.ts +38 -0
  94. package/dist/tracker/index.js +81 -0
  95. package/dist/tracker/lighter/const.d.ts +3 -0
  96. package/dist/tracker/lighter/const.js +3 -0
  97. package/dist/tracker/lighter/mapper.d.ts +16 -0
  98. package/dist/tracker/lighter/mapper.js +77 -0
  99. package/dist/tracker/lighter/tracker.d.ts +53 -0
  100. package/dist/tracker/lighter/tracker.js +150 -0
  101. package/dist/tracker/lighter/types.d.ts +16 -0
  102. package/dist/tracker/lighter/types.js +6 -0
  103. package/dist/{account/exchanges → tracker}/okx/mapper.d.ts +5 -3
  104. package/dist/{account/exchanges → tracker}/okx/mapper.js +11 -10
  105. package/dist/tracker/okx/tracker.d.ts +51 -0
  106. package/dist/tracker/okx/tracker.js +134 -0
  107. package/dist/tracker/okx/types.d.ts +8 -0
  108. package/dist/tracker/types.d.ts +63 -0
  109. package/dist/{account → tracker}/types.js +6 -4
  110. package/dist/tracker/utils.d.ts +11 -0
  111. package/dist/{account → tracker}/utils.js +0 -2
  112. package/dist/types.d.ts +50 -0
  113. package/dist/types.js +1 -0
  114. package/package.json +8 -4
  115. package/dist/account/account-manager.d.ts +0 -31
  116. package/dist/account/account-manager.js +0 -119
  117. package/dist/account/exchange-account.d.ts +0 -35
  118. package/dist/account/exchange-account.js +0 -158
  119. package/dist/account/exchanges/base.d.ts +0 -48
  120. package/dist/account/exchanges/base.js +0 -41
  121. package/dist/account/exchanges/binance/asset-tracker.d.ts +0 -26
  122. package/dist/account/exchanges/binance/asset-tracker.js +0 -38
  123. package/dist/account/exchanges/binance/const.d.ts +0 -10
  124. package/dist/account/exchanges/binance/const.js +0 -10
  125. package/dist/account/exchanges/binance/orchestrator.d.ts +0 -31
  126. package/dist/account/exchanges/binance/orchestrator.js +0 -91
  127. package/dist/account/exchanges/binance/state-handler.d.ts +0 -33
  128. package/dist/account/exchanges/binance/state-handler.js +0 -113
  129. package/dist/account/exchanges/binance/types.d.ts +0 -5
  130. package/dist/account/exchanges/binance/ws.d.ts +0 -23
  131. package/dist/account/exchanges/binance/ws.js +0 -69
  132. package/dist/account/exchanges/bybit/asset-tracker.d.ts +0 -26
  133. package/dist/account/exchanges/bybit/asset-tracker.js +0 -37
  134. package/dist/account/exchanges/bybit/const.d.ts +0 -7
  135. package/dist/account/exchanges/bybit/const.js +0 -7
  136. package/dist/account/exchanges/bybit/orchestrator.d.ts +0 -22
  137. package/dist/account/exchanges/bybit/orchestrator.js +0 -66
  138. package/dist/account/exchanges/bybit/state-handler.d.ts +0 -23
  139. package/dist/account/exchanges/bybit/state-handler.js +0 -70
  140. package/dist/account/exchanges/bybit/ws.d.ts +0 -19
  141. package/dist/account/exchanges/bybit/ws.js +0 -83
  142. package/dist/account/exchanges/hyperliquid/asset-tracker.d.ts +0 -35
  143. package/dist/account/exchanges/hyperliquid/asset-tracker.js +0 -83
  144. package/dist/account/exchanges/hyperliquid/orchestrator.d.ts +0 -26
  145. package/dist/account/exchanges/hyperliquid/orchestrator.js +0 -102
  146. package/dist/account/exchanges/hyperliquid/state-handler.d.ts +0 -25
  147. package/dist/account/exchanges/hyperliquid/state-handler.js +0 -104
  148. package/dist/account/exchanges/index.d.ts +0 -11
  149. package/dist/account/exchanges/index.js +0 -32
  150. package/dist/account/exchanges/okx/asset-tracker.d.ts +0 -26
  151. package/dist/account/exchanges/okx/asset-tracker.js +0 -34
  152. package/dist/account/exchanges/okx/const.d.ts +0 -7
  153. package/dist/account/exchanges/okx/const.js +0 -7
  154. package/dist/account/exchanges/okx/orchestrator.d.ts +0 -22
  155. package/dist/account/exchanges/okx/orchestrator.js +0 -57
  156. package/dist/account/exchanges/okx/state-handler.d.ts +0 -24
  157. package/dist/account/exchanges/okx/state-handler.js +0 -78
  158. package/dist/account/exchanges/okx/ws.d.ts +0 -20
  159. package/dist/account/exchanges/okx/ws.js +0 -103
  160. package/dist/account/index.d.ts +0 -11
  161. package/dist/account/index.js +0 -4
  162. package/dist/account/types.d.ts +0 -5
  163. package/dist/account/utils.d.ts +0 -10
  164. package/dist/credentials.d.ts +0 -28
  165. package/dist/credentials.js +0 -46
  166. package/dist/types-Caz2X4h0.d.ts +0 -151
  167. package/dist/utils/ws.d.ts +0 -10
  168. package/dist/utils/ws.js +0 -42
  169. /package/dist/{account/exchanges → client}/bybit/rest.d.ts +0 -0
  170. /package/dist/{utils → client}/hmac.d.ts +0 -0
  171. /package/dist/{utils → client}/hmac.js +0 -0
  172. /package/dist/{account/exchanges → client}/okx/rest.d.ts +0 -0
  173. /package/dist/{account/exchanges → tracker}/binance/types.js +0 -0
  174. /package/dist/{account/exchanges → tracker}/bybit/types.js +0 -0
  175. /package/dist/{account/exchanges → tracker}/hyperliquid/const.d.ts +0 -0
  176. /package/dist/{account/exchanges → tracker}/hyperliquid/const.js +0 -0
  177. /package/dist/{account/exchanges → tracker}/hyperliquid/types.js +0 -0
  178. /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,8 @@
1
+ declare enum OkxAccountType {
2
+ SPOT = "OKX_SPOT",
3
+ SINGLE_CURRENCY_MARGIN = "OKX_SINGLE",
4
+ MULTI_CURRENCY_MARGIN = "OKX_MULTI",
5
+ PORTFOLIO_MARGIN = "OKX_PORTFOLIO"
6
+ }
7
+
8
+ export { OkxAccountType };
@@ -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 './exchanges/binance/types';
2
- import { BybitAccountType } from './exchanges/bybit/types';
3
- import { HyperliquidAccountType } from './exchanges/hyperliquid/types';
4
- import { OkxAccountType } from './exchanges/okx/types';
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 };
@@ -2,8 +2,6 @@ function createEmptyState() {
2
2
  return {
3
3
  balance: null,
4
4
  positions: /* @__PURE__ */ new Map(),
5
- leverageSettings: /* @__PURE__ */ new Map(),
6
- trackedAssets: /* @__PURE__ */ new Map(),
7
5
  lastUpdated: 0,
8
6
  initialized: false
9
7
  };
@@ -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.0.18",
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.17",
29
- "@pear-protocol/types": "0.0.15",
30
- "@pear-protocol/utils": "0.0.15",
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 };