@pear-protocol/exchanges-sdk 0.6.5 → 0.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/base-ws.js +15 -6
- package/dist/client/binance/exchange-ws.js +22 -8
- package/dist/client/binance/rest.js +40 -27
- package/dist/client/binance/ws.js +21 -2
- package/dist/client/bybit/exchange-ws.js +13 -6
- package/dist/client/bybit/rest.js +30 -36
- package/dist/client/bybit/ws.js +16 -2
- package/dist/client/exchange-ws.js +5 -0
- package/dist/client/hmac.js +9 -1
- package/dist/client/hyperliquid/exchange-ws.js +13 -5
- package/dist/client/hyperliquid/rest.js +37 -7
- package/dist/client/hyperliquid/ws.js +10 -4
- package/dist/client/index.js +9 -2
- package/dist/client/lighter/constants.js +4 -0
- package/dist/client/lighter/exchange-ws.js +13 -5
- package/dist/client/lighter/rest.js +153 -18
- package/dist/client/lighter/ws.js +10 -4
- package/dist/client/okx/exchange-ws.js +13 -6
- package/dist/client/okx/rest.js +27 -24
- package/dist/client/okx/ws.js +5 -0
- package/dist/helper/factory.js +3 -0
- package/dist/helper/hyperliquid/helper.js +18 -23
- package/dist/helper/lighter/auth-token.helper.js +68 -0
- package/dist/helper/lighter/cctp-deposit.helper.js +297 -0
- package/dist/helper/lighter/ethereum/abi.js +55 -11
- package/dist/helper/lighter/ethereum/index.js +22 -3
- package/dist/helper/lighter/ethereum/usdc.helper.js +77 -0
- package/dist/helper/lighter/helper.js +112 -37
- package/dist/helper/lighter/index.js +1 -0
- package/dist/helper/lighter/onboarding.helper.js +28 -0
- package/dist/helper/lighter/types.js +6 -1
- package/dist/helper/subaccount.helper.js +20 -0
- package/dist/index.d.ts +200 -1
- package/dist/sdk.js +18 -7
- package/dist/status/base.js +16 -3
- package/dist/status/binance/status.js +3 -0
- package/dist/status/bybit/status.js +3 -0
- package/dist/status/factory.js +3 -0
- package/dist/status/hyperliquid/status.js +8 -6
- package/dist/status/lighter/status.js +11 -3
- package/dist/status/okx/status.js +3 -0
- package/dist/syncer/base.js +63 -24
- package/dist/syncer/binance/syncer.js +14 -13
- package/dist/syncer/bybit/syncer.js +10 -6
- package/dist/syncer/factory.js +3 -0
- package/dist/syncer/hyperliquid/funding.js +3 -0
- package/dist/syncer/hyperliquid/syncer.js +52 -66
- package/dist/syncer/lighter/funding.js +3 -0
- package/dist/syncer/lighter/syncer.js +26 -25
- package/dist/syncer/okx/syncer.js +15 -13
- package/dist/tracker/base.js +15 -5
- package/dist/tracker/binance/mapper.js +5 -1
- package/dist/tracker/binance/tracker.js +63 -23
- package/dist/tracker/binance/types.js +2 -2
- package/dist/tracker/bybit/mapper.js +7 -1
- package/dist/tracker/bybit/tracker.js +68 -24
- package/dist/tracker/bybit/types.js +2 -2
- package/dist/tracker/hyperliquid/const.js +3 -1
- package/dist/tracker/hyperliquid/mapper.js +36 -20
- package/dist/tracker/hyperliquid/tracker.js +147 -54
- package/dist/tracker/hyperliquid/types.js +2 -2
- package/dist/tracker/index.js +3 -0
- package/dist/tracker/lighter/mapper.js +41 -31
- package/dist/tracker/lighter/tracker.js +68 -27
- package/dist/tracker/lighter/types.js +4 -4
- package/dist/tracker/okx/mapper.js +8 -0
- package/dist/tracker/okx/tracker.js +69 -18
- package/dist/tracker/okx/types.js +2 -2
- package/dist/tracker/utils.js +4 -0
- package/package.json +3 -3
- package/dist/client/hyperliquid/client.test.js +0 -41
- package/dist/client/lighter/constants.test.js +0 -22
- package/dist/client/lighter/rest.test.js +0 -158
- package/dist/helper/hyperliquid/helper.test.js +0 -72
- package/dist/helper/lighter/helper.test.js +0 -289
- package/dist/sdk.test.js +0 -117
- package/dist/status/hyperliquid/status.test.js +0 -94
- package/dist/status/lighter/status.test.js +0 -86
- package/dist/syncer/base.test.js +0 -178
- package/dist/syncer/hyperliquid/funding.test.js +0 -63
- package/dist/syncer/hyperliquid/syncer.test.js +0 -271
- package/dist/syncer/lighter/funding.test.js +0 -48
- package/dist/syncer/lighter/syncer.test.js +0 -274
- package/dist/tracker/base.test.js +0 -132
- package/dist/tracker/binance/tracker.test.js +0 -138
- package/dist/tracker/bybit/tracker.test.js +0 -145
- package/dist/tracker/hyperliquid/mapper.test.js +0 -260
- package/dist/tracker/hyperliquid/tracker.test.js +0 -597
- package/dist/tracker/lighter/mapper.test.js +0 -199
- package/dist/tracker/lighter/tracker.test.js +0 -515
- package/dist/tracker/okx/tracker.test.js +0 -126
- package/dist/tracker/utils.test.js +0 -8
|
@@ -2,19 +2,23 @@ import BigNumber from 'bignumber.js';
|
|
|
2
2
|
import { fetchPositions, fetchFillsHistorySince } from '../../client/okx/rest';
|
|
3
3
|
import { BaseAccountSyncer } from '../base';
|
|
4
4
|
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
5
7
|
class OkxAccountSyncer extends BaseAccountSyncer {
|
|
8
|
+
static {
|
|
9
|
+
__name(this, "OkxAccountSyncer");
|
|
10
|
+
}
|
|
6
11
|
creds;
|
|
7
12
|
constructor(config) {
|
|
8
13
|
super(config);
|
|
9
14
|
this.creds = config.credentials;
|
|
10
15
|
}
|
|
11
|
-
async listExternalPositions({
|
|
12
|
-
instruments
|
|
13
|
-
}) {
|
|
16
|
+
async listExternalPositions({ instruments }) {
|
|
14
17
|
const rawPositions = await fetchPositions(this.creds, this.demo);
|
|
15
|
-
const contractSizeByInstrumentId = new Map(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
const contractSizeByInstrumentId = new Map(instruments.map((instrument) => [
|
|
19
|
+
instrument.id,
|
|
20
|
+
instrument.precision.quantity.contractSize
|
|
21
|
+
]));
|
|
18
22
|
return rawPositions.reduce((positions, rawPosition) => {
|
|
19
23
|
if (!rawPosition.pos || rawPosition.pos === "0") return positions;
|
|
20
24
|
const contractSize = contractSizeByInstrumentId.get(rawPosition.instId) ?? 1;
|
|
@@ -29,14 +33,12 @@ class OkxAccountSyncer extends BaseAccountSyncer {
|
|
|
29
33
|
return positions;
|
|
30
34
|
}, []);
|
|
31
35
|
}
|
|
32
|
-
async listExternalFills({
|
|
33
|
-
since,
|
|
34
|
-
instruments
|
|
35
|
-
}) {
|
|
36
|
+
async listExternalFills({ since, instruments }) {
|
|
36
37
|
const fills = await fetchFillsHistorySince(this.creds, since, this.demo);
|
|
37
|
-
const contractSizeByInstrumentId = new Map(
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
const contractSizeByInstrumentId = new Map(instruments.map((instrument) => [
|
|
39
|
+
instrument.id,
|
|
40
|
+
instrument.precision.quantity.contractSize
|
|
41
|
+
]));
|
|
40
42
|
return fills.reduce((result, rawFill) => {
|
|
41
43
|
const contractSize = contractSizeByInstrumentId.get(rawFill.instId) ?? 1;
|
|
42
44
|
result.push({
|
package/dist/tracker/base.js
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
1
3
|
class BaseAccountTracker {
|
|
4
|
+
static {
|
|
5
|
+
__name(this, "BaseAccountTracker");
|
|
6
|
+
}
|
|
2
7
|
onError;
|
|
3
8
|
demo;
|
|
4
9
|
credentials;
|
|
@@ -18,7 +23,9 @@ class BaseAccountTracker {
|
|
|
18
23
|
};
|
|
19
24
|
}
|
|
20
25
|
async snapshotAssets(coins) {
|
|
21
|
-
const unique = [
|
|
26
|
+
const unique = [
|
|
27
|
+
...new Set(coins)
|
|
28
|
+
];
|
|
22
29
|
if (unique.length === 0) return {};
|
|
23
30
|
return this.fetchAssetSnapshots(unique);
|
|
24
31
|
}
|
|
@@ -64,9 +71,9 @@ class BaseAccountTracker {
|
|
|
64
71
|
}
|
|
65
72
|
}
|
|
66
73
|
get trackedCoins() {
|
|
67
|
-
return new Set(
|
|
68
|
-
|
|
69
|
-
);
|
|
74
|
+
return new Set([
|
|
75
|
+
...this.assetEntries.entries()
|
|
76
|
+
].filter(([, entry]) => entry.listeners.size > 0).map(([coin]) => coin));
|
|
70
77
|
}
|
|
71
78
|
getBalance() {
|
|
72
79
|
return this.balance;
|
|
@@ -114,7 +121,10 @@ class BaseAccountTracker {
|
|
|
114
121
|
getOrCreateAssetEntry(coin) {
|
|
115
122
|
let entry = this.assetEntries.get(coin);
|
|
116
123
|
if (!entry) {
|
|
117
|
-
entry = {
|
|
124
|
+
entry = {
|
|
125
|
+
info: null,
|
|
126
|
+
listeners: /* @__PURE__ */ new Set()
|
|
127
|
+
};
|
|
118
128
|
this.assetEntries.set(coin, entry);
|
|
119
129
|
}
|
|
120
130
|
return entry;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import BigNumber from 'bignumber.js';
|
|
2
|
-
import '../types';
|
|
3
2
|
import { positionKey } from '../utils';
|
|
4
3
|
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
5
6
|
function mapBalance(raw) {
|
|
6
7
|
const free = {};
|
|
7
8
|
const used = {};
|
|
@@ -45,6 +46,7 @@ function mapBalance(raw) {
|
|
|
45
46
|
timestamp: Date.now()
|
|
46
47
|
};
|
|
47
48
|
}
|
|
49
|
+
__name(mapBalance, "mapBalance");
|
|
48
50
|
function mapPositions(raw) {
|
|
49
51
|
const positions = /* @__PURE__ */ new Map();
|
|
50
52
|
for (const p of raw) {
|
|
@@ -65,6 +67,7 @@ function mapPositions(raw) {
|
|
|
65
67
|
}
|
|
66
68
|
return positions;
|
|
67
69
|
}
|
|
70
|
+
__name(mapPositions, "mapPositions");
|
|
68
71
|
function mergePositions(incoming, existing) {
|
|
69
72
|
const merged = /* @__PURE__ */ new Map();
|
|
70
73
|
for (const [key, pos] of incoming) {
|
|
@@ -82,5 +85,6 @@ function mergePositions(incoming, existing) {
|
|
|
82
85
|
}
|
|
83
86
|
return merged;
|
|
84
87
|
}
|
|
88
|
+
__name(mergePositions, "mergePositions");
|
|
85
89
|
|
|
86
90
|
export { mapBalance, mapPositions, mergePositions };
|
|
@@ -6,7 +6,12 @@ import { DEFAULT_LISTEN_KEY_REFRESH_MS, DEFAULT_ACCOUNT_POLL_MS } from './const'
|
|
|
6
6
|
import { mapBalance, mapPositions, mergePositions } from './mapper';
|
|
7
7
|
import { BinanceAccountType } from './types';
|
|
8
8
|
|
|
9
|
+
var __defProp = Object.defineProperty;
|
|
10
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
11
|
class BinanceAccountTracker extends BaseAccountTracker {
|
|
12
|
+
static {
|
|
13
|
+
__name(this, "BinanceAccountTracker");
|
|
14
|
+
}
|
|
10
15
|
creds;
|
|
11
16
|
userDataWs = null;
|
|
12
17
|
wsApiWs = null;
|
|
@@ -28,16 +33,25 @@ class BinanceAccountTracker extends BaseAccountTracker {
|
|
|
28
33
|
async snapshot() {
|
|
29
34
|
const { snapshot, positionRisk, multiAssetsMargin } = await this.fetchSnapshotData();
|
|
30
35
|
const accountType = multiAssetsMargin ? BinanceAccountType.MULTI_ASSET : BinanceAccountType.SINGLE_ASSET;
|
|
31
|
-
const balance = {
|
|
32
|
-
|
|
36
|
+
const balance = {
|
|
37
|
+
...mapBalance(snapshot),
|
|
38
|
+
accountType
|
|
39
|
+
};
|
|
40
|
+
return {
|
|
41
|
+
balance,
|
|
42
|
+
positions: Array.from(mapPositions(positionRisk).values())
|
|
43
|
+
};
|
|
33
44
|
}
|
|
34
45
|
/**
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
* Stateless one-shot per-asset settings read: `positionRisk` with no symbol returns leverage +
|
|
47
|
+
* margin type for every symbol (positioned or not), so any number of assets costs one call.
|
|
48
|
+
*/
|
|
38
49
|
async fetchAssetSnapshots(coins) {
|
|
39
50
|
const risks = await fetchAllPositionRisk(this.creds, this.demo);
|
|
40
|
-
const bySymbol = new Map(risks.map((risk) => [
|
|
51
|
+
const bySymbol = new Map(risks.map((risk) => [
|
|
52
|
+
risk.symbol,
|
|
53
|
+
risk
|
|
54
|
+
]));
|
|
41
55
|
const result = {};
|
|
42
56
|
for (const coin of coins) {
|
|
43
57
|
const risk = bySymbol.get(coin);
|
|
@@ -50,15 +64,16 @@ class BinanceAccountTracker extends BaseAccountTracker {
|
|
|
50
64
|
this.accountType = multiAssetsMargin ? BinanceAccountType.MULTI_ASSET : BinanceAccountType.SINGLE_ASSET;
|
|
51
65
|
this.handleAccountStatus(snapshot);
|
|
52
66
|
this.handlePositionRisk(positionRisk, false);
|
|
53
|
-
const ws = await createExchangeWs("binance", {
|
|
67
|
+
const ws = await createExchangeWs("binance", {
|
|
68
|
+
demo: this.demo,
|
|
69
|
+
credentials: this.credentials
|
|
70
|
+
});
|
|
54
71
|
this.userDataWs = ws.userData;
|
|
55
72
|
this.wsApiWs = ws.wsApi;
|
|
56
73
|
this.userDataListenerId = this.userDataWs.addMessageListener((raw) => this.routeUserData(raw));
|
|
57
74
|
this.wsApiListenerId = this.wsApiWs.addMessageListener((raw) => this.routeWsApi(raw));
|
|
58
75
|
this.listenKeyTimer = setInterval(() => {
|
|
59
|
-
keepAliveListenKey(this.creds.read.api_key, this.demo).catch(
|
|
60
|
-
(err) => this.onError(err instanceof Error ? err : new Error(String(err)))
|
|
61
|
-
);
|
|
76
|
+
keepAliveListenKey(this.creds.read.api_key, this.demo).catch((err) => this.onError(err instanceof Error ? err : new Error(String(err))));
|
|
62
77
|
}, this.listenKeyRefreshMs);
|
|
63
78
|
this.pollAccountStatus();
|
|
64
79
|
this.pollTimer = setInterval(() => this.pollAccountStatus(), this.accountPollMs);
|
|
@@ -90,7 +105,11 @@ class BinanceAccountTracker extends BaseAccountTracker {
|
|
|
90
105
|
fetchAllPositionRisk(this.creds, this.demo),
|
|
91
106
|
fetchMultiAssetsMargin(this.creds, this.demo)
|
|
92
107
|
]);
|
|
93
|
-
return {
|
|
108
|
+
return {
|
|
109
|
+
snapshot,
|
|
110
|
+
positionRisk,
|
|
111
|
+
multiAssetsMargin
|
|
112
|
+
};
|
|
94
113
|
}
|
|
95
114
|
ensureAssetTracked(coin) {
|
|
96
115
|
if (this.trackedAssetInfos.has(coin)) return;
|
|
@@ -100,14 +119,18 @@ class BinanceAccountTracker extends BaseAccountTracker {
|
|
|
100
119
|
this.trackedAssetInfos.set(coin, info);
|
|
101
120
|
const trackedAssets = /* @__PURE__ */ new Map();
|
|
102
121
|
trackedAssets.set(coin, info);
|
|
103
|
-
this.onStateUpdate({
|
|
122
|
+
this.onStateUpdate({
|
|
123
|
+
trackedAssets
|
|
124
|
+
});
|
|
104
125
|
}).catch((err) => {
|
|
105
126
|
this.onError(err instanceof Error ? err : new Error(String(err)));
|
|
106
127
|
});
|
|
107
128
|
}
|
|
108
129
|
releaseAsset(coin) {
|
|
109
130
|
this.trackedAssetInfos.delete(coin);
|
|
110
|
-
this.onStateUpdate({
|
|
131
|
+
this.onStateUpdate({
|
|
132
|
+
trackedAssets: new Map(this.trackedAssetInfos)
|
|
133
|
+
});
|
|
111
134
|
}
|
|
112
135
|
pollAccountStatus() {
|
|
113
136
|
if (!this.wsApiWs?.connected) return;
|
|
@@ -134,8 +157,13 @@ class BinanceAccountTracker extends BaseAccountTracker {
|
|
|
134
157
|
}
|
|
135
158
|
}
|
|
136
159
|
handleAccountStatus(result) {
|
|
137
|
-
const balance = {
|
|
138
|
-
|
|
160
|
+
const balance = {
|
|
161
|
+
...mapBalance(result),
|
|
162
|
+
accountType: this.accountType
|
|
163
|
+
};
|
|
164
|
+
this.onStateUpdate({
|
|
165
|
+
balance
|
|
166
|
+
});
|
|
139
167
|
}
|
|
140
168
|
handlePositionRisk(risk, merge) {
|
|
141
169
|
let positions = mapPositions(risk);
|
|
@@ -143,7 +171,9 @@ class BinanceAccountTracker extends BaseAccountTracker {
|
|
|
143
171
|
positions = mergePositions(positions, this.currentPositions);
|
|
144
172
|
}
|
|
145
173
|
this.currentPositions = positions;
|
|
146
|
-
this.onStateUpdate({
|
|
174
|
+
this.onStateUpdate({
|
|
175
|
+
positions
|
|
176
|
+
});
|
|
147
177
|
}
|
|
148
178
|
handleUserDataEvent(event) {
|
|
149
179
|
if (event.e === "ACCOUNT_CONFIG_UPDATE" && event.ac) {
|
|
@@ -152,11 +182,16 @@ class BinanceAccountTracker extends BaseAccountTracker {
|
|
|
152
182
|
if (symbol && leverage !== "0") {
|
|
153
183
|
const existing = this.trackedAssetInfos.get(symbol);
|
|
154
184
|
if (existing) {
|
|
155
|
-
const updated = {
|
|
185
|
+
const updated = {
|
|
186
|
+
...existing,
|
|
187
|
+
leverage
|
|
188
|
+
};
|
|
156
189
|
this.trackedAssetInfos.set(symbol, updated);
|
|
157
190
|
const trackedAssets = /* @__PURE__ */ new Map();
|
|
158
191
|
trackedAssets.set(symbol, updated);
|
|
159
|
-
this.onStateUpdate({
|
|
192
|
+
this.onStateUpdate({
|
|
193
|
+
trackedAssets
|
|
194
|
+
});
|
|
160
195
|
}
|
|
161
196
|
}
|
|
162
197
|
this.refreshAllPositions();
|
|
@@ -170,9 +205,7 @@ class BinanceAccountTracker extends BaseAccountTracker {
|
|
|
170
205
|
for (const pos of this.currentPositions.values()) symbols.add(pos.symbol);
|
|
171
206
|
for (const coin of this.trackedCoins) symbols.add(coin);
|
|
172
207
|
if (symbols.size === 0) return;
|
|
173
|
-
const promises = Array.from(symbols).map(
|
|
174
|
-
(symbol) => fetchPositionRisk(this.creds, symbol, this.demo).catch(() => void 0)
|
|
175
|
-
);
|
|
208
|
+
const promises = Array.from(symbols).map((symbol) => fetchPositionRisk(this.creds, symbol, this.demo).catch(() => void 0));
|
|
176
209
|
Promise.all(promises).then((results) => {
|
|
177
210
|
const freshPositions = /* @__PURE__ */ new Map();
|
|
178
211
|
for (const risk of results) {
|
|
@@ -198,14 +231,21 @@ class BinanceAccountTracker extends BaseAccountTracker {
|
|
|
198
231
|
}
|
|
199
232
|
}
|
|
200
233
|
this.currentPositions = freshPositions;
|
|
201
|
-
this.onStateUpdate({
|
|
234
|
+
this.onStateUpdate({
|
|
235
|
+
positions: freshPositions
|
|
236
|
+
});
|
|
202
237
|
}).catch((err) => {
|
|
203
238
|
this.onError(err instanceof Error ? err : new Error(String(err)));
|
|
204
239
|
});
|
|
205
240
|
}
|
|
206
241
|
}
|
|
207
242
|
function toTrackedAssetInfo(coin, risk) {
|
|
208
|
-
return {
|
|
243
|
+
return {
|
|
244
|
+
coin,
|
|
245
|
+
leverage: risk.leverage,
|
|
246
|
+
marginType: risk.marginType
|
|
247
|
+
};
|
|
209
248
|
}
|
|
249
|
+
__name(toTrackedAssetInfo, "toTrackedAssetInfo");
|
|
210
250
|
|
|
211
251
|
export { BinanceAccountTracker };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
var BinanceAccountType = /* @__PURE__ */ ((BinanceAccountType2)
|
|
1
|
+
var BinanceAccountType = /* @__PURE__ */ (function(BinanceAccountType2) {
|
|
2
2
|
BinanceAccountType2["MULTI_ASSET"] = "MULTI_ASSET";
|
|
3
3
|
BinanceAccountType2["SINGLE_ASSET"] = "SINGLE_ASSET";
|
|
4
4
|
return BinanceAccountType2;
|
|
5
|
-
})(
|
|
5
|
+
})({});
|
|
6
6
|
|
|
7
7
|
export { BinanceAccountType };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import BigNumber from 'bignumber.js';
|
|
2
|
-
import '../types';
|
|
3
2
|
import { positionKey } from '../utils';
|
|
4
3
|
import { BybitAccountType } from './types';
|
|
5
4
|
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
7
|
function buildBalance(raw, coins, accountType) {
|
|
7
8
|
if (!accountType) return null;
|
|
8
9
|
const free = {};
|
|
@@ -57,6 +58,7 @@ function buildBalance(raw, coins, accountType) {
|
|
|
57
58
|
timestamp: Date.now()
|
|
58
59
|
};
|
|
59
60
|
}
|
|
61
|
+
__name(buildBalance, "buildBalance");
|
|
60
62
|
function mergeRawCoins(existing, incoming) {
|
|
61
63
|
const merged = new Map(existing);
|
|
62
64
|
for (const c of incoming) {
|
|
@@ -64,6 +66,7 @@ function mergeRawCoins(existing, incoming) {
|
|
|
64
66
|
}
|
|
65
67
|
return merged;
|
|
66
68
|
}
|
|
69
|
+
__name(mergeRawCoins, "mergeRawCoins");
|
|
67
70
|
function mapSinglePosition(p, size) {
|
|
68
71
|
const side = p.side === "Buy" ? "long" : p.side === "Sell" ? "short" : "both";
|
|
69
72
|
return {
|
|
@@ -77,6 +80,7 @@ function mapSinglePosition(p, size) {
|
|
|
77
80
|
liquidationPrice: p.liqPrice || null
|
|
78
81
|
};
|
|
79
82
|
}
|
|
83
|
+
__name(mapSinglePosition, "mapSinglePosition");
|
|
80
84
|
function mapPositions(raw) {
|
|
81
85
|
const positions = /* @__PURE__ */ new Map();
|
|
82
86
|
for (const p of raw) {
|
|
@@ -87,6 +91,7 @@ function mapPositions(raw) {
|
|
|
87
91
|
}
|
|
88
92
|
return positions;
|
|
89
93
|
}
|
|
94
|
+
__name(mapPositions, "mapPositions");
|
|
90
95
|
function mapPositionUpdates(raw) {
|
|
91
96
|
const positions = /* @__PURE__ */ new Map();
|
|
92
97
|
for (const p of raw) {
|
|
@@ -96,5 +101,6 @@ function mapPositionUpdates(raw) {
|
|
|
96
101
|
}
|
|
97
102
|
return positions;
|
|
98
103
|
}
|
|
104
|
+
__name(mapPositionUpdates, "mapPositionUpdates");
|
|
99
105
|
|
|
100
106
|
export { buildBalance, mapPositionUpdates, mapPositions, mapSinglePosition, mergeRawCoins };
|
|
@@ -2,9 +2,13 @@ import { createExchangeWs } from '../../client';
|
|
|
2
2
|
import { fetchPositions, fetchPositionLeverage, fetchWalletBalance, fetchAccountInfo } from '../../client/bybit/rest';
|
|
3
3
|
import { BaseAccountTracker } from '../base';
|
|
4
4
|
import { mergeRawCoins, buildBalance, mapPositions, mapPositionUpdates } from './mapper';
|
|
5
|
-
import './types';
|
|
6
5
|
|
|
6
|
+
var __defProp = Object.defineProperty;
|
|
7
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
7
8
|
class BybitAccountTracker extends BaseAccountTracker {
|
|
9
|
+
static {
|
|
10
|
+
__name(this, "BybitAccountTracker");
|
|
11
|
+
}
|
|
8
12
|
creds;
|
|
9
13
|
ws = null;
|
|
10
14
|
messageListenerId = null;
|
|
@@ -25,16 +29,19 @@ class BybitAccountTracker extends BaseAccountTracker {
|
|
|
25
29
|
const rawCoins = mergeRawCoins(/* @__PURE__ */ new Map(), wallet.coin ?? []);
|
|
26
30
|
balance = buildBalance(wallet, rawCoins, accountType);
|
|
27
31
|
}
|
|
28
|
-
return {
|
|
32
|
+
return {
|
|
33
|
+
balance,
|
|
34
|
+
positions: Array.from(mapPositions(positions).values())
|
|
35
|
+
};
|
|
29
36
|
}
|
|
30
37
|
/**
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
* Stateless one-shot per-asset settings read. Bybit has no batch leverage endpoint, but
|
|
39
|
+
* `position/list` by settleCoin returns every open position (with leverage) in one call, so
|
|
40
|
+
* only requested symbols without an open position need a per-symbol fill-in read (`?symbol=`
|
|
41
|
+
* returns the leverage setting even at size 0). For ≤2 symbols the per-symbol reads alone are
|
|
42
|
+
* cheaper than the two settleCoin reads, so the batch step is skipped. A failed fill-in maps
|
|
43
|
+
* to `null`; the read only throws when no underlying read succeeded.
|
|
44
|
+
*/
|
|
38
45
|
async fetchAssetSnapshots(coins) {
|
|
39
46
|
const bySymbol = /* @__PURE__ */ new Map();
|
|
40
47
|
const useBatch = coins.length > 2;
|
|
@@ -43,14 +50,15 @@ class BybitAccountTracker extends BaseAccountTracker {
|
|
|
43
50
|
fetchPositions(this.creds, "USDT", this.demo),
|
|
44
51
|
fetchPositions(this.creds, "USDC", this.demo)
|
|
45
52
|
]);
|
|
46
|
-
for (const pos of [
|
|
53
|
+
for (const pos of [
|
|
54
|
+
positionsUsd,
|
|
55
|
+
positionsUsdc
|
|
56
|
+
].flat()) {
|
|
47
57
|
if (pos.symbol) bySymbol.set(pos.symbol, pos);
|
|
48
58
|
}
|
|
49
59
|
}
|
|
50
60
|
const missing = coins.filter((coin) => !bySymbol.has(coin));
|
|
51
|
-
const fillIns = await Promise.allSettled(
|
|
52
|
-
missing.map((symbol) => fetchPositionLeverage(this.creds, symbol, this.demo))
|
|
53
|
-
);
|
|
61
|
+
const fillIns = await Promise.allSettled(missing.map((symbol) => fetchPositionLeverage(this.creds, symbol, this.demo)));
|
|
54
62
|
missing.forEach((symbol, i) => {
|
|
55
63
|
const res = fillIns[i];
|
|
56
64
|
if (res?.status === "fulfilled" && res.value) bySymbol.set(symbol, res.value);
|
|
@@ -68,7 +76,10 @@ class BybitAccountTracker extends BaseAccountTracker {
|
|
|
68
76
|
async start() {
|
|
69
77
|
const { wallet, positions, accountInfo } = await this.fetchSnapshotData();
|
|
70
78
|
this.handleInitialData(wallet ?? null, positions, accountInfo?.marginMode ?? null);
|
|
71
|
-
this.ws = await createExchangeWs("bybit", {
|
|
79
|
+
this.ws = await createExchangeWs("bybit", {
|
|
80
|
+
demo: this.demo,
|
|
81
|
+
credentials: this.credentials
|
|
82
|
+
});
|
|
72
83
|
this.messageListenerId = this.ws.main.addMessageListener((raw) => this.routeRaw(raw));
|
|
73
84
|
this.openListenerId = this.ws.main.addOpenListener(() => {
|
|
74
85
|
this.ws?.authenticate().then(() => this.subscribe()).catch((err) => this.onError(err));
|
|
@@ -97,7 +108,14 @@ class BybitAccountTracker extends BaseAccountTracker {
|
|
|
97
108
|
fetchPositions(this.creds, "USDC", this.demo),
|
|
98
109
|
fetchAccountInfo(this.creds, this.demo)
|
|
99
110
|
]);
|
|
100
|
-
return {
|
|
111
|
+
return {
|
|
112
|
+
wallet,
|
|
113
|
+
positions: [
|
|
114
|
+
positionsUsd,
|
|
115
|
+
positionsUsdc
|
|
116
|
+
].flat(),
|
|
117
|
+
accountInfo
|
|
118
|
+
};
|
|
101
119
|
}
|
|
102
120
|
ensureAssetTracked(coin) {
|
|
103
121
|
if (this.trackedAssetInfos.has(coin)) return;
|
|
@@ -106,17 +124,27 @@ class BybitAccountTracker extends BaseAccountTracker {
|
|
|
106
124
|
this.trackedAssetInfos.set(coin, info);
|
|
107
125
|
const trackedAssets = /* @__PURE__ */ new Map();
|
|
108
126
|
trackedAssets.set(coin, info);
|
|
109
|
-
this.onStateUpdate({
|
|
127
|
+
this.onStateUpdate({
|
|
128
|
+
trackedAssets
|
|
129
|
+
});
|
|
110
130
|
}).catch((err) => {
|
|
111
131
|
this.onError(err instanceof Error ? err : new Error(String(err)));
|
|
112
132
|
});
|
|
113
133
|
}
|
|
114
134
|
releaseAsset(coin) {
|
|
115
135
|
this.trackedAssetInfos.delete(coin);
|
|
116
|
-
this.onStateUpdate({
|
|
136
|
+
this.onStateUpdate({
|
|
137
|
+
trackedAssets: new Map(this.trackedAssetInfos)
|
|
138
|
+
});
|
|
117
139
|
}
|
|
118
140
|
subscribe() {
|
|
119
|
-
this.ws?.main.send({
|
|
141
|
+
this.ws?.main.send({
|
|
142
|
+
op: "subscribe",
|
|
143
|
+
args: [
|
|
144
|
+
"wallet",
|
|
145
|
+
"position"
|
|
146
|
+
]
|
|
147
|
+
});
|
|
120
148
|
}
|
|
121
149
|
handleInitialData(wallet, positions, accountType) {
|
|
122
150
|
this.accountType = accountType;
|
|
@@ -124,15 +152,22 @@ class BybitAccountTracker extends BaseAccountTracker {
|
|
|
124
152
|
this.lastWallet = wallet;
|
|
125
153
|
this.rawCoins = mergeRawCoins(/* @__PURE__ */ new Map(), wallet.coin ?? []);
|
|
126
154
|
const balance = buildBalance(wallet, this.rawCoins, this.accountType);
|
|
127
|
-
if (balance) this.onStateUpdate({
|
|
155
|
+
if (balance) this.onStateUpdate({
|
|
156
|
+
balance
|
|
157
|
+
});
|
|
128
158
|
}
|
|
129
|
-
this.onStateUpdate({
|
|
159
|
+
this.onStateUpdate({
|
|
160
|
+
positions: mapPositions(positions)
|
|
161
|
+
});
|
|
130
162
|
}
|
|
131
163
|
routeRaw(raw) {
|
|
132
164
|
try {
|
|
133
165
|
const msg = JSON.parse(raw);
|
|
134
166
|
if (msg.topic && msg.data) {
|
|
135
|
-
this.handleMessage({
|
|
167
|
+
this.handleMessage({
|
|
168
|
+
topic: msg.topic,
|
|
169
|
+
data: msg.data
|
|
170
|
+
});
|
|
136
171
|
}
|
|
137
172
|
} catch (err) {
|
|
138
173
|
this.onError(err instanceof Error ? err : new Error(String(err)));
|
|
@@ -152,14 +187,20 @@ class BybitAccountTracker extends BaseAccountTracker {
|
|
|
152
187
|
if (existing) {
|
|
153
188
|
const leverage = pos.leverage || existing.leverage;
|
|
154
189
|
const marginType = pos.tradeMode === "1" ? "isolated" : "cross";
|
|
155
|
-
const updated = {
|
|
190
|
+
const updated = {
|
|
191
|
+
...existing,
|
|
192
|
+
leverage,
|
|
193
|
+
marginType
|
|
194
|
+
};
|
|
156
195
|
this.trackedAssetInfos.set(pos.symbol, updated);
|
|
157
196
|
trackedAssets.set(pos.symbol, updated);
|
|
158
197
|
}
|
|
159
198
|
}
|
|
160
199
|
this.onStateUpdate({
|
|
161
200
|
positions,
|
|
162
|
-
...trackedAssets.size > 0 ? {
|
|
201
|
+
...trackedAssets.size > 0 ? {
|
|
202
|
+
trackedAssets
|
|
203
|
+
} : {}
|
|
163
204
|
});
|
|
164
205
|
}
|
|
165
206
|
}
|
|
@@ -179,7 +220,9 @@ class BybitAccountTracker extends BaseAccountTracker {
|
|
|
179
220
|
} : raw;
|
|
180
221
|
this.lastWallet = merged;
|
|
181
222
|
const balance = buildBalance(merged, this.rawCoins, this.accountType);
|
|
182
|
-
if (balance) this.onStateUpdate({
|
|
223
|
+
if (balance) this.onStateUpdate({
|
|
224
|
+
balance
|
|
225
|
+
});
|
|
183
226
|
}
|
|
184
227
|
}
|
|
185
228
|
function toTrackedAssetInfo(coin, pos) {
|
|
@@ -189,5 +232,6 @@ function toTrackedAssetInfo(coin, pos) {
|
|
|
189
232
|
marginType: pos?.tradeMode === "1" ? "isolated" : "cross"
|
|
190
233
|
};
|
|
191
234
|
}
|
|
235
|
+
__name(toTrackedAssetInfo, "toTrackedAssetInfo");
|
|
192
236
|
|
|
193
237
|
export { BybitAccountTracker };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var BybitAccountType = /* @__PURE__ */ ((BybitAccountType2)
|
|
1
|
+
var BybitAccountType = /* @__PURE__ */ (function(BybitAccountType2) {
|
|
2
2
|
BybitAccountType2["ISOLATED_MARGIN"] = "ISOLATED_MARGIN";
|
|
3
3
|
BybitAccountType2["REGULAR_MARGIN"] = "REGULAR_MARGIN";
|
|
4
4
|
BybitAccountType2["PORTFOLIO_MARGIN"] = "PORTFOLIO_MARGIN";
|
|
5
5
|
return BybitAccountType2;
|
|
6
|
-
})(
|
|
6
|
+
})({});
|
|
7
7
|
|
|
8
8
|
export { BybitAccountType };
|