@pear-protocol/exchanges-sdk 0.0.18 → 0.1.3

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 (190) 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 +93 -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 +43 -24
  67. package/dist/index.js +6 -21
  68. package/dist/sdk.d.ts +43 -0
  69. package/dist/sdk.js +53 -0
  70. package/dist/syncer/base.d.ts +40 -0
  71. package/dist/syncer/base.js +50 -0
  72. package/dist/syncer/binance/syncer.d.ts +24 -0
  73. package/dist/syncer/binance/syncer.js +9 -0
  74. package/dist/syncer/bybit/syncer.d.ts +24 -0
  75. package/dist/syncer/bybit/syncer.js +9 -0
  76. package/dist/syncer/factory.d.ts +22 -0
  77. package/dist/syncer/factory.js +26 -0
  78. package/dist/syncer/hyperliquid/syncer.d.ts +26 -0
  79. package/dist/syncer/hyperliquid/syncer.js +43 -0
  80. package/dist/syncer/index.d.ts +24 -0
  81. package/dist/syncer/index.js +7 -0
  82. package/dist/syncer/lighter/syncer.d.ts +24 -0
  83. package/dist/syncer/lighter/syncer.js +9 -0
  84. package/dist/syncer/okx/syncer.d.ts +24 -0
  85. package/dist/syncer/okx/syncer.js +9 -0
  86. package/dist/tracker/base.d.ts +79 -0
  87. package/dist/tracker/base.js +120 -0
  88. package/dist/tracker/binance/const.d.ts +4 -0
  89. package/dist/tracker/binance/const.js +4 -0
  90. package/dist/{account/exchanges → tracker}/binance/mapper.d.ts +4 -1
  91. package/dist/{account/exchanges → tracker}/binance/mapper.js +7 -6
  92. package/dist/tracker/binance/tracker.d.ts +60 -0
  93. package/dist/tracker/binance/tracker.js +181 -0
  94. package/dist/tracker/binance/types.d.ts +6 -0
  95. package/dist/{account/exchanges → tracker}/bybit/mapper.d.ts +5 -3
  96. package/dist/{account/exchanges → tracker}/bybit/mapper.js +11 -10
  97. package/dist/tracker/bybit/tracker.d.ts +51 -0
  98. package/dist/tracker/bybit/tracker.js +138 -0
  99. package/dist/tracker/bybit/types.d.ts +7 -0
  100. package/dist/{account/exchanges → tracker}/hyperliquid/mapper.d.ts +6 -4
  101. package/dist/{account/exchanges → tracker}/hyperliquid/mapper.js +18 -16
  102. package/dist/tracker/hyperliquid/tracker.d.ts +62 -0
  103. package/dist/tracker/hyperliquid/tracker.js +219 -0
  104. package/dist/tracker/hyperliquid/types.d.ts +23 -0
  105. package/dist/tracker/index.d.ts +38 -0
  106. package/dist/tracker/index.js +81 -0
  107. package/dist/tracker/lighter/const.d.ts +3 -0
  108. package/dist/tracker/lighter/const.js +3 -0
  109. package/dist/tracker/lighter/mapper.d.ts +16 -0
  110. package/dist/tracker/lighter/mapper.js +77 -0
  111. package/dist/tracker/lighter/tracker.d.ts +53 -0
  112. package/dist/tracker/lighter/tracker.js +150 -0
  113. package/dist/tracker/lighter/types.d.ts +16 -0
  114. package/dist/tracker/lighter/types.js +6 -0
  115. package/dist/{account/exchanges → tracker}/okx/mapper.d.ts +5 -3
  116. package/dist/{account/exchanges → tracker}/okx/mapper.js +11 -10
  117. package/dist/tracker/okx/tracker.d.ts +51 -0
  118. package/dist/tracker/okx/tracker.js +134 -0
  119. package/dist/tracker/okx/types.d.ts +8 -0
  120. package/dist/tracker/types.d.ts +63 -0
  121. package/dist/{account → tracker}/types.js +6 -4
  122. package/dist/tracker/utils.d.ts +11 -0
  123. package/dist/{account → tracker}/utils.js +0 -2
  124. package/dist/types.d.ts +50 -0
  125. package/dist/types.js +1 -0
  126. package/package.json +7 -5
  127. package/dist/account/account-manager.d.ts +0 -31
  128. package/dist/account/account-manager.js +0 -119
  129. package/dist/account/exchange-account.d.ts +0 -35
  130. package/dist/account/exchange-account.js +0 -158
  131. package/dist/account/exchanges/base.d.ts +0 -48
  132. package/dist/account/exchanges/base.js +0 -41
  133. package/dist/account/exchanges/binance/asset-tracker.d.ts +0 -26
  134. package/dist/account/exchanges/binance/asset-tracker.js +0 -38
  135. package/dist/account/exchanges/binance/const.d.ts +0 -10
  136. package/dist/account/exchanges/binance/const.js +0 -10
  137. package/dist/account/exchanges/binance/orchestrator.d.ts +0 -31
  138. package/dist/account/exchanges/binance/orchestrator.js +0 -91
  139. package/dist/account/exchanges/binance/state-handler.d.ts +0 -33
  140. package/dist/account/exchanges/binance/state-handler.js +0 -113
  141. package/dist/account/exchanges/binance/types.d.ts +0 -5
  142. package/dist/account/exchanges/binance/ws.d.ts +0 -23
  143. package/dist/account/exchanges/binance/ws.js +0 -69
  144. package/dist/account/exchanges/bybit/asset-tracker.d.ts +0 -26
  145. package/dist/account/exchanges/bybit/asset-tracker.js +0 -37
  146. package/dist/account/exchanges/bybit/const.d.ts +0 -7
  147. package/dist/account/exchanges/bybit/const.js +0 -7
  148. package/dist/account/exchanges/bybit/orchestrator.d.ts +0 -22
  149. package/dist/account/exchanges/bybit/orchestrator.js +0 -66
  150. package/dist/account/exchanges/bybit/state-handler.d.ts +0 -23
  151. package/dist/account/exchanges/bybit/state-handler.js +0 -70
  152. package/dist/account/exchanges/bybit/ws.d.ts +0 -19
  153. package/dist/account/exchanges/bybit/ws.js +0 -83
  154. package/dist/account/exchanges/hyperliquid/asset-tracker.d.ts +0 -35
  155. package/dist/account/exchanges/hyperliquid/asset-tracker.js +0 -83
  156. package/dist/account/exchanges/hyperliquid/orchestrator.d.ts +0 -26
  157. package/dist/account/exchanges/hyperliquid/orchestrator.js +0 -102
  158. package/dist/account/exchanges/hyperliquid/state-handler.d.ts +0 -25
  159. package/dist/account/exchanges/hyperliquid/state-handler.js +0 -104
  160. package/dist/account/exchanges/index.d.ts +0 -11
  161. package/dist/account/exchanges/index.js +0 -32
  162. package/dist/account/exchanges/okx/asset-tracker.d.ts +0 -26
  163. package/dist/account/exchanges/okx/asset-tracker.js +0 -34
  164. package/dist/account/exchanges/okx/const.d.ts +0 -7
  165. package/dist/account/exchanges/okx/const.js +0 -7
  166. package/dist/account/exchanges/okx/orchestrator.d.ts +0 -22
  167. package/dist/account/exchanges/okx/orchestrator.js +0 -57
  168. package/dist/account/exchanges/okx/state-handler.d.ts +0 -24
  169. package/dist/account/exchanges/okx/state-handler.js +0 -78
  170. package/dist/account/exchanges/okx/ws.d.ts +0 -20
  171. package/dist/account/exchanges/okx/ws.js +0 -103
  172. package/dist/account/index.d.ts +0 -11
  173. package/dist/account/index.js +0 -4
  174. package/dist/account/types.d.ts +0 -5
  175. package/dist/account/utils.d.ts +0 -10
  176. package/dist/credentials.d.ts +0 -28
  177. package/dist/credentials.js +0 -46
  178. package/dist/types-Caz2X4h0.d.ts +0 -151
  179. package/dist/utils/ws.d.ts +0 -10
  180. package/dist/utils/ws.js +0 -42
  181. /package/dist/{account/exchanges → client}/bybit/rest.d.ts +0 -0
  182. /package/dist/{utils → client}/hmac.d.ts +0 -0
  183. /package/dist/{utils → client}/hmac.js +0 -0
  184. /package/dist/{account/exchanges → client}/okx/rest.d.ts +0 -0
  185. /package/dist/{account/exchanges → tracker}/binance/types.js +0 -0
  186. /package/dist/{account/exchanges → tracker}/bybit/types.js +0 -0
  187. /package/dist/{account/exchanges → tracker}/hyperliquid/const.d.ts +0 -0
  188. /package/dist/{account/exchanges → tracker}/hyperliquid/const.js +0 -0
  189. /package/dist/{account/exchanges → tracker}/hyperliquid/types.js +0 -0
  190. /package/dist/{account/exchanges → tracker}/okx/types.js +0 -0
