@pear-protocol/symmio-client 0.3.14 → 0.3.16
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/index.d.mts +49 -1
- package/dist/index.d.ts +49 -1
- package/dist/index.js +191 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +187 -1
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +127 -36
- package/dist/react/index.d.ts +127 -36
- package/dist/react/index.js +486 -73
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +481 -75
- package/dist/react/index.mjs.map +1 -1
- package/dist/react/provider.js +70 -25
- package/dist/react/provider.js.map +1 -1
- package/dist/react/provider.mjs +70 -25
- package/dist/react/provider.mjs.map +1 -1
- package/package.json +2 -2
package/dist/react/index.js
CHANGED
|
@@ -75,6 +75,7 @@ var RECONNECT_DELAYS = [1e3, 2e3, 4e3, 8e3, 16e3, 3e4];
|
|
|
75
75
|
var IDLE_CLOSE_DELAY_MS = 3e4;
|
|
76
76
|
var STALE_CONNECTION_MS = 3e4;
|
|
77
77
|
var STALE_CHECK_INTERVAL_MS = 1e4;
|
|
78
|
+
var RECONNECT_RESET_MS = 6e4;
|
|
78
79
|
var STABLE_QUOTES = ["USDT0", "USDT", "USDC", "USDE", "USDH", "USD"];
|
|
79
80
|
function normalizeBaseSymbol(symbol) {
|
|
80
81
|
const normalized = symbol.toUpperCase().trim();
|
|
@@ -126,6 +127,7 @@ var BinanceWsManager = class {
|
|
|
126
127
|
reconnectTimer = null;
|
|
127
128
|
idleCloseTimer = null;
|
|
128
129
|
staleCheckTimer = null;
|
|
130
|
+
reconnectResetTimer = null;
|
|
129
131
|
intentionalClose = false;
|
|
130
132
|
pendingSubscribes = /* @__PURE__ */ new Set();
|
|
131
133
|
lastMessageAt = 0;
|
|
@@ -164,6 +166,7 @@ var BinanceWsManager = class {
|
|
|
164
166
|
const wrappedCb = (raw) => {
|
|
165
167
|
cb({
|
|
166
168
|
symbol: normalizeBaseSymbol(raw.s),
|
|
169
|
+
binanceSymbol: raw.s,
|
|
167
170
|
markPrice: parseFloat(raw.p),
|
|
168
171
|
indexPrice: parseFloat(raw.i),
|
|
169
172
|
time: raw.E,
|
|
@@ -185,6 +188,7 @@ var BinanceWsManager = class {
|
|
|
185
188
|
cb(
|
|
186
189
|
extractTickers(raw).map((entry) => ({
|
|
187
190
|
symbol: normalizeBaseSymbol(entry.s),
|
|
191
|
+
binanceSymbol: entry.s,
|
|
188
192
|
markPrice: parseFloat(entry.p),
|
|
189
193
|
indexPrice: parseFloat(entry.i),
|
|
190
194
|
time: entry.E,
|
|
@@ -204,6 +208,7 @@ var BinanceWsManager = class {
|
|
|
204
208
|
this.clearReconnectTimer();
|
|
205
209
|
this.clearIdleCloseTimer();
|
|
206
210
|
this.clearStaleCheckTimer();
|
|
211
|
+
this.clearReconnectResetTimer();
|
|
207
212
|
this.pendingSubscribes.clear();
|
|
208
213
|
if (this.ws) {
|
|
209
214
|
this.ws.close();
|
|
@@ -240,20 +245,26 @@ var BinanceWsManager = class {
|
|
|
240
245
|
}
|
|
241
246
|
}
|
|
242
247
|
ensureConnected() {
|
|
243
|
-
if (this.ws
|
|
244
|
-
|
|
248
|
+
if (this.ws) {
|
|
249
|
+
const state = this.ws.readyState;
|
|
250
|
+
if (state === WebSocket.OPEN || state === WebSocket.CONNECTING || state === WebSocket.CLOSING) {
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
245
253
|
}
|
|
246
254
|
this.clearReconnectTimer();
|
|
247
255
|
this.connect();
|
|
248
256
|
}
|
|
249
257
|
connect() {
|
|
250
258
|
if (typeof WebSocket === "undefined") return;
|
|
259
|
+
if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
251
262
|
this.intentionalClose = false;
|
|
252
263
|
this.ws = new WebSocket(BINANCE_WS_URL);
|
|
253
264
|
this.ws.onopen = () => {
|
|
254
|
-
this.reconnectAttempt = 0;
|
|
255
265
|
this.lastMessageAt = Date.now();
|
|
256
266
|
this.startStaleCheck();
|
|
267
|
+
this.scheduleReconnectReset();
|
|
257
268
|
const activeStreams = Array.from(
|
|
258
269
|
/* @__PURE__ */ new Set([...this.streams.keys(), ...this.pendingSubscribes])
|
|
259
270
|
);
|
|
@@ -266,14 +277,24 @@ var BinanceWsManager = class {
|
|
|
266
277
|
try {
|
|
267
278
|
const data = JSON.parse(event.data);
|
|
268
279
|
this.lastMessageAt = Date.now();
|
|
280
|
+
this.resetReconnectAttempt();
|
|
269
281
|
this.handleMessage(data);
|
|
270
282
|
} catch {
|
|
271
283
|
}
|
|
272
284
|
};
|
|
273
285
|
this.ws.onclose = () => {
|
|
286
|
+
const wasIntentional = this.intentionalClose;
|
|
287
|
+
this.intentionalClose = false;
|
|
274
288
|
this.ws = null;
|
|
275
289
|
this.clearStaleCheckTimer();
|
|
276
|
-
|
|
290
|
+
this.clearReconnectResetTimer();
|
|
291
|
+
if (this.streams.size === 0) {
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
if (wasIntentional) {
|
|
295
|
+
this.connect();
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
277
298
|
this.scheduleReconnect();
|
|
278
299
|
};
|
|
279
300
|
this.ws.onerror = () => {
|
|
@@ -349,9 +370,6 @@ var BinanceWsManager = class {
|
|
|
349
370
|
if (this.streams.size > 0 || !this.ws) return;
|
|
350
371
|
this.intentionalClose = true;
|
|
351
372
|
this.ws.close();
|
|
352
|
-
this.ws = null;
|
|
353
|
-
this.intentionalClose = false;
|
|
354
|
-
this.clearStaleCheckTimer();
|
|
355
373
|
}, IDLE_CLOSE_DELAY_MS);
|
|
356
374
|
}
|
|
357
375
|
startStaleCheck() {
|
|
@@ -363,6 +381,17 @@ var BinanceWsManager = class {
|
|
|
363
381
|
this.ws.close();
|
|
364
382
|
}, STALE_CHECK_INTERVAL_MS);
|
|
365
383
|
}
|
|
384
|
+
scheduleReconnectReset() {
|
|
385
|
+
this.clearReconnectResetTimer();
|
|
386
|
+
this.reconnectResetTimer = setTimeout(() => {
|
|
387
|
+
this.reconnectResetTimer = null;
|
|
388
|
+
this.resetReconnectAttempt();
|
|
389
|
+
}, RECONNECT_RESET_MS);
|
|
390
|
+
}
|
|
391
|
+
resetReconnectAttempt() {
|
|
392
|
+
this.reconnectAttempt = 0;
|
|
393
|
+
this.clearReconnectResetTimer();
|
|
394
|
+
}
|
|
366
395
|
clearReconnectTimer() {
|
|
367
396
|
if (!this.reconnectTimer) return;
|
|
368
397
|
clearTimeout(this.reconnectTimer);
|
|
@@ -378,13 +407,21 @@ var BinanceWsManager = class {
|
|
|
378
407
|
clearInterval(this.staleCheckTimer);
|
|
379
408
|
this.staleCheckTimer = null;
|
|
380
409
|
}
|
|
410
|
+
clearReconnectResetTimer() {
|
|
411
|
+
if (!this.reconnectResetTimer) return;
|
|
412
|
+
clearTimeout(this.reconnectResetTimer);
|
|
413
|
+
this.reconnectResetTimer = null;
|
|
414
|
+
}
|
|
381
415
|
};
|
|
382
|
-
var
|
|
416
|
+
var BINANCE_WS_SINGLETON_KEY = "__pearBinanceWsManager__";
|
|
383
417
|
function getBinanceWsManager() {
|
|
384
|
-
|
|
385
|
-
|
|
418
|
+
const g = globalThis;
|
|
419
|
+
let manager = g[BINANCE_WS_SINGLETON_KEY];
|
|
420
|
+
if (!manager) {
|
|
421
|
+
manager = new BinanceWsManager();
|
|
422
|
+
g[BINANCE_WS_SINGLETON_KEY] = manager;
|
|
386
423
|
}
|
|
387
|
-
return
|
|
424
|
+
return manager;
|
|
388
425
|
}
|
|
389
426
|
|
|
390
427
|
// src/react/stores/use-binance-mark-price-store.ts
|
|
@@ -392,15 +429,8 @@ var refCounts = /* @__PURE__ */ new Map();
|
|
|
392
429
|
var streamSymbols = /* @__PURE__ */ new Map();
|
|
393
430
|
var allMarkPricesRefCount = 0;
|
|
394
431
|
var allMarkPricesUnsubscribe = null;
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
const normalized = symbol.toUpperCase().trim();
|
|
398
|
-
for (const quote of STABLE_QUOTES2) {
|
|
399
|
-
if (normalized.endsWith(quote) && normalized.length > quote.length) {
|
|
400
|
-
return normalized.slice(0, -quote.length);
|
|
401
|
-
}
|
|
402
|
-
}
|
|
403
|
-
return normalized;
|
|
432
|
+
function normalizeBinanceSymbolKey(symbol) {
|
|
433
|
+
return symbol.toUpperCase().trim();
|
|
404
434
|
}
|
|
405
435
|
function getNextRefCount(binanceSymbol) {
|
|
406
436
|
return (refCounts.get(binanceSymbol) ?? 0) + 1;
|
|
@@ -435,7 +465,7 @@ var useBinanceMarkPriceStore = zustand.create((set) => ({
|
|
|
435
465
|
fundingRates: {},
|
|
436
466
|
nextFundingTimes: {},
|
|
437
467
|
subscribeSymbol: (symmSymbol, rawBinanceSymbol) => {
|
|
438
|
-
const binanceSymbol =
|
|
468
|
+
const binanceSymbol = normalizeBinanceSymbolKey(rawBinanceSymbol);
|
|
439
469
|
const nextRefCount = getNextRefCount(binanceSymbol);
|
|
440
470
|
refCounts.set(binanceSymbol, nextRefCount);
|
|
441
471
|
addMappedSymbol(binanceSymbol, symmSymbol);
|
|
@@ -447,8 +477,10 @@ var useBinanceMarkPriceStore = zustand.create((set) => ({
|
|
|
447
477
|
let nextFundingRates = null;
|
|
448
478
|
let nextFundingTimes = null;
|
|
449
479
|
entries.forEach((entry) => {
|
|
450
|
-
const
|
|
451
|
-
|
|
480
|
+
const binanceSymbolKey = normalizeBinanceSymbolKey(
|
|
481
|
+
entry.binanceSymbol ?? entry.symbol
|
|
482
|
+
);
|
|
483
|
+
const mappedSymbols = streamSymbols.get(binanceSymbolKey);
|
|
452
484
|
if (!mappedSymbols || mappedSymbols.size === 0) return;
|
|
453
485
|
nextMarkPrices ??= { ...state.markPrices };
|
|
454
486
|
nextFundingRates ??= { ...state.fundingRates };
|
|
@@ -473,7 +505,7 @@ var useBinanceMarkPriceStore = zustand.create((set) => ({
|
|
|
473
505
|
allMarkPricesRefCount += 1;
|
|
474
506
|
},
|
|
475
507
|
unsubscribeSymbol: (symmSymbol, rawBinanceSymbol) => {
|
|
476
|
-
const binanceSymbol =
|
|
508
|
+
const binanceSymbol = normalizeBinanceSymbolKey(rawBinanceSymbol);
|
|
477
509
|
const removedSubscription = removeMappedSymbol(binanceSymbol, symmSymbol);
|
|
478
510
|
if (!removedSubscription) {
|
|
479
511
|
return;
|
|
@@ -513,6 +545,7 @@ var useBinanceMarkPriceStore = zustand.create((set) => ({
|
|
|
513
545
|
}));
|
|
514
546
|
|
|
515
547
|
// src/react/hooks/use-binance-ws.ts
|
|
548
|
+
var BOOTSTRAP_RETRY_DELAYS_MS = [1e3, 2e3, 5e3];
|
|
516
549
|
function useBinanceWs(params) {
|
|
517
550
|
const { symmCoreClient, chainId } = params;
|
|
518
551
|
const subscribeSymbol = useBinanceMarkPriceStore((state) => state.subscribeSymbol);
|
|
@@ -523,7 +556,8 @@ function useBinanceWs(params) {
|
|
|
523
556
|
}
|
|
524
557
|
let cancelled = false;
|
|
525
558
|
let subscribedPairs = [];
|
|
526
|
-
|
|
559
|
+
let retryTimer = null;
|
|
560
|
+
const run = async (attempt = 0) => {
|
|
527
561
|
try {
|
|
528
562
|
const result = await symmCoreClient.markets.listSymmHedger({ chainId });
|
|
529
563
|
if (cancelled) {
|
|
@@ -543,11 +577,22 @@ function useBinanceWs(params) {
|
|
|
543
577
|
subscribeSymbol(symbol, binanceSymbol);
|
|
544
578
|
});
|
|
545
579
|
} catch {
|
|
580
|
+
const delay = BOOTSTRAP_RETRY_DELAYS_MS[attempt];
|
|
581
|
+
if (cancelled || delay == null) {
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
retryTimer = setTimeout(() => {
|
|
585
|
+
retryTimer = null;
|
|
586
|
+
void run(attempt + 1);
|
|
587
|
+
}, delay);
|
|
546
588
|
}
|
|
547
589
|
};
|
|
548
590
|
void run();
|
|
549
591
|
return () => {
|
|
550
592
|
cancelled = true;
|
|
593
|
+
if (retryTimer) {
|
|
594
|
+
clearTimeout(retryTimer);
|
|
595
|
+
}
|
|
551
596
|
subscribedPairs.forEach(([symbol, binanceSymbol]) => {
|
|
552
597
|
unsubscribeSymbol(symbol, binanceSymbol);
|
|
553
598
|
});
|
|
@@ -25635,21 +25680,196 @@ function useSymmAccountData(params) {
|
|
|
25635
25680
|
enabled: internalEnabled && (params.query?.enabled ?? true)
|
|
25636
25681
|
});
|
|
25637
25682
|
}
|
|
25638
|
-
|
|
25683
|
+
|
|
25684
|
+
// src/utils/account-pnl.ts
|
|
25685
|
+
function toNumber(value) {
|
|
25686
|
+
if (value === null || value === void 0 || value === "") {
|
|
25687
|
+
return 0;
|
|
25688
|
+
}
|
|
25689
|
+
const parsed = Number(value);
|
|
25690
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
25691
|
+
}
|
|
25692
|
+
function readOpenedPrice(leg) {
|
|
25693
|
+
return toNumber(leg.openedPrice ?? leg.opened_price);
|
|
25694
|
+
}
|
|
25695
|
+
function readCurrentPrice(leg) {
|
|
25696
|
+
const parsed = Number(leg.currentPrice ?? leg.current_price);
|
|
25697
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
25698
|
+
}
|
|
25699
|
+
function readMarkPrice(leg, markPrices) {
|
|
25700
|
+
const symbol = leg.symbol?.trim().toUpperCase();
|
|
25701
|
+
if (symbol) {
|
|
25702
|
+
const markPrice = Number(markPrices[symbol]);
|
|
25703
|
+
if (Number.isFinite(markPrice)) {
|
|
25704
|
+
return markPrice;
|
|
25705
|
+
}
|
|
25706
|
+
}
|
|
25707
|
+
return readCurrentPrice(leg);
|
|
25708
|
+
}
|
|
25709
|
+
function getSymbol(leg) {
|
|
25710
|
+
return leg.symbol?.trim().toUpperCase() || void 0;
|
|
25711
|
+
}
|
|
25712
|
+
function computeLegUpnl(leg, side, markPrices) {
|
|
25713
|
+
const markPrice = readMarkPrice(leg, markPrices);
|
|
25714
|
+
if (markPrice === void 0) {
|
|
25715
|
+
return { upnl: 0, missingSymbol: getSymbol(leg) };
|
|
25716
|
+
}
|
|
25717
|
+
const quantity = toNumber(leg.quantity);
|
|
25718
|
+
const openedPrice = readOpenedPrice(leg);
|
|
25719
|
+
const direction = side === "short" ? -1 : 1;
|
|
25720
|
+
return {
|
|
25721
|
+
upnl: quantity * (markPrice - openedPrice) * direction
|
|
25722
|
+
};
|
|
25723
|
+
}
|
|
25724
|
+
function computeSymmPositionUpnl(position, markPrices = {}) {
|
|
25725
|
+
const missingSymbols = /* @__PURE__ */ new Set();
|
|
25726
|
+
let upnl = 0;
|
|
25727
|
+
let legsCount = 0;
|
|
25728
|
+
for (const leg of position.longAssets ?? []) {
|
|
25729
|
+
legsCount += 1;
|
|
25730
|
+
const result = computeLegUpnl(leg, "long", markPrices);
|
|
25731
|
+
upnl += result.upnl;
|
|
25732
|
+
if (result.missingSymbol) missingSymbols.add(result.missingSymbol);
|
|
25733
|
+
}
|
|
25734
|
+
for (const leg of position.shortAssets ?? []) {
|
|
25735
|
+
legsCount += 1;
|
|
25736
|
+
const result = computeLegUpnl(leg, "short", markPrices);
|
|
25737
|
+
upnl += result.upnl;
|
|
25738
|
+
if (result.missingSymbol) missingSymbols.add(result.missingSymbol);
|
|
25739
|
+
}
|
|
25740
|
+
if (legsCount === 0) {
|
|
25741
|
+
return {
|
|
25742
|
+
upnl: toNumber(position.unrealizedPnl ?? position.unrealized_pnl),
|
|
25743
|
+
missingSymbols: [],
|
|
25744
|
+
positionsCount: 1,
|
|
25745
|
+
legsCount,
|
|
25746
|
+
usedFallbackPositions: 1
|
|
25747
|
+
};
|
|
25748
|
+
}
|
|
25749
|
+
return {
|
|
25750
|
+
upnl,
|
|
25751
|
+
missingSymbols: Array.from(missingSymbols),
|
|
25752
|
+
positionsCount: 1,
|
|
25753
|
+
legsCount,
|
|
25754
|
+
usedFallbackPositions: 0
|
|
25755
|
+
};
|
|
25756
|
+
}
|
|
25757
|
+
function computeSymmPositionsUpnl(positions = [], markPrices = {}) {
|
|
25758
|
+
const missingSymbols = /* @__PURE__ */ new Set();
|
|
25759
|
+
let upnl = 0;
|
|
25760
|
+
let legsCount = 0;
|
|
25761
|
+
let usedFallbackPositions = 0;
|
|
25762
|
+
for (const position of positions) {
|
|
25763
|
+
const result = computeSymmPositionUpnl(position, markPrices);
|
|
25764
|
+
upnl += result.upnl;
|
|
25765
|
+
legsCount += result.legsCount;
|
|
25766
|
+
usedFallbackPositions += result.usedFallbackPositions;
|
|
25767
|
+
result.missingSymbols.forEach((symbol) => missingSymbols.add(symbol));
|
|
25768
|
+
}
|
|
25769
|
+
return {
|
|
25770
|
+
upnl,
|
|
25771
|
+
missingSymbols: Array.from(missingSymbols),
|
|
25772
|
+
positionsCount: positions.length,
|
|
25773
|
+
legsCount,
|
|
25774
|
+
usedFallbackPositions
|
|
25775
|
+
};
|
|
25776
|
+
}
|
|
25777
|
+
function readMessageNumber(message, keys) {
|
|
25778
|
+
for (const key of keys) {
|
|
25779
|
+
if (key in message) {
|
|
25780
|
+
return toNumber(message[key]);
|
|
25781
|
+
}
|
|
25782
|
+
}
|
|
25783
|
+
return 0;
|
|
25784
|
+
}
|
|
25785
|
+
function normalizeSymmUpnlWebSocketMessage(raw) {
|
|
25786
|
+
if (typeof raw !== "object" || raw === null) {
|
|
25787
|
+
return void 0;
|
|
25788
|
+
}
|
|
25789
|
+
const message = raw;
|
|
25790
|
+
const timestamp = readMessageNumber(message, ["timestamp"]);
|
|
25791
|
+
return {
|
|
25792
|
+
upnl: readMessageNumber(message, ["upnl"]),
|
|
25793
|
+
timestamp: timestamp || void 0,
|
|
25794
|
+
availableBalance: readMessageNumber(message, [
|
|
25795
|
+
"availableBalance",
|
|
25796
|
+
"available_balance"
|
|
25797
|
+
]),
|
|
25798
|
+
allocatedBalance: readMessageNumber(message, [
|
|
25799
|
+
"allocatedBalance",
|
|
25800
|
+
"allocated_balance"
|
|
25801
|
+
]),
|
|
25802
|
+
cva: readMessageNumber(message, ["cva"]),
|
|
25803
|
+
lf: readMessageNumber(message, ["lf"]),
|
|
25804
|
+
partyAmm: readMessageNumber(message, ["partyAmm", "party_a_mm", "mm"]),
|
|
25805
|
+
pendingPartyAmm: readMessageNumber(message, [
|
|
25806
|
+
"pendingPartyAmm",
|
|
25807
|
+
"pending_party_a_mm",
|
|
25808
|
+
"pending_mm"
|
|
25809
|
+
]),
|
|
25810
|
+
pendingCva: readMessageNumber(message, ["pendingCva", "pending_cva"]),
|
|
25811
|
+
pendingLf: readMessageNumber(message, ["pendingLf", "pending_lf"]),
|
|
25812
|
+
raw
|
|
25813
|
+
};
|
|
25814
|
+
}
|
|
25815
|
+
function useSymmPositions(params) {
|
|
25639
25816
|
const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
|
|
25640
|
-
const {
|
|
25817
|
+
const { accountAddress, address } = params;
|
|
25818
|
+
const resolvedAddress = accountAddress ? void 0 : address;
|
|
25641
25819
|
const chainId = params.chainId ?? ctxChainId;
|
|
25642
|
-
const internalEnabled = !!symmCoreClient && !!
|
|
25820
|
+
const internalEnabled = !!symmCoreClient && !!(accountAddress || resolvedAddress);
|
|
25821
|
+
const enabled = internalEnabled && (params.query?.enabled ?? true);
|
|
25643
25822
|
return reactQuery.useQuery({
|
|
25644
25823
|
...params.query,
|
|
25645
|
-
queryKey: symmKeys.
|
|
25646
|
-
|
|
25647
|
-
|
|
25648
|
-
chainId
|
|
25649
|
-
multiAccountAddress
|
|
25824
|
+
queryKey: symmKeys.positions({
|
|
25825
|
+
accountAddress,
|
|
25826
|
+
address: resolvedAddress,
|
|
25827
|
+
chainId
|
|
25650
25828
|
}),
|
|
25651
|
-
|
|
25829
|
+
queryFn: () => symmCoreClient.positions.getOpen({
|
|
25830
|
+
accountAddress,
|
|
25831
|
+
address: resolvedAddress,
|
|
25832
|
+
chainId
|
|
25833
|
+
}),
|
|
25834
|
+
enabled
|
|
25835
|
+
});
|
|
25836
|
+
}
|
|
25837
|
+
|
|
25838
|
+
// src/react/hooks/use-symm-account-current-pnl.ts
|
|
25839
|
+
function readPositions(response) {
|
|
25840
|
+
if (typeof response !== "object" || response === null) {
|
|
25841
|
+
return [];
|
|
25842
|
+
}
|
|
25843
|
+
const data = response.data;
|
|
25844
|
+
if (typeof data !== "object" || data === null) {
|
|
25845
|
+
return [];
|
|
25846
|
+
}
|
|
25847
|
+
const positions = data.positions;
|
|
25848
|
+
return Array.isArray(positions) ? positions : [];
|
|
25849
|
+
}
|
|
25850
|
+
function useSymmAccountCurrentPnl(params) {
|
|
25851
|
+
const { accountAddress, address, positions, query } = params;
|
|
25852
|
+
const liveMarkPrices = useBinanceMarkPriceStore((state) => state.markPrices);
|
|
25853
|
+
const positionsQuery = useSymmPositions({
|
|
25854
|
+
accountAddress,
|
|
25855
|
+
address,
|
|
25856
|
+
chainId: params.chainId,
|
|
25857
|
+
query: {
|
|
25858
|
+
...query,
|
|
25859
|
+
enabled: positions === void 0 && (query?.enabled ?? true)
|
|
25860
|
+
}
|
|
25652
25861
|
});
|
|
25862
|
+
const resolvedPositions = positions ?? readPositions(positionsQuery.data);
|
|
25863
|
+
const pnl = react.useMemo(
|
|
25864
|
+
() => computeSymmPositionsUpnl(resolvedPositions, liveMarkPrices),
|
|
25865
|
+
[liveMarkPrices, resolvedPositions]
|
|
25866
|
+
);
|
|
25867
|
+
return {
|
|
25868
|
+
...pnl,
|
|
25869
|
+
value: pnl.upnl,
|
|
25870
|
+
positions: resolvedPositions,
|
|
25871
|
+
positionsQuery
|
|
25872
|
+
};
|
|
25653
25873
|
}
|
|
25654
25874
|
|
|
25655
25875
|
// src/utils/account-overview.ts
|
|
@@ -25679,7 +25899,7 @@ function readValue(source, keys) {
|
|
|
25679
25899
|
}
|
|
25680
25900
|
return void 0;
|
|
25681
25901
|
}
|
|
25682
|
-
function
|
|
25902
|
+
function toNumber2(value) {
|
|
25683
25903
|
if (value === null || value === void 0 || value === "") {
|
|
25684
25904
|
return 0;
|
|
25685
25905
|
}
|
|
@@ -25696,7 +25916,7 @@ function toDisplayString(value) {
|
|
|
25696
25916
|
return String(value);
|
|
25697
25917
|
}
|
|
25698
25918
|
function readNumber(source, keys) {
|
|
25699
|
-
return
|
|
25919
|
+
return toNumber2(readValue(source, keys));
|
|
25700
25920
|
}
|
|
25701
25921
|
function readTimestamp(source) {
|
|
25702
25922
|
const timestamp = readValue(source, ["timestamp"]);
|
|
@@ -25706,6 +25926,28 @@ function readTimestamp(source) {
|
|
|
25706
25926
|
const parsed = Number(timestamp);
|
|
25707
25927
|
return Number.isFinite(parsed) ? parsed : void 0;
|
|
25708
25928
|
}
|
|
25929
|
+
function hasAccountDataShape(value) {
|
|
25930
|
+
return isRecord(value) && ("equity" in value || "maintenanceMargin" in value || "availableForOrder" in value || "totalLocked" in value);
|
|
25931
|
+
}
|
|
25932
|
+
function getSymmAccountData(response) {
|
|
25933
|
+
if (!isRecord(response)) {
|
|
25934
|
+
return void 0;
|
|
25935
|
+
}
|
|
25936
|
+
const data = response.data;
|
|
25937
|
+
if (isRecord(data)) {
|
|
25938
|
+
if (hasAccountDataShape(data.accountData)) {
|
|
25939
|
+
return data.accountData;
|
|
25940
|
+
}
|
|
25941
|
+
if (hasAccountDataShape(data)) {
|
|
25942
|
+
return data;
|
|
25943
|
+
}
|
|
25944
|
+
return void 0;
|
|
25945
|
+
}
|
|
25946
|
+
if (hasAccountDataShape(response)) {
|
|
25947
|
+
return response;
|
|
25948
|
+
}
|
|
25949
|
+
return void 0;
|
|
25950
|
+
}
|
|
25709
25951
|
function getBalanceInfoContainer(response) {
|
|
25710
25952
|
if (!isRecord(response)) {
|
|
25711
25953
|
return void 0;
|
|
@@ -25786,7 +26028,7 @@ function computeSymmAccountOverview({
|
|
|
25786
26028
|
"pendingLockedPartyAMM",
|
|
25787
26029
|
"pending_locked_party_a_mm"
|
|
25788
26030
|
]);
|
|
25789
|
-
const upnl = upnlOverride === void 0 ? readNumber(balanceInfo, ["upnl"]) :
|
|
26031
|
+
const upnl = upnlOverride === void 0 ? readNumber(balanceInfo, ["upnl"]) : toNumber2(upnlOverride);
|
|
25790
26032
|
const computedTotalLocked = cva + lf + partyAmm;
|
|
25791
26033
|
const totalLocked = readValue(
|
|
25792
26034
|
balanceInfo,
|
|
@@ -25816,11 +26058,43 @@ function computeSymmAccountOverview({
|
|
|
25816
26058
|
availableForOrder: toDisplayString(availableForOrder),
|
|
25817
26059
|
availableMargin: toDisplayString(availableForOrder),
|
|
25818
26060
|
availableBalance: toDisplayString(availableBalance),
|
|
25819
|
-
netDeposited: toDisplayString(
|
|
26061
|
+
netDeposited: toDisplayString(toNumber2(netDeposited)),
|
|
25820
26062
|
notional: toDisplayString(notional),
|
|
25821
26063
|
timestamp: readTimestamp(balanceInfo)
|
|
25822
26064
|
};
|
|
25823
26065
|
}
|
|
26066
|
+
function computeSymmAccountOverviewFromData({
|
|
26067
|
+
accountData,
|
|
26068
|
+
upnl,
|
|
26069
|
+
netDeposited
|
|
26070
|
+
}) {
|
|
26071
|
+
const equity = readNumber(accountData, ["equity"]);
|
|
26072
|
+
const maintenanceMargin = readNumber(accountData, [
|
|
26073
|
+
"maintenanceMargin",
|
|
26074
|
+
"maintenance_margin"
|
|
26075
|
+
]);
|
|
26076
|
+
const availableForOrder = readNumber(accountData, [
|
|
26077
|
+
"availableForOrder",
|
|
26078
|
+
"available_for_order"
|
|
26079
|
+
]);
|
|
26080
|
+
const totalLocked = readNumber(accountData, ["totalLocked", "total_locked"]);
|
|
26081
|
+
return {
|
|
26082
|
+
allocatedBalance: "0",
|
|
26083
|
+
upnl: toDisplayString(toNumber2(upnl)),
|
|
26084
|
+
equity: toDisplayString(equity),
|
|
26085
|
+
totalAccountValue: toDisplayString(equity),
|
|
26086
|
+
maintenanceMargin: toDisplayString(maintenanceMargin),
|
|
26087
|
+
accountHealthData: accountData.accountHealthData,
|
|
26088
|
+
totalLocked: toDisplayString(totalLocked),
|
|
26089
|
+
marginUsed: toDisplayString(totalLocked),
|
|
26090
|
+
totalPendingLocked: "0",
|
|
26091
|
+
availableForOrder: toDisplayString(availableForOrder),
|
|
26092
|
+
availableMargin: toDisplayString(availableForOrder),
|
|
26093
|
+
availableBalance: toDisplayString(availableForOrder),
|
|
26094
|
+
netDeposited: toDisplayString(toNumber2(netDeposited)),
|
|
26095
|
+
notional: "0"
|
|
26096
|
+
};
|
|
26097
|
+
}
|
|
25824
26098
|
function computeSymmNetDeposited(totals, decimals = 6) {
|
|
25825
26099
|
if (!totals) {
|
|
25826
26100
|
return "0";
|
|
@@ -25861,32 +26135,186 @@ function useSymmAccountOverview(params) {
|
|
|
25861
26135
|
const {
|
|
25862
26136
|
userAddress,
|
|
25863
26137
|
accountAddress,
|
|
25864
|
-
multiAccountAddress,
|
|
25865
26138
|
upnl,
|
|
25866
|
-
netDeposited
|
|
26139
|
+
netDeposited,
|
|
26140
|
+
positions,
|
|
26141
|
+
currentPnlQuery
|
|
25867
26142
|
} = params;
|
|
25868
|
-
const
|
|
25869
|
-
|
|
25870
|
-
|
|
26143
|
+
const address = accountAddress ?? userAddress;
|
|
26144
|
+
const shouldUseLocalPnl = upnl === void 0;
|
|
26145
|
+
const currentPnl = useSymmAccountCurrentPnl({
|
|
26146
|
+
accountAddress: address,
|
|
26147
|
+
positions,
|
|
25871
26148
|
chainId: params.chainId,
|
|
25872
|
-
query:
|
|
26149
|
+
query: {
|
|
26150
|
+
...currentPnlQuery,
|
|
26151
|
+
enabled: shouldUseLocalPnl && (currentPnlQuery?.enabled ?? true)
|
|
26152
|
+
}
|
|
26153
|
+
});
|
|
26154
|
+
const resolvedUpnl = shouldUseLocalPnl ? currentPnl.value : upnl;
|
|
26155
|
+
const upnlReady = !shouldUseLocalPnl || positions !== void 0 || currentPnl.positionsQuery.isSuccess;
|
|
26156
|
+
const query = useSymmAccountData({
|
|
26157
|
+
address,
|
|
26158
|
+
upnl: upnlReady ? String(resolvedUpnl ?? 0) : void 0,
|
|
26159
|
+
chainId: params.chainId,
|
|
26160
|
+
query: {
|
|
26161
|
+
...params.query,
|
|
26162
|
+
enabled: upnlReady && (params.query?.enabled ?? true)
|
|
26163
|
+
}
|
|
25873
26164
|
});
|
|
25874
26165
|
const data = react.useMemo(() => {
|
|
25875
26166
|
if (query.data === void 0) {
|
|
25876
26167
|
return void 0;
|
|
25877
26168
|
}
|
|
25878
|
-
const
|
|
25879
|
-
query.data,
|
|
25880
|
-
accountAddress ?? userAddress
|
|
25881
|
-
);
|
|
26169
|
+
const accountData = getSymmAccountData(query.data);
|
|
25882
26170
|
return {
|
|
25883
26171
|
response: query.data,
|
|
25884
|
-
|
|
25885
|
-
|
|
26172
|
+
accountData,
|
|
26173
|
+
coreAccountData: accountData,
|
|
26174
|
+
currentPnl,
|
|
26175
|
+
overview: accountData ? computeSymmAccountOverviewFromData({
|
|
26176
|
+
accountData,
|
|
26177
|
+
upnl: resolvedUpnl,
|
|
26178
|
+
netDeposited
|
|
26179
|
+
}) : void 0
|
|
25886
26180
|
};
|
|
25887
|
-
}, [
|
|
26181
|
+
}, [currentPnl, netDeposited, query.data, resolvedUpnl]);
|
|
25888
26182
|
return { ...query, data };
|
|
25889
26183
|
}
|
|
26184
|
+
function parseMessageData(data) {
|
|
26185
|
+
if (typeof data !== "string") {
|
|
26186
|
+
return data;
|
|
26187
|
+
}
|
|
26188
|
+
try {
|
|
26189
|
+
return JSON.parse(data);
|
|
26190
|
+
} catch {
|
|
26191
|
+
return void 0;
|
|
26192
|
+
}
|
|
26193
|
+
}
|
|
26194
|
+
function toBalanceInfo(message) {
|
|
26195
|
+
return {
|
|
26196
|
+
allocatedBalance: message.allocatedBalance,
|
|
26197
|
+
cva: message.cva,
|
|
26198
|
+
lf: message.lf,
|
|
26199
|
+
partyAmm: message.partyAmm,
|
|
26200
|
+
pendingCva: message.pendingCva,
|
|
26201
|
+
pendingLf: message.pendingLf,
|
|
26202
|
+
pendingPartyAmm: message.pendingPartyAmm,
|
|
26203
|
+
upnl: message.upnl,
|
|
26204
|
+
availableBalance: message.availableBalance,
|
|
26205
|
+
timestamp: message.timestamp
|
|
26206
|
+
};
|
|
26207
|
+
}
|
|
26208
|
+
function useSymmUpnlWebSocket(params) {
|
|
26209
|
+
const {
|
|
26210
|
+
url,
|
|
26211
|
+
accountAddress,
|
|
26212
|
+
enabled = true,
|
|
26213
|
+
reconnectAttempts = 2,
|
|
26214
|
+
reconnectDelayMs = 1e3,
|
|
26215
|
+
webSocketFactory
|
|
26216
|
+
} = params;
|
|
26217
|
+
const [data, setData] = react.useState();
|
|
26218
|
+
const [status, setStatus] = react.useState("idle");
|
|
26219
|
+
const [error, setError] = react.useState();
|
|
26220
|
+
const socketRef = react.useRef(null);
|
|
26221
|
+
const sendAccountAddress = react.useCallback(() => {
|
|
26222
|
+
if (!accountAddress || socketRef.current?.readyState !== 1) {
|
|
26223
|
+
return;
|
|
26224
|
+
}
|
|
26225
|
+
socketRef.current.send(accountAddress);
|
|
26226
|
+
}, [accountAddress]);
|
|
26227
|
+
react.useEffect(() => {
|
|
26228
|
+
if (!enabled || !url || !accountAddress) {
|
|
26229
|
+
setStatus("idle");
|
|
26230
|
+
setData(void 0);
|
|
26231
|
+
setError(void 0);
|
|
26232
|
+
return;
|
|
26233
|
+
}
|
|
26234
|
+
const createSocket = webSocketFactory ?? ((wsUrl) => new WebSocket(wsUrl));
|
|
26235
|
+
let closedByHook = false;
|
|
26236
|
+
let reconnectCount = 0;
|
|
26237
|
+
let reconnectTimer;
|
|
26238
|
+
const connect = () => {
|
|
26239
|
+
setStatus("connecting");
|
|
26240
|
+
const socket = createSocket(url);
|
|
26241
|
+
socketRef.current = socket;
|
|
26242
|
+
socket.onopen = () => {
|
|
26243
|
+
reconnectCount = 0;
|
|
26244
|
+
setStatus("open");
|
|
26245
|
+
setError(void 0);
|
|
26246
|
+
socket.send(accountAddress);
|
|
26247
|
+
};
|
|
26248
|
+
socket.onmessage = (event) => {
|
|
26249
|
+
const parsed = parseMessageData(event.data);
|
|
26250
|
+
const nextMessage = normalizeSymmUpnlWebSocketMessage(parsed);
|
|
26251
|
+
if (nextMessage) {
|
|
26252
|
+
setData(nextMessage);
|
|
26253
|
+
}
|
|
26254
|
+
};
|
|
26255
|
+
socket.onerror = (event) => {
|
|
26256
|
+
setError(event);
|
|
26257
|
+
setStatus("error");
|
|
26258
|
+
};
|
|
26259
|
+
socket.onclose = () => {
|
|
26260
|
+
if (closedByHook) {
|
|
26261
|
+
setStatus("closed");
|
|
26262
|
+
return;
|
|
26263
|
+
}
|
|
26264
|
+
if (reconnectCount < reconnectAttempts) {
|
|
26265
|
+
reconnectCount += 1;
|
|
26266
|
+
reconnectTimer = setTimeout(connect, reconnectDelayMs);
|
|
26267
|
+
return;
|
|
26268
|
+
}
|
|
26269
|
+
setStatus("closed");
|
|
26270
|
+
};
|
|
26271
|
+
};
|
|
26272
|
+
connect();
|
|
26273
|
+
return () => {
|
|
26274
|
+
closedByHook = true;
|
|
26275
|
+
if (reconnectTimer) {
|
|
26276
|
+
clearTimeout(reconnectTimer);
|
|
26277
|
+
}
|
|
26278
|
+
socketRef.current?.close();
|
|
26279
|
+
socketRef.current = null;
|
|
26280
|
+
};
|
|
26281
|
+
}, [
|
|
26282
|
+
accountAddress,
|
|
26283
|
+
enabled,
|
|
26284
|
+
reconnectAttempts,
|
|
26285
|
+
reconnectDelayMs,
|
|
26286
|
+
url,
|
|
26287
|
+
webSocketFactory
|
|
26288
|
+
]);
|
|
26289
|
+
const balanceInfo = react.useMemo(
|
|
26290
|
+
() => data ? toBalanceInfo(data) : void 0,
|
|
26291
|
+
[data]
|
|
26292
|
+
);
|
|
26293
|
+
return {
|
|
26294
|
+
data,
|
|
26295
|
+
upnl: data?.upnl,
|
|
26296
|
+
balanceInfo,
|
|
26297
|
+
status,
|
|
26298
|
+
error,
|
|
26299
|
+
sendAccountAddress
|
|
26300
|
+
};
|
|
26301
|
+
}
|
|
26302
|
+
function useSymmBalances(params) {
|
|
26303
|
+
const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
|
|
26304
|
+
const { userAddress, multiAccountAddress } = params;
|
|
26305
|
+
const chainId = params.chainId ?? ctxChainId;
|
|
26306
|
+
const internalEnabled = !!symmCoreClient && !!userAddress;
|
|
26307
|
+
return reactQuery.useQuery({
|
|
26308
|
+
...params.query,
|
|
26309
|
+
queryKey: symmKeys.balances(userAddress, chainId, multiAccountAddress),
|
|
26310
|
+
queryFn: () => symmCoreClient.accounts.getBalanceInfo({
|
|
26311
|
+
userAddress,
|
|
26312
|
+
chainId,
|
|
26313
|
+
multiAccountAddress
|
|
26314
|
+
}),
|
|
26315
|
+
enabled: internalEnabled && (params.query?.enabled ?? true)
|
|
26316
|
+
});
|
|
26317
|
+
}
|
|
25890
26318
|
function useSymmOpenBasketMutation(options) {
|
|
25891
26319
|
const { symmCoreClient } = useSymmContext();
|
|
25892
26320
|
const queryClient = reactQuery.useQueryClient();
|
|
@@ -26017,28 +26445,6 @@ function useSymmUpdatePositionMutation(paramsOrOptions, maybeOptions) {
|
|
|
26017
26445
|
}
|
|
26018
26446
|
});
|
|
26019
26447
|
}
|
|
26020
|
-
function useSymmPositions(params) {
|
|
26021
|
-
const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
|
|
26022
|
-
const { accountAddress, address } = params;
|
|
26023
|
-
const resolvedAddress = accountAddress ? void 0 : address;
|
|
26024
|
-
const chainId = params.chainId ?? ctxChainId;
|
|
26025
|
-
const internalEnabled = !!symmCoreClient && !!(accountAddress || resolvedAddress);
|
|
26026
|
-
const enabled = internalEnabled && (params.query?.enabled ?? true);
|
|
26027
|
-
return reactQuery.useQuery({
|
|
26028
|
-
...params.query,
|
|
26029
|
-
queryKey: symmKeys.positions({
|
|
26030
|
-
accountAddress,
|
|
26031
|
-
address: resolvedAddress,
|
|
26032
|
-
chainId
|
|
26033
|
-
}),
|
|
26034
|
-
queryFn: () => symmCoreClient.positions.getOpen({
|
|
26035
|
-
accountAddress,
|
|
26036
|
-
address: resolvedAddress,
|
|
26037
|
-
chainId
|
|
26038
|
-
}),
|
|
26039
|
-
enabled
|
|
26040
|
-
});
|
|
26041
|
-
}
|
|
26042
26448
|
function useSymmOpenOrders(params) {
|
|
26043
26449
|
const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
|
|
26044
26450
|
const { accountAddress, address } = params;
|
|
@@ -27461,11 +27867,17 @@ function getSymmErrorMessage(error) {
|
|
|
27461
27867
|
|
|
27462
27868
|
exports.SymmProvider = SymmProvider;
|
|
27463
27869
|
exports.computeSymmAccountOverview = computeSymmAccountOverview;
|
|
27870
|
+
exports.computeSymmAccountOverviewFromData = computeSymmAccountOverviewFromData;
|
|
27464
27871
|
exports.computeSymmNetDeposited = computeSymmNetDeposited;
|
|
27872
|
+
exports.computeSymmPositionUpnl = computeSymmPositionUpnl;
|
|
27873
|
+
exports.computeSymmPositionsUpnl = computeSymmPositionsUpnl;
|
|
27465
27874
|
exports.getSymmAccountBalanceInfo = getSymmAccountBalanceInfo;
|
|
27875
|
+
exports.getSymmAccountData = getSymmAccountData;
|
|
27466
27876
|
exports.getSymmErrorMessage = getSymmErrorMessage;
|
|
27877
|
+
exports.normalizeSymmUpnlWebSocketMessage = normalizeSymmUpnlWebSocketMessage;
|
|
27467
27878
|
exports.symmKeys = symmKeys;
|
|
27468
27879
|
exports.useBinanceMarkPriceStore = useBinanceMarkPriceStore;
|
|
27880
|
+
exports.useSymmAccountCurrentPnl = useSymmAccountCurrentPnl;
|
|
27469
27881
|
exports.useSymmAccountData = useSymmAccountData;
|
|
27470
27882
|
exports.useSymmAccountOverview = useSymmAccountOverview;
|
|
27471
27883
|
exports.useSymmAccountSummary = useSymmAccountSummary;
|
|
@@ -27535,6 +27947,7 @@ exports.useSymmTwapOrder = useSymmTwapOrder;
|
|
|
27535
27947
|
exports.useSymmTwapOrdersQuery = useSymmTwapOrdersQuery;
|
|
27536
27948
|
exports.useSymmUnreadCountQuery = useSymmUnreadCountQuery;
|
|
27537
27949
|
exports.useSymmUpdatePositionMutation = useSymmUpdatePositionMutation;
|
|
27950
|
+
exports.useSymmUpnlWebSocket = useSymmUpnlWebSocket;
|
|
27538
27951
|
exports.useSymmWithdraw = useSymmWithdraw;
|
|
27539
27952
|
exports.useSymmWsStore = useSymmWsStore;
|
|
27540
27953
|
//# sourceMappingURL=index.js.map
|