@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
@@ -1,7 +1,9 @@
1
- import { a as AccountBalance, c as AccountPosition } from '../../../types-Caz2X4h0.js';
2
- import { BybitRawWallet, BybitRawCoin, BybitAccountType, BybitRawPosition } from './types.js';
3
- import '@pear-protocol/types';
1
+ import { BybitRawWallet, BybitRawCoin, BybitRawPosition } from '../../client/bybit/types.js';
2
+ import { AccountBalance, AccountPosition } from '../types.js';
3
+ import { BybitAccountType } from './types.js';
4
+ import '../binance/types.js';
4
5
  import '../hyperliquid/types.js';
6
+ import '../lighter/types.js';
5
7
  import '../okx/types.js';
6
8
 
7
9
  declare function buildBalance(raw: BybitRawWallet, coins: Map<string, BybitRawCoin>, accountType: BybitAccountType | null): AccountBalance | null;
@@ -1,5 +1,6 @@
1
- import '../../types';
2
- import { positionKey } from '../../utils';
1
+ import BigNumber from 'bignumber.js';
2
+ import '../types';
3
+ import { positionKey } from '../utils';
3
4
  import { BybitAccountType } from './types';
4
5
 
5
6
  function buildBalance(raw, coins, accountType) {
@@ -14,19 +15,19 @@ function buildBalance(raw, coins, accountType) {
14
15
  const positionInitialMargin = c.totalPositionIM === "" ? "0" : c.totalPositionIM ?? "0";
15
16
  const orderInitialMargin = c.totalOrderIM === "" ? "0" : c.totalOrderIM ?? "0";
16
17
  const locked = c.locked ?? "0";
17
- const equityNum = parseFloat(equity);
18
- const positionInitialMarginNum = parseFloat(positionInitialMargin);
19
- const orderInitialMarginNum = parseFloat(orderInitialMargin);
20
- const lockedNum = parseFloat(locked);
21
- if (equityNum === 0 && parseFloat(c.walletBalance ?? "0") === 0) continue;
18
+ const equityBN = new BigNumber(equity);
19
+ const positionInitialMarginBN = new BigNumber(positionInitialMargin);
20
+ const orderInitialMarginBN = new BigNumber(orderInitialMargin);
21
+ const lockedBN = new BigNumber(locked);
22
+ if (equityBN.isZero() && new BigNumber(c.walletBalance ?? "0").isZero()) continue;
22
23
  let coinFree;
23
24
  let coinUsed;
24
25
  if (isPortfolio) {
25
- coinFree = (equityNum - lockedNum).toString();
26
+ coinFree = equityBN.minus(lockedBN).toFixed();
26
27
  coinUsed = "0";
27
28
  } else {
28
- coinFree = (equityNum - positionInitialMarginNum - orderInitialMarginNum - lockedNum).toString();
29
- coinUsed = (positionInitialMarginNum + orderInitialMarginNum).toString();
29
+ coinFree = equityBN.minus(positionInitialMarginBN).minus(orderInitialMarginBN).minus(lockedBN).toFixed();
30
+ coinUsed = positionInitialMarginBN.plus(orderInitialMarginBN).toFixed();
30
31
  }
31
32
  free[c.coin] = coinFree;
32
33
  used[c.coin] = coinUsed;
@@ -0,0 +1,51 @@
1
+ import { BybitExchangeWs } from '../../client/bybit/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/bybit/ws.js';
9
+ import '@pear-protocol/core-sdk';
10
+ import '../../client/binance/exchange-ws.js';
11
+ import '../../client/binance/ws.js';
12
+ import '../../client/hyperliquid/exchange-ws.js';
13
+ import '../../client/hyperliquid/ws.js';
14
+ import '../../client/lighter/exchange-ws.js';
15
+ import '../../client/lighter/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 './types.js';
21
+ import '../hyperliquid/types.js';
22
+ import '../lighter/types.js';
23
+ import '../okx/types.js';
24
+
25
+ type BybitAccountTrackerConfig = AccountTrackerConfig & {
26
+ credentials: SupportedCredentials;
27
+ ws: BybitExchangeWs;
28
+ };
29
+ declare class BybitAccountTracker extends BaseAccountTracker {
30
+ private readonly creds;
31
+ private readonly ws;
32
+ private messageListenerId;
33
+ private openListenerId;
34
+ private rawCoins;
35
+ private lastWallet;
36
+ private accountType;
37
+ private trackedAssetInfos;
38
+ constructor(config: BybitAccountTrackerConfig);
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 subscribe;
45
+ private handleInitialData;
46
+ private routeRaw;
47
+ private handleMessage;
48
+ private handleWalletUpdate;
49
+ }
50
+
51
+ export { BybitAccountTracker, type BybitAccountTrackerConfig };
@@ -0,0 +1,138 @@
1
+ import { fetchWalletBalance, fetchPositions, fetchAccountInfo, fetchPositionLeverage } from '../../client/bybit/rest';
2
+ import { BaseAccountTracker } from '../base';
3
+ import { mergeRawCoins, buildBalance, mapPositions, mapPositionUpdates } from './mapper';
4
+ import './types';
5
+
6
+ class BybitAccountTracker extends BaseAccountTracker {
7
+ creds;
8
+ ws;
9
+ messageListenerId = null;
10
+ openListenerId = null;
11
+ rawCoins = /* @__PURE__ */ new Map();
12
+ lastWallet = null;
13
+ accountType = null;
14
+ trackedAssetInfos = /* @__PURE__ */ new Map();
15
+ constructor(config) {
16
+ super(config);
17
+ this.credentials = config.credentials;
18
+ this.creds = config.credentials;
19
+ this.ws = config.ws;
20
+ }
21
+ async start() {
22
+ const [wallet, positionsUsd, positionsUsdc, accountInfo] = await Promise.all([
23
+ fetchWalletBalance(this.creds, this.demo),
24
+ fetchPositions(this.creds, "USDT", this.demo),
25
+ fetchPositions(this.creds, "USDC", this.demo),
26
+ fetchAccountInfo(this.creds, this.demo)
27
+ ]);
28
+ this.handleInitialData(
29
+ wallet ?? null,
30
+ [positionsUsd, positionsUsdc].flat(),
31
+ accountInfo?.marginMode ?? null
32
+ );
33
+ this.messageListenerId = this.ws.main.addMessageListener((raw) => this.routeRaw(raw));
34
+ this.openListenerId = this.ws.main.addOpenListener(() => {
35
+ this.ws.authenticate().then(() => this.subscribe()).catch((err) => this.onError(err));
36
+ });
37
+ this.subscribe();
38
+ }
39
+ async cleanupConnections() {
40
+ if (this.messageListenerId) {
41
+ this.ws.main.removeMessageListener(this.messageListenerId);
42
+ this.messageListenerId = null;
43
+ }
44
+ if (this.openListenerId) {
45
+ this.ws.main.removeOpenListener(this.openListenerId);
46
+ this.openListenerId = null;
47
+ }
48
+ }
49
+ get isConnected() {
50
+ return this.ws.isConnected;
51
+ }
52
+ ensureAssetTracked(coin) {
53
+ if (this.trackedAssetInfos.has(coin)) return;
54
+ fetchPositionLeverage(this.creds, coin, this.demo).then((pos) => {
55
+ const leverage = pos?.leverage || "1";
56
+ const marginType = pos?.tradeMode === "1" ? "cross" : "isolated";
57
+ const info = { coin, leverage, marginType };
58
+ this.trackedAssetInfos.set(coin, info);
59
+ const trackedAssets = /* @__PURE__ */ new Map();
60
+ trackedAssets.set(coin, info);
61
+ this.onStateUpdate({ trackedAssets });
62
+ }).catch((err) => {
63
+ this.onError(err instanceof Error ? err : new Error(String(err)));
64
+ });
65
+ }
66
+ releaseAsset(coin) {
67
+ this.trackedAssetInfos.delete(coin);
68
+ this.onStateUpdate({ trackedAssets: new Map(this.trackedAssetInfos) });
69
+ }
70
+ subscribe() {
71
+ this.ws.main.send({ op: "subscribe", args: ["wallet", "position"] });
72
+ }
73
+ handleInitialData(wallet, positions, accountType) {
74
+ this.accountType = accountType;
75
+ if (wallet) {
76
+ this.lastWallet = wallet;
77
+ this.rawCoins = mergeRawCoins(/* @__PURE__ */ new Map(), wallet.coin ?? []);
78
+ const balance = buildBalance(wallet, this.rawCoins, this.accountType);
79
+ if (balance) this.onStateUpdate({ balance });
80
+ }
81
+ this.onStateUpdate({ positions: mapPositions(positions) });
82
+ }
83
+ routeRaw(raw) {
84
+ try {
85
+ const msg = JSON.parse(raw);
86
+ if (msg.topic && msg.data) {
87
+ this.handleMessage({ topic: msg.topic, data: msg.data });
88
+ }
89
+ } catch (err) {
90
+ this.onError(err instanceof Error ? err : new Error(String(err)));
91
+ }
92
+ }
93
+ handleMessage(msg) {
94
+ if (msg.topic === "wallet") {
95
+ const wallet = msg.data[0];
96
+ if (wallet) this.handleWalletUpdate(wallet);
97
+ } else if (msg.topic === "position") {
98
+ const rawPositions = msg.data;
99
+ const positions = mapPositionUpdates(rawPositions);
100
+ if (positions.size > 0) {
101
+ const trackedAssets = /* @__PURE__ */ new Map();
102
+ for (const pos of rawPositions) {
103
+ const existing = this.trackedAssetInfos.get(pos.symbol);
104
+ if (existing) {
105
+ const leverage = pos.leverage || existing.leverage;
106
+ const marginType = pos.tradeMode === "1" ? "isolated" : "cross";
107
+ const updated = { ...existing, leverage, marginType };
108
+ this.trackedAssetInfos.set(pos.symbol, updated);
109
+ trackedAssets.set(pos.symbol, updated);
110
+ }
111
+ }
112
+ this.onStateUpdate({
113
+ positions,
114
+ ...trackedAssets.size > 0 ? { trackedAssets } : {}
115
+ });
116
+ }
117
+ }
118
+ }
119
+ handleWalletUpdate(raw) {
120
+ this.rawCoins = mergeRawCoins(this.rawCoins, raw.coin ?? []);
121
+ const merged = this.lastWallet ? {
122
+ totalEquity: raw.totalEquity || this.lastWallet.totalEquity,
123
+ totalWalletBalance: raw.totalWalletBalance || this.lastWallet.totalWalletBalance,
124
+ totalMarginBalance: raw.totalMarginBalance || this.lastWallet.totalMarginBalance,
125
+ totalAvailableBalance: raw.totalAvailableBalance || this.lastWallet.totalAvailableBalance,
126
+ totalPerpUPL: raw.totalPerpUPL || this.lastWallet.totalPerpUPL,
127
+ totalInitialMargin: raw.totalInitialMargin || this.lastWallet.totalInitialMargin,
128
+ totalMaintenanceMargin: raw.totalMaintenanceMargin || this.lastWallet.totalMaintenanceMargin,
129
+ accountMMRate: raw.accountMMRate || this.lastWallet.accountMMRate,
130
+ coin: raw.coin ?? this.lastWallet.coin
131
+ } : raw;
132
+ this.lastWallet = merged;
133
+ const balance = buildBalance(merged, this.rawCoins, this.accountType);
134
+ if (balance) this.onStateUpdate({ balance });
135
+ }
136
+ }
137
+
138
+ export { BybitAccountTracker };
@@ -0,0 +1,7 @@
1
+ declare enum BybitAccountType {
2
+ ISOLATED_MARGIN = "ISOLATED_MARGIN",
3
+ REGULAR_MARGIN = "REGULAR_MARGIN",
4
+ PORTFOLIO_MARGIN = "PORTFOLIO_MARGIN"
5
+ }
6
+
7
+ export { BybitAccountType };
@@ -1,10 +1,12 @@
1
- import { a as AccountBalance, c as AccountPosition } from '../../../types-Caz2X4h0.js';
2
- import { AggregatedClearinghouseSummary, HyperliquidCoinBalance, HyperliquidAccountType, AssetPosition } from './types.js';
3
- import '@pear-protocol/types';
1
+ import { AssetPosition } from '../../client/hyperliquid/types.js';
2
+ import { AccountBalance, AccountPosition } from '../types.js';
3
+ import { AggregatedClearinghouseSummary, HyperliquidCoinBalance, HyperliquidAccountType } from './types.js';
4
+ import '../binance/types.js';
4
5
  import '../bybit/types.js';
6
+ import '../lighter/types.js';
5
7
  import '../okx/types.js';
6
8
 
7
- declare function mapBalance(summary: AggregatedClearinghouseSummary, spotCoinBalances: Map<string, HyperliquidCoinBalance>, accountType: HyperliquidAccountType | null, availableToTradeByCollateral: Map<string, number>): AccountBalance | null;
9
+ declare function mapBalance(summary: AggregatedClearinghouseSummary, spotCoinBalances: Map<string, HyperliquidCoinBalance>, accountType: HyperliquidAccountType | null, availableToTradeByCollateral: Map<string, string>): AccountBalance | null;
8
10
  declare function mapPositions(raw: AssetPosition[]): Map<string, AccountPosition>;
9
11
 
10
12
  export { mapBalance, mapPositions };
@@ -1,4 +1,5 @@
1
- import { positionKey } from '../../utils';
1
+ import BigNumber from 'bignumber.js';
2
+ import { positionKey } from '../utils';
2
3
  import { COLLATERAL_TOKEN_MAP } from './types';
3
4
 
4
5
  const COLLATERAL_COINS = new Set(Object.values(COLLATERAL_TOKEN_MAP));
@@ -11,9 +12,9 @@ function mapBalance(summary, spotCoinBalances, accountType, availableToTradeByCo
11
12
  for (const [, coin] of spotCoinBalances) {
12
13
  if (!COLLATERAL_COINS.has(coin.coin)) continue;
13
14
  const availableOverride = availableToTradeByCollateral.get(coin.coin);
14
- const coinFree = availableOverride !== void 0 ? availableOverride.toString() : (coin.total - coin.hold).toString();
15
- const coinUsed = coin.hold.toString();
16
- const coinTotal = coin.total.toString();
15
+ const coinFree = availableOverride !== void 0 ? availableOverride : new BigNumber(coin.total).minus(coin.hold).toFixed();
16
+ const coinUsed = coin.hold;
17
+ const coinTotal = coin.total;
17
18
  free[coin.coin] = coinFree;
18
19
  used[coin.coin] = coinUsed;
19
20
  total[coin.coin] = coinTotal;
@@ -26,19 +27,20 @@ function mapBalance(summary, spotCoinBalances, accountType, availableToTradeByCo
26
27
  usdValue: coinTotal
27
28
  });
28
29
  }
29
- const walletBalance = summary.accountValue - summary.totalUnrealizedPnl;
30
- const marginRatio = summary.accountValue > 0 ? (summary.crossMaintenanceMarginUsed / summary.accountValue).toFixed(4) : "0.0000";
30
+ const accountValueBN = new BigNumber(summary.accountValue);
31
+ const walletBalance = accountValueBN.minus(summary.totalUnrealizedPnl).toFixed();
32
+ const marginRatio = accountValueBN.gt(0) ? new BigNumber(summary.crossMaintenanceMarginUsed).div(accountValueBN).toFixed(4) : "0.0000";
31
33
  return {
32
34
  accountType,
33
35
  free,
34
36
  used,
35
37
  total,
36
- availableToTrade: summary.withdrawable.toString(),
37
- totalEquity: summary.accountValue.toString(),
38
- walletBalance: walletBalance.toString(),
39
- unrealizedPnl: summary.totalUnrealizedPnl.toString(),
40
- initialMarginUsed: summary.totalMarginUsed.toString(),
41
- maintenanceMargin: summary.crossMaintenanceMarginUsed.toString(),
38
+ availableToTrade: summary.withdrawable,
39
+ totalEquity: summary.accountValue,
40
+ walletBalance,
41
+ unrealizedPnl: summary.totalUnrealizedPnl,
42
+ initialMarginUsed: summary.totalMarginUsed,
43
+ maintenanceMargin: summary.crossMaintenanceMarginUsed,
42
44
  marginRatio,
43
45
  assets,
44
46
  timestamp: Date.now()
@@ -48,14 +50,14 @@ function mapPositions(raw) {
48
50
  const positions = /* @__PURE__ */ new Map();
49
51
  for (const ap of raw) {
50
52
  const pos = ap.position;
51
- const szi = Number.parseFloat(pos.szi || "0");
52
- if (szi === 0) continue;
53
+ const sziBN = new BigNumber(pos.szi || "0");
54
+ if (sziBN.isZero()) continue;
53
55
  const coin = pos.coin || "";
54
- const side = szi > 0 ? "long" : "short";
56
+ const side = sziBN.isPositive() ? "long" : "short";
55
57
  positions.set(positionKey(coin, side), {
56
58
  symbol: coin,
57
59
  side,
58
- size: szi.toString(),
60
+ size: sziBN.toFixed(),
59
61
  entryPrice: pos.entryPx || "0",
60
62
  unrealizedPnl: pos.unrealizedPnl || "0",
61
63
  leverage: pos.leverage.value.toString(),
@@ -0,0 +1,62 @@
1
+ import { HyperliquidWs } from '../../client/hyperliquid/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/lighter/exchange-ws.js';
15
+ import '../../client/lighter/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 './types.js';
22
+ import '../lighter/types.js';
23
+ import '../okx/types.js';
24
+
25
+ type HyperliquidAccountTrackerConfig = AccountTrackerConfig & {
26
+ credentials: SupportedCredentials;
27
+ ws: HyperliquidWs;
28
+ };
29
+ declare class HyperliquidAccountTracker extends BaseAccountTracker {
30
+ private readonly address;
31
+ private readonly ws;
32
+ private messageListenerId;
33
+ private openListenerId;
34
+ private subscribedCoins;
35
+ private lastSummary;
36
+ private spotCoinBalances;
37
+ private accountType;
38
+ private symbolToCollateralToken;
39
+ private availableToTradeByCollateral;
40
+ private trackedAssetData;
41
+ constructor(config: HyperliquidAccountTrackerConfig);
42
+ start(): Promise<void>;
43
+ protected cleanupConnections(): Promise<void>;
44
+ get isConnected(): boolean;
45
+ protected ensureAssetTracked(coin: string): void;
46
+ protected releaseAsset(coin: string): void;
47
+ private isLocked;
48
+ private addrLower;
49
+ private sendStaticSubs;
50
+ private resubscribeAll;
51
+ private routeRaw;
52
+ private handle;
53
+ private loadPerpMetas;
54
+ private onClearinghouseState;
55
+ private onActiveAssetData;
56
+ private onWebData3;
57
+ private onSpotState;
58
+ private buildBalance;
59
+ private buildTrackedAssetsMap;
60
+ }
61
+
62
+ export { HyperliquidAccountTracker, type HyperliquidAccountTrackerConfig };
@@ -0,0 +1,219 @@
1
+ import BigNumber from 'bignumber.js';
2
+ import { fetchInfo } from '../../client/hyperliquid/rest';
3
+ import { BaseAccountTracker } from '../base';
4
+ import { LOCKED_TRACKED_COINS } from './const';
5
+ import { mapPositions, mapBalance } from './mapper';
6
+ import { COLLATERAL_TOKEN_MAP } from './types';
7
+
8
+ class HyperliquidAccountTracker extends BaseAccountTracker {
9
+ address;
10
+ ws;
11
+ messageListenerId = null;
12
+ openListenerId = null;
13
+ subscribedCoins = /* @__PURE__ */ new Set();
14
+ lastSummary = {
15
+ accountValue: "0",
16
+ totalMarginUsed: "0",
17
+ totalRawUsd: "0",
18
+ crossMaintenanceMarginUsed: "0",
19
+ withdrawable: "0",
20
+ totalUnrealizedPnl: "0"
21
+ };
22
+ spotCoinBalances = /* @__PURE__ */ new Map();
23
+ accountType = null;
24
+ symbolToCollateralToken = /* @__PURE__ */ new Map();
25
+ availableToTradeByCollateral = /* @__PURE__ */ new Map();
26
+ trackedAssetData = /* @__PURE__ */ new Map();
27
+ constructor(config) {
28
+ super(config);
29
+ const creds = config.credentials;
30
+ this.credentials = config.credentials;
31
+ this.address = creds.accountIdentifier;
32
+ this.ws = config.ws;
33
+ }
34
+ async start() {
35
+ const allMetas = await fetchInfo({ type: "allPerpMetas" });
36
+ this.loadPerpMetas(allMetas);
37
+ this.messageListenerId = this.ws.addMessageListener((raw) => this.routeRaw(raw));
38
+ this.openListenerId = this.ws.addOpenListener(() => this.resubscribeAll());
39
+ this.sendStaticSubs();
40
+ for (const coin of LOCKED_TRACKED_COINS) {
41
+ this.ensureAssetTracked(coin);
42
+ }
43
+ }
44
+ async cleanupConnections() {
45
+ if (this.messageListenerId) {
46
+ this.ws.removeMessageListener(this.messageListenerId);
47
+ this.messageListenerId = null;
48
+ }
49
+ if (this.openListenerId) {
50
+ this.ws.removeOpenListener(this.openListenerId);
51
+ this.openListenerId = null;
52
+ }
53
+ this.subscribedCoins.clear();
54
+ }
55
+ get isConnected() {
56
+ return this.ws.connected;
57
+ }
58
+ ensureAssetTracked(coin) {
59
+ if (this.subscribedCoins.has(coin)) return;
60
+ this.subscribedCoins.add(coin);
61
+ this.ws.send({
62
+ method: "subscribe",
63
+ subscription: { type: "activeAssetData", coin, user: this.addrLower() }
64
+ });
65
+ }
66
+ releaseAsset(coin) {
67
+ if (this.isLocked(coin)) return;
68
+ if (!this.subscribedCoins.has(coin)) return;
69
+ this.subscribedCoins.delete(coin);
70
+ this.ws.send({
71
+ method: "unsubscribe",
72
+ subscription: { type: "activeAssetData", coin, user: this.addrLower() }
73
+ });
74
+ this.trackedAssetData.delete(coin);
75
+ this.onStateUpdate({ trackedAssets: this.buildTrackedAssetsMap() });
76
+ }
77
+ isLocked(coin) {
78
+ return LOCKED_TRACKED_COINS.includes(coin);
79
+ }
80
+ addrLower() {
81
+ return this.address.toLowerCase();
82
+ }
83
+ sendStaticSubs() {
84
+ const user = this.addrLower();
85
+ this.ws.send({ method: "subscribe", subscription: { type: "allDexsClearinghouseState", user } });
86
+ this.ws.send({ method: "subscribe", subscription: { type: "spotState", user } });
87
+ this.ws.send({ method: "subscribe", subscription: { type: "webData3", user } });
88
+ }
89
+ resubscribeAll() {
90
+ this.sendStaticSubs();
91
+ const user = this.addrLower();
92
+ for (const coin of this.subscribedCoins) {
93
+ this.ws.send({
94
+ method: "subscribe",
95
+ subscription: { type: "activeAssetData", coin, user }
96
+ });
97
+ }
98
+ }
99
+ routeRaw(raw) {
100
+ try {
101
+ const msg = JSON.parse(raw);
102
+ if (!msg.channel || !msg.data) return;
103
+ switch (msg.channel) {
104
+ case "allDexsClearinghouseState":
105
+ this.handle({ kind: "clearinghouseState", data: msg.data });
106
+ break;
107
+ case "spotState":
108
+ this.handle({ kind: "spotState", data: msg.data });
109
+ break;
110
+ case "webData3":
111
+ this.handle({ kind: "webData3", data: msg.data });
112
+ break;
113
+ case "activeAssetData":
114
+ this.handle({ kind: "activeAssetData", data: msg.data });
115
+ break;
116
+ }
117
+ } catch (err) {
118
+ this.onError(err instanceof Error ? err : new Error(String(err)));
119
+ }
120
+ }
121
+ handle(event) {
122
+ switch (event.kind) {
123
+ case "clearinghouseState":
124
+ this.onClearinghouseState(event.data);
125
+ break;
126
+ case "spotState":
127
+ this.onSpotState(event.data);
128
+ break;
129
+ case "webData3":
130
+ this.onWebData3(event.data);
131
+ break;
132
+ case "activeAssetData":
133
+ this.onActiveAssetData(event.data);
134
+ break;
135
+ }
136
+ }
137
+ loadPerpMetas(allMetas) {
138
+ allMetas.forEach((dexMeta) => {
139
+ const collateralToken = COLLATERAL_TOKEN_MAP[dexMeta.collateralToken];
140
+ dexMeta.universe.forEach((asset) => {
141
+ if (!asset.name) return;
142
+ if (collateralToken && !this.symbolToCollateralToken.has(asset.name)) {
143
+ this.symbolToCollateralToken.set(asset.name, collateralToken);
144
+ }
145
+ });
146
+ });
147
+ }
148
+ onClearinghouseState(data) {
149
+ const states = (data.clearinghouseStates || []).map(([, s]) => s).filter(Boolean);
150
+ const sumStr = (values) => values.reduce((acc, v) => acc.plus(new BigNumber(v || "0")), new BigNumber(0)).toFixed();
151
+ const allAssetPositions = states.flatMap((s) => s.assetPositions || []);
152
+ const totalUnrealizedPnl = allAssetPositions.reduce((acc, ap) => acc.plus(new BigNumber(ap.position.unrealizedPnl || "0")), new BigNumber(0)).toFixed();
153
+ this.lastSummary = {
154
+ accountValue: sumStr(states.map((s) => s.crossMarginSummary.accountValue)),
155
+ totalMarginUsed: sumStr(states.map((s) => s.crossMarginSummary.totalMarginUsed)),
156
+ totalRawUsd: sumStr(states.map((s) => s.crossMarginSummary.totalRawUsd)),
157
+ crossMaintenanceMarginUsed: sumStr(states.map((s) => s.crossMaintenanceMarginUsed)),
158
+ withdrawable: sumStr(states.map((s) => s.withdrawable)),
159
+ totalUnrealizedPnl
160
+ };
161
+ const balance = this.buildBalance();
162
+ const positions = mapPositions(allAssetPositions);
163
+ this.onStateUpdate({ balance: balance ?? void 0, positions });
164
+ }
165
+ onActiveAssetData(data) {
166
+ if (!data.coin) return;
167
+ if (!this.trackedCoins.has(data.coin)) return;
168
+ this.trackedAssetData.set(data.coin, data);
169
+ const collateral = this.symbolToCollateralToken.get(data.coin);
170
+ if (collateral && data.availableToTrade) {
171
+ const long = new BigNumber(data.availableToTrade[0] || "0");
172
+ const short = new BigNumber(data.availableToTrade[1] || "0");
173
+ const minAvailable = BigNumber.min(long, short).toFixed();
174
+ this.availableToTradeByCollateral.set(collateral, minAvailable);
175
+ const balance = this.buildBalance();
176
+ if (balance) this.onStateUpdate({ balance });
177
+ }
178
+ const trackedAssets = /* @__PURE__ */ new Map();
179
+ trackedAssets.set(data.coin, buildTrackedAssetInfo(data));
180
+ this.onStateUpdate({ trackedAssets });
181
+ }
182
+ onWebData3(data) {
183
+ this.accountType = data.userState.abstraction ?? null;
184
+ }
185
+ onSpotState(data) {
186
+ const balances = data?.spotState?.balances;
187
+ if (!balances) return;
188
+ for (const b of balances) {
189
+ const totalBN = new BigNumber(b.total || "0");
190
+ const holdBN = new BigNumber(b.hold || "0");
191
+ if (!totalBN.isZero() || !holdBN.isZero()) {
192
+ this.spotCoinBalances.set(b.coin, { coin: b.coin, total: totalBN.toFixed(), hold: holdBN.toFixed() });
193
+ } else {
194
+ this.spotCoinBalances.delete(b.coin);
195
+ }
196
+ }
197
+ const balance = this.buildBalance();
198
+ if (balance) this.onStateUpdate({ balance });
199
+ }
200
+ buildBalance() {
201
+ return mapBalance(this.lastSummary, this.spotCoinBalances, this.accountType, this.availableToTradeByCollateral);
202
+ }
203
+ buildTrackedAssetsMap() {
204
+ const result = /* @__PURE__ */ new Map();
205
+ for (const [coin, data] of this.trackedAssetData) {
206
+ result.set(coin, buildTrackedAssetInfo(data));
207
+ }
208
+ return result;
209
+ }
210
+ }
211
+ function buildTrackedAssetInfo(data) {
212
+ return {
213
+ coin: data.coin,
214
+ leverage: (data.leverage?.value ?? 1).toString(),
215
+ marginType: data.leverage?.type
216
+ };
217
+ }
218
+
219
+ export { HyperliquidAccountTracker };
@@ -0,0 +1,23 @@
1
+ declare enum HyperliquidAccountType {
2
+ DEFAULT = "default",
3
+ DEX_ABSTRACTION = "dexAbstraction",
4
+ DISABLED = "disabled",
5
+ PORTFOLIO_MARGIN = "portfolioMargin",
6
+ UNIFIED_ACCOUNT = "unifiedAccount"
7
+ }
8
+ interface HyperliquidCoinBalance {
9
+ coin: string;
10
+ total: string;
11
+ hold: string;
12
+ }
13
+ interface AggregatedClearinghouseSummary {
14
+ accountValue: string;
15
+ totalMarginUsed: string;
16
+ totalRawUsd: string;
17
+ crossMaintenanceMarginUsed: string;
18
+ withdrawable: string;
19
+ totalUnrealizedPnl: string;
20
+ }
21
+ declare const COLLATERAL_TOKEN_MAP: Record<number, string>;
22
+
23
+ export { type AggregatedClearinghouseSummary, COLLATERAL_TOKEN_MAP, HyperliquidAccountType, type HyperliquidCoinBalance };