@@ -0,0 +1,79 @@
1
+ import { SupportedCredentials } from '../types.js';
2
+ import { BalanceCallback, PositionsCallback, TrackedAssetCallback, AccountBalance, AccountPosition, TrackedAssetInfo, StateUpdate } from './types.js';
3
+ import '@pear-protocol/core-sdk';
4
+ import '@pear-protocol/types';
5
+ import '../client/binance/exchange-ws.js';
6
+ import '../client/base-ws.js';
7
+ import 'partysocket';
8
+ import '../client/exchange-ws.js';
9
+ import '../client/binance/ws.js';
10
+ import '../client/bybit/exchange-ws.js';
11
+ import '../client/bybit/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 './binance/types.js';
19
+ import './bybit/types.js';
20
+ import './hyperliquid/types.js';
21
+ import './lighter/types.js';
22
+ import './okx/types.js';
23
+
24
+ type ErrorHandler = (error: Error) => void;
25
+ type AccountTrackerConfig = {
26
+ demo: boolean;
27
+ onError?: ErrorHandler;
28
+ };
29
+ interface AccountTracker {
30
+ start(): Promise<void>;
31
+ disconnect(): Promise<void>;
32
+ readonly isConnected: boolean;
33
+ readonly isInitialized: boolean;
34
+ readonly hasListeners: boolean;
35
+ trackBalance(cb: BalanceCallback): () => void;
36
+ trackPosition(cb: PositionsCallback): () => void;
37
+ trackAsset(asset: string, cb: TrackedAssetCallback): () => void;
38
+ getBalance(): AccountBalance | null;
39
+ getPositions(): AccountPosition[];
40
+ getTrackedAsset(coin: string): TrackedAssetInfo | null;
41
+ }
42
+ declare abstract class BaseAccountTracker implements AccountTracker {
43
+ protected onError: ErrorHandler;
44
+ protected demo: boolean;
45
+ protected credentials: SupportedCredentials | null;
46
+ private balance;
47
+ private positions;
48
+ private initialized;
49
+ private balanceListeners;
50
+ private positionListeners;
51
+ private assetEntries;
52
+ constructor(config: AccountTrackerConfig);
53
+ disconnect(): Promise<void>;
54
+ get isInitialized(): boolean;
55
+ get hasListeners(): boolean;
56
+ trackBalance(cb: BalanceCallback): () => void;
57
+ trackPosition(cb: PositionsCallback): () => void;
58
+ trackAsset(asset: string, cb: TrackedAssetCallback): () => void;
59
+ private releaseAssetListener;
60
+ protected get trackedCoins(): ReadonlySet<string>;
61
+ getBalance(): AccountBalance | null;
62
+ getPositions(): AccountPosition[];
63
+ getTrackedAsset(coin: string): TrackedAssetInfo | null;
64
+ protected onStateUpdate(update: StateUpdate): void;
65
+ private applyBalanceUpdate;
66
+ private applyPositionsUpdate;
67
+ private applyTrackedAssetsUpdate;
68
+ private getOrCreateAssetEntry;
69
+ private positionSnapshot;
70
+ private notify;
71
+ private broadcast;
72
+ abstract start(): Promise<void>;
73
+ abstract get isConnected(): boolean;
74
+ protected abstract ensureAssetTracked(asset: string): void;
75
+ protected abstract releaseAsset(asset: string): void;
76
+ protected abstract cleanupConnections(): void | Promise<void>;
77
+ }
78
+
79
+ export { type AccountTracker, type AccountTrackerConfig, BaseAccountTracker };
@@ -0,0 +1,120 @@
1
+ class BaseAccountTracker {
2
+ onError;
3
+ demo;
4
+ credentials = null;
5
+ balance = null;
6
+ positions = /* @__PURE__ */ new Map();
7
+ initialized = false;
8
+ balanceListeners = /* @__PURE__ */ new Set();
9
+ positionListeners = /* @__PURE__ */ new Set();
10
+ assetEntries = /* @__PURE__ */ new Map();
11
+ constructor(config) {
12
+ this.demo = config.demo;
13
+ this.onError = (error) => {
14
+ console.warn("[AccountTracker] error:", error.message);
15
+ config.onError?.(error);
16
+ };
17
+ }
18
+ async disconnect() {
19
+ this.balanceListeners.clear();
20
+ this.positionListeners.clear();
21
+ this.assetEntries.clear();
22
+ await this.cleanupConnections();
23
+ }
24
+ get isInitialized() {
25
+ return this.initialized;
26
+ }
27
+ get hasListeners() {
28
+ if (this.balanceListeners.size > 0 || this.positionListeners.size > 0) return true;
29
+ for (const entry of this.assetEntries.values()) {
30
+ if (entry.listeners.size > 0) return true;
31
+ }
32
+ return false;
33
+ }
34
+ trackBalance(cb) {
35
+ this.balanceListeners.add(cb);
36
+ if (this.balance) this.notify(cb, this.balance);
37
+ return () => this.balanceListeners.delete(cb);
38
+ }
39
+ trackPosition(cb) {
40
+ this.positionListeners.add(cb);
41
+ if (this.initialized) this.notify(cb, this.positionSnapshot());
42
+ return () => this.positionListeners.delete(cb);
43
+ }
44
+ trackAsset(asset, cb) {
45
+ const entry = this.getOrCreateAssetEntry(asset);
46
+ entry.listeners.add(cb);
47
+ if (this.isConnected) this.ensureAssetTracked(asset);
48
+ if (entry.info) this.notify(cb, entry.info);
49
+ return () => this.releaseAssetListener(asset, cb);
50
+ }
51
+ releaseAssetListener(asset, cb) {
52
+ const entry = this.assetEntries.get(asset);
53
+ if (!entry) return;
54
+ entry.listeners.delete(cb);
55
+ if (entry.listeners.size === 0 && this.isConnected) {
56
+ this.releaseAsset(asset);
57
+ }
58
+ }
59
+ get trackedCoins() {
60
+ return new Set(
61
+ [...this.assetEntries.entries()].filter(([, entry]) => entry.listeners.size > 0).map(([coin]) => coin)
62
+ );
63
+ }
64
+ getBalance() {
65
+ return this.balance;
66
+ }
67
+ getPositions() {
68
+ return this.positionSnapshot();
69
+ }
70
+ getTrackedAsset(coin) {
71
+ return this.assetEntries.get(coin)?.info ?? null;
72
+ }
73
+ onStateUpdate(update) {
74
+ if (update.balance) this.applyBalanceUpdate(update.balance);
75
+ if (update.positions) this.applyPositionsUpdate(update.positions);
76
+ if (update.trackedAssets) this.applyTrackedAssetsUpdate(update.trackedAssets);
77
+ if (!this.initialized) this.initialized = true;
78
+ }
79
+ applyBalanceUpdate(balance) {
80
+ this.balance = balance;
81
+ this.broadcast(this.balanceListeners, balance);
82
+ }
83
+ applyPositionsUpdate(positions) {
84
+ for (const [key, pos] of positions) {
85
+ if (pos.size === "0") this.positions.delete(key);
86
+ else this.positions.set(key, pos);
87
+ }
88
+ this.broadcast(this.positionListeners, this.positionSnapshot());
89
+ }
90
+ applyTrackedAssetsUpdate(trackedAssets) {
91
+ for (const [coin, info] of trackedAssets) {
92
+ const entry = this.getOrCreateAssetEntry(coin);
93
+ entry.info = info;
94
+ this.broadcast(entry.listeners, info);
95
+ }
96
+ }
97
+ getOrCreateAssetEntry(coin) {
98
+ let entry = this.assetEntries.get(coin);
99
+ if (!entry) {
100
+ entry = { info: null, listeners: /* @__PURE__ */ new Set() };
101
+ this.assetEntries.set(coin, entry);
102
+ }
103
+ return entry;
104
+ }
105
+ positionSnapshot() {
106
+ return Array.from(this.positions.values());
107
+ }
108
+ notify(cb, arg) {
109
+ try {
110
+ cb(arg);
111
+ } catch (err) {
112
+ this.onError(err instanceof Error ? err : new Error(String(err)));
113
+ }
114
+ }
115
+ broadcast(listeners, arg) {
116
+ for (const cb of listeners) this.notify(cb, arg);
117
+ }
118
+ }
119
+
120
+ export { BaseAccountTracker };
@@ -0,0 +1,4 @@
1
+ declare const DEFAULT_LISTEN_KEY_REFRESH_MS: number;
2
+ declare const DEFAULT_ACCOUNT_POLL_MS = 1000;
3
+
4
+ export { DEFAULT_ACCOUNT_POLL_MS, DEFAULT_LISTEN_KEY_REFRESH_MS };
@@ -0,0 +1,4 @@
1
+ const DEFAULT_LISTEN_KEY_REFRESH_MS = 25 * 60 * 1e3;
2
+ const DEFAULT_ACCOUNT_POLL_MS = 1e3;
3
+
4
+ export { DEFAULT_ACCOUNT_POLL_MS, DEFAULT_LISTEN_KEY_REFRESH_MS };
@@ -1,7 +1,10 @@
1
- import { j as BinanceRawAccountStatus, a as AccountBalance, k as BinanceRawPositionRisk, c as AccountPosition } from '../../../types-Caz2X4h0.js';
1
+ import { BinanceRawAccountStatus, BinanceRawPositionRisk } from '../../client/binance/types.js';
2
+ import { AccountBalance, AccountPosition } from '../types.js';
2
3
  import '@pear-protocol/types';
4
+ import './types.js';
3
5
  import '../bybit/types.js';
4
6
  import '../hyperliquid/types.js';
7
+ import '../lighter/types.js';
5
8
  import '../okx/types.js';
6
9
 
7
10
  declare function mapBalance(raw: BinanceRawAccountStatus): Omit<AccountBalance, 'accountType'>;
@@ -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
 
4
5
  function mapBalance(raw) {
5
6
  const free = {};
@@ -11,7 +12,7 @@ function mapBalance(raw) {
11
12
  const ab = a.availableBalance ?? "0";
12
13
  const mb = a.marginBalance ?? "0";
13
14
  const im = a.initialMargin ?? "0";
14
- if (parseFloat(wb) === 0 && parseFloat(ab) === 0 && parseFloat(mb) === 0) continue;
15
+ if (new BigNumber(wb).isZero() && new BigNumber(ab).isZero() && new BigNumber(mb).isZero()) continue;
15
16
  free[a.asset] = ab;
16
17
  used[a.asset] = im;
17
18
  total[a.asset] = mb;
@@ -26,9 +27,9 @@ function mapBalance(raw) {
26
27
  }
27
28
  const totalMarginBalance = raw.totalMarginBalance ?? "0";
28
29
  const totalMaintMargin = raw.totalMaintMargin ?? "0";
29
- const marginBalance = parseFloat(totalMarginBalance);
30
- const maintMargin = parseFloat(totalMaintMargin);
31
- const marginRatio = marginBalance > 0 ? (maintMargin / marginBalance).toFixed(4) : "0.0000";
30
+ const marginBalanceBN = new BigNumber(totalMarginBalance);
31
+ const maintMarginBN = new BigNumber(totalMaintMargin);
32
+ const marginRatio = marginBalanceBN.gt(0) ? maintMarginBN.div(marginBalanceBN).toFixed(4) : "0.0000";
32
33
  return {
33
34
  free,
34
35
  used,
@@ -0,0 +1,60 @@
1
+ import { BinanceUserDataWs, BinanceWsApi } from '../../client/binance/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 '@pear-protocol/core-sdk';
8
+ import '../../client/binance/exchange-ws.js';
9
+ import '../../client/exchange-ws.js';
10
+ import '../../client/bybit/exchange-ws.js';
11
+ import '../../client/bybit/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 './types.js';
20
+ import '../bybit/types.js';
21
+ import '../hyperliquid/types.js';
22
+ import '../lighter/types.js';
23
+ import '../okx/types.js';
24
+
25
+ type BinanceAccountTrackerConfig = AccountTrackerConfig & {
26
+ credentials: SupportedCredentials;
27
+ userDataWs: BinanceUserDataWs;
28
+ wsApiWs: BinanceWsApi;
29
+ listenKeyRefreshMs?: number;
30
+ accountPollMs?: number;
31
+ };
32
+ declare class BinanceAccountTracker extends BaseAccountTracker {
33
+ private readonly creds;
34
+ private readonly userDataWs;
35
+ private readonly wsApiWs;
36
+ private readonly listenKeyRefreshMs;
37
+ private readonly accountPollMs;
38
+ private userDataListenerId;
39
+ private wsApiListenerId;
40
+ private listenKeyTimer;
41
+ private pollTimer;
42
+ private currentPositions;
43
+ private accountType;
44
+ private trackedAssetInfos;
45
+ constructor(config: BinanceAccountTrackerConfig);
46
+ start(): Promise<void>;
47
+ protected cleanupConnections(): Promise<void>;
48
+ get isConnected(): boolean;
49
+ protected ensureAssetTracked(coin: string): void;
50
+ protected releaseAsset(coin: string): void;
51
+ private pollAccountStatus;
52
+ private routeUserData;
53
+ private routeWsApi;
54
+ private handleAccountStatus;
55
+ private handlePositionRisk;
56
+ private handleUserDataEvent;
57
+ private refreshAllPositions;
58
+ }
59
+
60
+ export { BinanceAccountTracker, type BinanceAccountTrackerConfig };
@@ -0,0 +1,181 @@
1
+ import { fetchAccountStatus, fetchAllPositionRisk, fetchMultiAssetsMargin, keepAliveListenKey, fetchPositionRisk } from '../../client/binance/rest';
2
+ import { BaseAccountTracker } from '../base';
3
+ import { positionKey } from '../utils';
4
+ import { DEFAULT_LISTEN_KEY_REFRESH_MS, DEFAULT_ACCOUNT_POLL_MS } from './const';
5
+ import { mapBalance, mapPositions, mergePositions } from './mapper';
6
+ import { BinanceAccountType } from './types';
7
+
8
+ class BinanceAccountTracker extends BaseAccountTracker {
9
+ creds;
10
+ userDataWs;
11
+ wsApiWs;
12
+ listenKeyRefreshMs;
13
+ accountPollMs;
14
+ userDataListenerId = null;
15
+ wsApiListenerId = null;
16
+ listenKeyTimer = null;
17
+ pollTimer = null;
18
+ currentPositions = /* @__PURE__ */ new Map();
19
+ accountType = BinanceAccountType.SINGLE_ASSET;
20
+ trackedAssetInfos = /* @__PURE__ */ new Map();
21
+ constructor(config) {
22
+ super(config);
23
+ this.credentials = config.credentials;
24
+ this.creds = config.credentials;
25
+ this.userDataWs = config.userDataWs;
26
+ this.wsApiWs = config.wsApiWs;
27
+ this.listenKeyRefreshMs = config.listenKeyRefreshMs ?? DEFAULT_LISTEN_KEY_REFRESH_MS;
28
+ this.accountPollMs = config.accountPollMs ?? DEFAULT_ACCOUNT_POLL_MS;
29
+ }
30
+ async start() {
31
+ const [snapshot, positionRisk, multiAssetsMargin] = await Promise.all([
32
+ fetchAccountStatus(this.creds, this.demo),
33
+ fetchAllPositionRisk(this.creds, this.demo),
34
+ fetchMultiAssetsMargin(this.creds, this.demo)
35
+ ]);
36
+ this.accountType = multiAssetsMargin ? BinanceAccountType.MULTI_ASSET : BinanceAccountType.SINGLE_ASSET;
37
+ this.handleAccountStatus(snapshot);
38
+ this.handlePositionRisk(positionRisk, false);
39
+ this.userDataListenerId = this.userDataWs.addMessageListener((raw) => this.routeUserData(raw));
40
+ this.wsApiListenerId = this.wsApiWs.addMessageListener((raw) => this.routeWsApi(raw));
41
+ this.listenKeyTimer = setInterval(() => {
42
+ keepAliveListenKey(this.creds.read.api_key, this.demo).catch(
43
+ (err) => this.onError(err instanceof Error ? err : new Error(String(err)))
44
+ );
45
+ }, this.listenKeyRefreshMs);
46
+ this.pollAccountStatus();
47
+ this.pollTimer = setInterval(() => this.pollAccountStatus(), this.accountPollMs);
48
+ }
49
+ async cleanupConnections() {
50
+ if (this.listenKeyTimer) clearInterval(this.listenKeyTimer);
51
+ this.listenKeyTimer = null;
52
+ if (this.pollTimer) clearInterval(this.pollTimer);
53
+ this.pollTimer = null;
54
+ if (this.userDataListenerId) {
55
+ this.userDataWs.removeMessageListener(this.userDataListenerId);
56
+ this.userDataListenerId = null;
57
+ }
58
+ if (this.wsApiListenerId) {
59
+ this.wsApiWs.removeMessageListener(this.wsApiListenerId);
60
+ this.wsApiListenerId = null;
61
+ }
62
+ }
63
+ get isConnected() {
64
+ return this.userDataWs.connected && this.wsApiWs.connected;
65
+ }
66
+ ensureAssetTracked(coin) {
67
+ if (this.trackedAssetInfos.has(coin)) return;
68
+ fetchPositionRisk(this.creds, coin, this.demo).then((risk) => {
69
+ if (!risk) return;
70
+ const leverage = risk.leverage;
71
+ const marginType = risk.marginType;
72
+ const info = { coin, leverage, marginType };
73
+ this.trackedAssetInfos.set(coin, info);
74
+ const trackedAssets = /* @__PURE__ */ new Map();
75
+ trackedAssets.set(coin, info);
76
+ this.onStateUpdate({ trackedAssets });
77
+ }).catch((err) => {
78
+ this.onError(err instanceof Error ? err : new Error(String(err)));
79
+ });
80
+ }
81
+ releaseAsset(coin) {
82
+ this.trackedAssetInfos.delete(coin);
83
+ this.onStateUpdate({ trackedAssets: new Map(this.trackedAssetInfos) });
84
+ }
85
+ pollAccountStatus() {
86
+ if (!this.wsApiWs.connected) return;
87
+ this.wsApiWs.sendSignedRequest(this.creds, "v2/account.status").catch((err) => {
88
+ this.onError(err instanceof Error ? err : new Error(String(err)));
89
+ });
90
+ }
91
+ routeUserData(raw) {
92
+ try {
93
+ const event = JSON.parse(raw);
94
+ this.handleUserDataEvent(event);
95
+ } catch (err) {
96
+ this.onError(err instanceof Error ? err : new Error(String(err)));
97
+ }
98
+ }
99
+ routeWsApi(raw) {
100
+ try {
101
+ const msg = JSON.parse(raw);
102
+ if (msg.id !== void 0 && msg.result !== void 0) {
103
+ this.handleAccountStatus(msg.result);
104
+ }
105
+ } catch (err) {
106
+ this.onError(err instanceof Error ? err : new Error(String(err)));
107
+ }
108
+ }
109
+ handleAccountStatus(result) {
110
+ const balance = { ...mapBalance(result), accountType: this.accountType };
111
+ this.onStateUpdate({ balance });
112
+ }
113
+ handlePositionRisk(risk, merge) {
114
+ let positions = mapPositions(risk);
115
+ if (merge && this.currentPositions.size > 0) {
116
+ positions = mergePositions(positions, this.currentPositions);
117
+ }
118
+ this.currentPositions = positions;
119
+ this.onStateUpdate({ positions });
120
+ }
121
+ handleUserDataEvent(event) {
122
+ if (event.e === "ACCOUNT_CONFIG_UPDATE" && event.ac) {
123
+ const symbol = event.ac.s ?? "";
124
+ const leverage = event.ac.l ?? "0";
125
+ if (symbol && leverage !== "0") {
126
+ const existing = this.trackedAssetInfos.get(symbol);
127
+ if (existing) {
128
+ const updated = { ...existing, leverage };
129
+ this.trackedAssetInfos.set(symbol, updated);
130
+ const trackedAssets = /* @__PURE__ */ new Map();
131
+ trackedAssets.set(symbol, updated);
132
+ this.onStateUpdate({ trackedAssets });
133
+ }
134
+ }
135
+ this.refreshAllPositions();
136
+ }
137
+ if (event.e === "ACCOUNT_UPDATE") {
138
+ this.refreshAllPositions();
139
+ }
140
+ }
141
+ refreshAllPositions() {
142
+ const symbols = /* @__PURE__ */ new Set();
143
+ for (const pos of this.currentPositions.values()) symbols.add(pos.symbol);
144
+ for (const coin of this.trackedCoins) symbols.add(coin);
145
+ if (symbols.size === 0) return;
146
+ const promises = Array.from(symbols).map(
147
+ (symbol) => fetchPositionRisk(this.creds, symbol, this.demo).catch(() => void 0)
148
+ );
149
+ Promise.all(promises).then((results) => {
150
+ const freshPositions = /* @__PURE__ */ new Map();
151
+ for (const risk of results) {
152
+ if (!risk) continue;
153
+ const amt = risk.positionAmt ?? "0";
154
+ if (amt === "0" || amt === "") continue;
155
+ const symbol = risk.symbol ?? "";
156
+ const side = amt.startsWith("-") ? "short" : "long";
157
+ freshPositions.set(positionKey(symbol, side), {
158
+ symbol,
159
+ side,
160
+ size: amt,
161
+ entryPrice: risk.entryPrice ?? "0",
162
+ unrealizedPnl: risk.unRealizedProfit ?? "0",
163
+ leverage: risk.leverage ?? "0",
164
+ marginType: risk.marginType,
165
+ liquidationPrice: risk.liquidationPrice || null
166
+ });
167
+ }
168
+ for (const [key, pos] of this.currentPositions) {
169
+ if (!symbols.has(pos.symbol) && !freshPositions.has(key)) {
170
+ freshPositions.set(key, pos);
171
+ }
172
+ }
173
+ this.currentPositions = freshPositions;
174
+ this.onStateUpdate({ positions: freshPositions });
175
+ }).catch((err) => {
176
+ this.onError(err instanceof Error ? err : new Error(String(err)));
177
+ });
178
+ }
179
+ }
180
+
181
+ export { BinanceAccountTracker };
@@ -0,0 +1,6 @@
1
+ declare enum BinanceAccountType {
2
+ MULTI_ASSET = "MULTI_ASSET",
3
+ SINGLE_ASSET = "SINGLE_ASSET"
4
+ }
5
+
6
+ export { BinanceAccountType };
@@ -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 };