@pear-protocol/symmio-client 0.3.13 → 0.3.15

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.
@@ -240,14 +240,20 @@ var BinanceWsManager = class {
240
240
  }
241
241
  }
242
242
  ensureConnected() {
243
- if (this.ws && (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING)) {
244
- return;
243
+ if (this.ws) {
244
+ const state = this.ws.readyState;
245
+ if (state === WebSocket.OPEN || state === WebSocket.CONNECTING || state === WebSocket.CLOSING) {
246
+ return;
247
+ }
245
248
  }
246
249
  this.clearReconnectTimer();
247
250
  this.connect();
248
251
  }
249
252
  connect() {
250
253
  if (typeof WebSocket === "undefined") return;
254
+ if (this.ws && this.ws.readyState !== WebSocket.CLOSED) {
255
+ return;
256
+ }
251
257
  this.intentionalClose = false;
252
258
  this.ws = new WebSocket(BINANCE_WS_URL);
253
259
  this.ws.onopen = () => {
@@ -271,9 +277,17 @@ var BinanceWsManager = class {
271
277
  }
272
278
  };
273
279
  this.ws.onclose = () => {
280
+ const wasIntentional = this.intentionalClose;
281
+ this.intentionalClose = false;
274
282
  this.ws = null;
275
283
  this.clearStaleCheckTimer();
276
- if (this.intentionalClose) return;
284
+ if (this.streams.size === 0) {
285
+ return;
286
+ }
287
+ if (wasIntentional) {
288
+ this.connect();
289
+ return;
290
+ }
277
291
  this.scheduleReconnect();
278
292
  };
279
293
  this.ws.onerror = () => {
@@ -349,9 +363,6 @@ var BinanceWsManager = class {
349
363
  if (this.streams.size > 0 || !this.ws) return;
350
364
  this.intentionalClose = true;
351
365
  this.ws.close();
352
- this.ws = null;
353
- this.intentionalClose = false;
354
- this.clearStaleCheckTimer();
355
366
  }, IDLE_CLOSE_DELAY_MS);
356
367
  }
357
368
  startStaleCheck() {
@@ -379,12 +390,15 @@ var BinanceWsManager = class {
379
390
  this.staleCheckTimer = null;
380
391
  }
381
392
  };
382
- var _instance = null;
393
+ var BINANCE_WS_SINGLETON_KEY = "__pearBinanceWsManager__";
383
394
  function getBinanceWsManager() {
384
- if (!_instance) {
385
- _instance = new BinanceWsManager();
395
+ const g = globalThis;
396
+ let manager = g[BINANCE_WS_SINGLETON_KEY];
397
+ if (!manager) {
398
+ manager = new BinanceWsManager();
399
+ g[BINANCE_WS_SINGLETON_KEY] = manager;
386
400
  }
387
- return _instance;
401
+ return manager;
388
402
  }
389
403
 
390
404
  // src/react/stores/use-binance-mark-price-store.ts
@@ -578,7 +592,7 @@ var symmKeys = {
578
592
  signature: (address, chainId) => ["symm", "signature", address, chainId],
579
593
  auth: (accountAddress, chainId, signerAddress) => ["symm", "auth", accountAddress, chainId, signerAddress],
580
594
  approval: (owner, spender, chainId, token) => ["symm", "approval", owner, spender, chainId, token],
581
- balances: (address, chainId) => ["symm", "balances", address, chainId],
595
+ balances: (address, chainId, multiAccountAddress) => multiAccountAddress === void 0 ? ["symm", "balances", address, chainId] : ["symm", "balances", address, chainId, multiAccountAddress],
582
596
  positions: (params) => ["symm", "positions", params],
583
597
  openOrders: (params) => ["symm", "openOrders", params],
584
598
  tradeHistory: (params) => ["symm", "tradeHistory", params],
@@ -25635,6 +25649,616 @@ function useSymmAccountData(params) {
25635
25649
  enabled: internalEnabled && (params.query?.enabled ?? true)
25636
25650
  });
25637
25651
  }
25652
+
25653
+ // src/utils/account-pnl.ts
25654
+ function toNumber(value) {
25655
+ if (value === null || value === void 0 || value === "") {
25656
+ return 0;
25657
+ }
25658
+ const parsed = Number(value);
25659
+ return Number.isFinite(parsed) ? parsed : 0;
25660
+ }
25661
+ function readOpenedPrice(leg) {
25662
+ return toNumber(leg.openedPrice ?? leg.opened_price);
25663
+ }
25664
+ function readCurrentPrice(leg) {
25665
+ const parsed = Number(leg.currentPrice ?? leg.current_price);
25666
+ return Number.isFinite(parsed) ? parsed : void 0;
25667
+ }
25668
+ function readMarkPrice(leg, markPrices) {
25669
+ const symbol = leg.symbol?.trim().toUpperCase();
25670
+ if (symbol) {
25671
+ const markPrice = Number(markPrices[symbol]);
25672
+ if (Number.isFinite(markPrice)) {
25673
+ return markPrice;
25674
+ }
25675
+ }
25676
+ return readCurrentPrice(leg);
25677
+ }
25678
+ function getSymbol(leg) {
25679
+ return leg.symbol?.trim().toUpperCase() || void 0;
25680
+ }
25681
+ function computeLegUpnl(leg, side, markPrices) {
25682
+ const markPrice = readMarkPrice(leg, markPrices);
25683
+ if (markPrice === void 0) {
25684
+ return { upnl: 0, missingSymbol: getSymbol(leg) };
25685
+ }
25686
+ const quantity = toNumber(leg.quantity);
25687
+ const openedPrice = readOpenedPrice(leg);
25688
+ const direction = side === "short" ? -1 : 1;
25689
+ return {
25690
+ upnl: quantity * (markPrice - openedPrice) * direction
25691
+ };
25692
+ }
25693
+ function computeSymmPositionUpnl(position, markPrices = {}) {
25694
+ const missingSymbols = /* @__PURE__ */ new Set();
25695
+ let upnl = 0;
25696
+ let legsCount = 0;
25697
+ for (const leg of position.longAssets ?? []) {
25698
+ legsCount += 1;
25699
+ const result = computeLegUpnl(leg, "long", markPrices);
25700
+ upnl += result.upnl;
25701
+ if (result.missingSymbol) missingSymbols.add(result.missingSymbol);
25702
+ }
25703
+ for (const leg of position.shortAssets ?? []) {
25704
+ legsCount += 1;
25705
+ const result = computeLegUpnl(leg, "short", markPrices);
25706
+ upnl += result.upnl;
25707
+ if (result.missingSymbol) missingSymbols.add(result.missingSymbol);
25708
+ }
25709
+ if (legsCount === 0) {
25710
+ return {
25711
+ upnl: toNumber(position.unrealizedPnl ?? position.unrealized_pnl),
25712
+ missingSymbols: [],
25713
+ positionsCount: 1,
25714
+ legsCount,
25715
+ usedFallbackPositions: 1
25716
+ };
25717
+ }
25718
+ return {
25719
+ upnl,
25720
+ missingSymbols: Array.from(missingSymbols),
25721
+ positionsCount: 1,
25722
+ legsCount,
25723
+ usedFallbackPositions: 0
25724
+ };
25725
+ }
25726
+ function computeSymmPositionsUpnl(positions = [], markPrices = {}) {
25727
+ const missingSymbols = /* @__PURE__ */ new Set();
25728
+ let upnl = 0;
25729
+ let legsCount = 0;
25730
+ let usedFallbackPositions = 0;
25731
+ for (const position of positions) {
25732
+ const result = computeSymmPositionUpnl(position, markPrices);
25733
+ upnl += result.upnl;
25734
+ legsCount += result.legsCount;
25735
+ usedFallbackPositions += result.usedFallbackPositions;
25736
+ result.missingSymbols.forEach((symbol) => missingSymbols.add(symbol));
25737
+ }
25738
+ return {
25739
+ upnl,
25740
+ missingSymbols: Array.from(missingSymbols),
25741
+ positionsCount: positions.length,
25742
+ legsCount,
25743
+ usedFallbackPositions
25744
+ };
25745
+ }
25746
+ function readMessageNumber(message, keys) {
25747
+ for (const key of keys) {
25748
+ if (key in message) {
25749
+ return toNumber(message[key]);
25750
+ }
25751
+ }
25752
+ return 0;
25753
+ }
25754
+ function normalizeSymmUpnlWebSocketMessage(raw) {
25755
+ if (typeof raw !== "object" || raw === null) {
25756
+ return void 0;
25757
+ }
25758
+ const message = raw;
25759
+ const timestamp = readMessageNumber(message, ["timestamp"]);
25760
+ return {
25761
+ upnl: readMessageNumber(message, ["upnl"]),
25762
+ timestamp: timestamp || void 0,
25763
+ availableBalance: readMessageNumber(message, [
25764
+ "availableBalance",
25765
+ "available_balance"
25766
+ ]),
25767
+ allocatedBalance: readMessageNumber(message, [
25768
+ "allocatedBalance",
25769
+ "allocated_balance"
25770
+ ]),
25771
+ cva: readMessageNumber(message, ["cva"]),
25772
+ lf: readMessageNumber(message, ["lf"]),
25773
+ partyAmm: readMessageNumber(message, ["partyAmm", "party_a_mm", "mm"]),
25774
+ pendingPartyAmm: readMessageNumber(message, [
25775
+ "pendingPartyAmm",
25776
+ "pending_party_a_mm",
25777
+ "pending_mm"
25778
+ ]),
25779
+ pendingCva: readMessageNumber(message, ["pendingCva", "pending_cva"]),
25780
+ pendingLf: readMessageNumber(message, ["pendingLf", "pending_lf"]),
25781
+ raw
25782
+ };
25783
+ }
25784
+ function useSymmPositions(params) {
25785
+ const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
25786
+ const { accountAddress, address } = params;
25787
+ const resolvedAddress = accountAddress ? void 0 : address;
25788
+ const chainId = params.chainId ?? ctxChainId;
25789
+ const internalEnabled = !!symmCoreClient && !!(accountAddress || resolvedAddress);
25790
+ const enabled = internalEnabled && (params.query?.enabled ?? true);
25791
+ return reactQuery.useQuery({
25792
+ ...params.query,
25793
+ queryKey: symmKeys.positions({
25794
+ accountAddress,
25795
+ address: resolvedAddress,
25796
+ chainId
25797
+ }),
25798
+ queryFn: () => symmCoreClient.positions.getOpen({
25799
+ accountAddress,
25800
+ address: resolvedAddress,
25801
+ chainId
25802
+ }),
25803
+ enabled
25804
+ });
25805
+ }
25806
+
25807
+ // src/react/hooks/use-symm-account-current-pnl.ts
25808
+ function readPositions(response) {
25809
+ if (typeof response !== "object" || response === null) {
25810
+ return [];
25811
+ }
25812
+ const data = response.data;
25813
+ if (typeof data !== "object" || data === null) {
25814
+ return [];
25815
+ }
25816
+ const positions = data.positions;
25817
+ return Array.isArray(positions) ? positions : [];
25818
+ }
25819
+ function useSymmAccountCurrentPnl(params) {
25820
+ const { accountAddress, address, positions, query } = params;
25821
+ const liveMarkPrices = useBinanceMarkPriceStore((state) => state.markPrices);
25822
+ const positionsQuery = useSymmPositions({
25823
+ accountAddress,
25824
+ address,
25825
+ chainId: params.chainId,
25826
+ query: {
25827
+ ...query,
25828
+ enabled: positions === void 0 && (query?.enabled ?? true)
25829
+ }
25830
+ });
25831
+ const resolvedPositions = positions ?? readPositions(positionsQuery.data);
25832
+ const pnl = react.useMemo(
25833
+ () => computeSymmPositionsUpnl(resolvedPositions, liveMarkPrices),
25834
+ [liveMarkPrices, resolvedPositions]
25835
+ );
25836
+ return {
25837
+ ...pnl,
25838
+ value: pnl.upnl,
25839
+ positions: resolvedPositions,
25840
+ positionsQuery
25841
+ };
25842
+ }
25843
+
25844
+ // src/utils/account-overview.ts
25845
+ var BALANCE_INFO_KEYS = [
25846
+ "allocatedBalance",
25847
+ "allocated_balance",
25848
+ "cva",
25849
+ "lf",
25850
+ "partyAmm",
25851
+ "partyAMM",
25852
+ "party_a_mm",
25853
+ "mm",
25854
+ "lockedPartyAMM",
25855
+ "upnl"
25856
+ ];
25857
+ function isRecord(value) {
25858
+ return typeof value === "object" && value !== null;
25859
+ }
25860
+ function hasBalanceInfoShape(value) {
25861
+ return isRecord(value) && BALANCE_INFO_KEYS.some((key) => key in value);
25862
+ }
25863
+ function readValue(source, keys) {
25864
+ for (const key of keys) {
25865
+ if (key in source) {
25866
+ return source[key];
25867
+ }
25868
+ }
25869
+ return void 0;
25870
+ }
25871
+ function toNumber2(value) {
25872
+ if (value === null || value === void 0 || value === "") {
25873
+ return 0;
25874
+ }
25875
+ if (typeof value === "bigint") {
25876
+ return Number(value);
25877
+ }
25878
+ const parsed = Number(value);
25879
+ return Number.isFinite(parsed) ? parsed : 0;
25880
+ }
25881
+ function toDisplayString(value) {
25882
+ if (Object.is(value, -0) || Math.abs(value) < Number.EPSILON) {
25883
+ return "0";
25884
+ }
25885
+ return String(value);
25886
+ }
25887
+ function readNumber(source, keys) {
25888
+ return toNumber2(readValue(source, keys));
25889
+ }
25890
+ function readTimestamp(source) {
25891
+ const timestamp = readValue(source, ["timestamp"]);
25892
+ if (timestamp === void 0 || timestamp === null) {
25893
+ return void 0;
25894
+ }
25895
+ const parsed = Number(timestamp);
25896
+ return Number.isFinite(parsed) ? parsed : void 0;
25897
+ }
25898
+ function getSymmAccountData(response) {
25899
+ if (!isRecord(response)) {
25900
+ return void 0;
25901
+ }
25902
+ const data = response.data;
25903
+ if (isRecord(data)) {
25904
+ return data;
25905
+ }
25906
+ if ("equity" in response || "maintenanceMargin" in response || "availableForOrder" in response || "totalLocked" in response) {
25907
+ return response;
25908
+ }
25909
+ return void 0;
25910
+ }
25911
+ function getBalanceInfoContainer(response) {
25912
+ if (!isRecord(response)) {
25913
+ return void 0;
25914
+ }
25915
+ if (hasBalanceInfoShape(response)) {
25916
+ return response;
25917
+ }
25918
+ const data = response.data;
25919
+ if (isRecord(data)) {
25920
+ return data;
25921
+ }
25922
+ return response;
25923
+ }
25924
+ function getSymmAccountBalanceInfo(response, accountAddress) {
25925
+ const container = getBalanceInfoContainer(response);
25926
+ if (!container) {
25927
+ return void 0;
25928
+ }
25929
+ if (hasBalanceInfoShape(container)) {
25930
+ return container;
25931
+ }
25932
+ if (accountAddress) {
25933
+ const normalizedAddress = accountAddress.toLowerCase();
25934
+ const direct = container[accountAddress] ?? container[normalizedAddress];
25935
+ if (isRecord(direct) && hasBalanceInfoShape(direct)) {
25936
+ return direct;
25937
+ }
25938
+ const matchingEntry = Object.entries(container).find(
25939
+ ([key]) => key.toLowerCase() === normalizedAddress
25940
+ );
25941
+ if (isRecord(matchingEntry?.[1]) && hasBalanceInfoShape(matchingEntry[1])) {
25942
+ return matchingEntry[1];
25943
+ }
25944
+ }
25945
+ const values = Object.values(container);
25946
+ if (values.length === 1 && isRecord(values[0]) && hasBalanceInfoShape(values[0])) {
25947
+ return values[0];
25948
+ }
25949
+ return void 0;
25950
+ }
25951
+ function computeSymmAccountOverview({
25952
+ balanceInfo,
25953
+ upnl: upnlOverride,
25954
+ netDeposited
25955
+ }) {
25956
+ const allocatedBalance = readNumber(balanceInfo, [
25957
+ "allocatedBalance",
25958
+ "allocated_balance"
25959
+ ]);
25960
+ const cva = readNumber(balanceInfo, ["cva", "lockedCVA", "locked_cva"]);
25961
+ const lf = readNumber(balanceInfo, ["lf", "lockedLF", "locked_lf"]);
25962
+ const partyAmm = readNumber(balanceInfo, [
25963
+ "partyAmm",
25964
+ "partyAMM",
25965
+ "party_a_mm",
25966
+ "mm",
25967
+ "lockedPartyAMM",
25968
+ "locked_party_a_mm"
25969
+ ]);
25970
+ const pendingCva = readNumber(balanceInfo, [
25971
+ "pendingCva",
25972
+ "pending_cva",
25973
+ "pendingLockedCVA",
25974
+ "pending_locked_cva"
25975
+ ]);
25976
+ const pendingLf = readNumber(balanceInfo, [
25977
+ "pendingLf",
25978
+ "pending_lf",
25979
+ "pendingLockedLF",
25980
+ "pending_locked_lf"
25981
+ ]);
25982
+ const pendingPartyAmm = readNumber(balanceInfo, [
25983
+ "pendingPartyAmm",
25984
+ "pendingPartyAMM",
25985
+ "pending_party_a_mm",
25986
+ "pendingMm",
25987
+ "pending_mm",
25988
+ "pendingLockedPartyAMM",
25989
+ "pending_locked_party_a_mm"
25990
+ ]);
25991
+ const upnl = upnlOverride === void 0 ? readNumber(balanceInfo, ["upnl"]) : toNumber2(upnlOverride);
25992
+ const computedTotalLocked = cva + lf + partyAmm;
25993
+ const totalLocked = readValue(
25994
+ balanceInfo,
25995
+ ["totalLocked", "total_locked"]
25996
+ ) === void 0 ? computedTotalLocked : readNumber(balanceInfo, ["totalLocked", "total_locked"]);
25997
+ const totalPendingLocked = readValue(balanceInfo, [
25998
+ "totalPendingLocked",
25999
+ "total_pending_locked"
26000
+ ]) === void 0 ? pendingCva + pendingLf + pendingPartyAmm : readNumber(balanceInfo, ["totalPendingLocked", "total_pending_locked"]);
26001
+ const maintenanceMargin = cva + lf;
26002
+ const equity = allocatedBalance + upnl;
26003
+ const availableForOrder = upnl >= 0 ? allocatedBalance + upnl - totalLocked - totalPendingLocked : allocatedBalance - cva - lf - totalPendingLocked - Math.max(Math.abs(upnl), partyAmm);
26004
+ const availableBalance = readNumber(balanceInfo, [
26005
+ "availableBalance",
26006
+ "available_balance"
26007
+ ]);
26008
+ const notional = readNumber(balanceInfo, ["notional"]);
26009
+ return {
26010
+ allocatedBalance: toDisplayString(allocatedBalance),
26011
+ upnl: toDisplayString(upnl),
26012
+ equity: toDisplayString(equity),
26013
+ totalAccountValue: toDisplayString(equity),
26014
+ maintenanceMargin: toDisplayString(maintenanceMargin),
26015
+ totalLocked: toDisplayString(totalLocked),
26016
+ marginUsed: toDisplayString(computedTotalLocked),
26017
+ totalPendingLocked: toDisplayString(totalPendingLocked),
26018
+ availableForOrder: toDisplayString(availableForOrder),
26019
+ availableMargin: toDisplayString(availableForOrder),
26020
+ availableBalance: toDisplayString(availableBalance),
26021
+ netDeposited: toDisplayString(toNumber2(netDeposited)),
26022
+ notional: toDisplayString(notional),
26023
+ timestamp: readTimestamp(balanceInfo)
26024
+ };
26025
+ }
26026
+ function computeSymmAccountOverviewFromData({
26027
+ accountData,
26028
+ upnl,
26029
+ netDeposited
26030
+ }) {
26031
+ const equity = readNumber(accountData, ["equity"]);
26032
+ const maintenanceMargin = readNumber(accountData, [
26033
+ "maintenanceMargin",
26034
+ "maintenance_margin"
26035
+ ]);
26036
+ const availableForOrder = readNumber(accountData, [
26037
+ "availableForOrder",
26038
+ "available_for_order"
26039
+ ]);
26040
+ const totalLocked = readNumber(accountData, ["totalLocked", "total_locked"]);
26041
+ return {
26042
+ allocatedBalance: "0",
26043
+ upnl: toDisplayString(toNumber2(upnl)),
26044
+ equity: toDisplayString(equity),
26045
+ totalAccountValue: toDisplayString(equity),
26046
+ maintenanceMargin: toDisplayString(maintenanceMargin),
26047
+ accountHealthData: accountData.accountHealthData,
26048
+ totalLocked: toDisplayString(totalLocked),
26049
+ marginUsed: toDisplayString(totalLocked),
26050
+ totalPendingLocked: "0",
26051
+ availableForOrder: toDisplayString(availableForOrder),
26052
+ availableMargin: toDisplayString(availableForOrder),
26053
+ availableBalance: toDisplayString(availableForOrder),
26054
+ netDeposited: toDisplayString(toNumber2(netDeposited)),
26055
+ notional: "0"
26056
+ };
26057
+ }
26058
+ function computeSymmNetDeposited(totals, decimals = 6) {
26059
+ if (!totals) {
26060
+ return "0";
26061
+ }
26062
+ const deposit2 = parseRawCollateralUnits(totals.deposit);
26063
+ const withdraw2 = parseRawCollateralUnits(totals.withdraw);
26064
+ const value = deposit2 - withdraw2;
26065
+ const negative = value < 0n;
26066
+ const absolute = negative ? -value : value;
26067
+ const scale = 10n ** BigInt(decimals);
26068
+ const whole = absolute / scale;
26069
+ const fraction = absolute % scale;
26070
+ const fractionText = fraction.toString().padStart(decimals, "0").replace(/0+$/, "");
26071
+ const amount = fractionText ? `${whole}.${fractionText}` : whole.toString();
26072
+ return negative ? `-${amount}` : amount;
26073
+ }
26074
+ function parseRawCollateralUnits(value) {
26075
+ if (value === null || value === void 0 || value === "") {
26076
+ return 0n;
26077
+ }
26078
+ if (typeof value === "bigint") {
26079
+ return value;
26080
+ }
26081
+ if (typeof value === "number") {
26082
+ if (!Number.isSafeInteger(value)) {
26083
+ throw new Error("Raw collateral unit numbers must be safe integers");
26084
+ }
26085
+ return BigInt(value);
26086
+ }
26087
+ if (!/^-?\d+$/.test(value)) {
26088
+ throw new Error("Raw collateral unit strings must be base-10 integers");
26089
+ }
26090
+ return BigInt(value);
26091
+ }
26092
+
26093
+ // src/react/hooks/use-symm-account-overview.ts
26094
+ function useSymmAccountOverview(params) {
26095
+ const {
26096
+ userAddress,
26097
+ accountAddress,
26098
+ upnl,
26099
+ netDeposited,
26100
+ positions,
26101
+ currentPnlQuery
26102
+ } = params;
26103
+ const address = accountAddress ?? userAddress;
26104
+ const shouldUseLocalPnl = upnl === void 0;
26105
+ const currentPnl = useSymmAccountCurrentPnl({
26106
+ accountAddress: address,
26107
+ positions,
26108
+ chainId: params.chainId,
26109
+ query: {
26110
+ ...currentPnlQuery,
26111
+ enabled: shouldUseLocalPnl && (currentPnlQuery?.enabled ?? true)
26112
+ }
26113
+ });
26114
+ const resolvedUpnl = shouldUseLocalPnl ? currentPnl.value : upnl;
26115
+ const upnlReady = !shouldUseLocalPnl || positions !== void 0 || currentPnl.positionsQuery.isSuccess;
26116
+ const query = useSymmAccountData({
26117
+ address,
26118
+ upnl: upnlReady ? String(resolvedUpnl ?? 0) : void 0,
26119
+ chainId: params.chainId,
26120
+ query: {
26121
+ ...params.query,
26122
+ enabled: upnlReady && (params.query?.enabled ?? true)
26123
+ }
26124
+ });
26125
+ const data = react.useMemo(() => {
26126
+ if (query.data === void 0) {
26127
+ return void 0;
26128
+ }
26129
+ const accountData = getSymmAccountData(query.data);
26130
+ return {
26131
+ response: query.data,
26132
+ accountData,
26133
+ coreAccountData: accountData,
26134
+ currentPnl,
26135
+ overview: accountData ? computeSymmAccountOverviewFromData({
26136
+ accountData,
26137
+ upnl: resolvedUpnl,
26138
+ netDeposited
26139
+ }) : void 0
26140
+ };
26141
+ }, [currentPnl, netDeposited, query.data, resolvedUpnl]);
26142
+ return { ...query, data };
26143
+ }
26144
+ function parseMessageData(data) {
26145
+ if (typeof data !== "string") {
26146
+ return data;
26147
+ }
26148
+ try {
26149
+ return JSON.parse(data);
26150
+ } catch {
26151
+ return void 0;
26152
+ }
26153
+ }
26154
+ function toBalanceInfo(message) {
26155
+ return {
26156
+ allocatedBalance: message.allocatedBalance,
26157
+ cva: message.cva,
26158
+ lf: message.lf,
26159
+ partyAmm: message.partyAmm,
26160
+ pendingCva: message.pendingCva,
26161
+ pendingLf: message.pendingLf,
26162
+ pendingPartyAmm: message.pendingPartyAmm,
26163
+ upnl: message.upnl,
26164
+ availableBalance: message.availableBalance,
26165
+ timestamp: message.timestamp
26166
+ };
26167
+ }
26168
+ function useSymmUpnlWebSocket(params) {
26169
+ const {
26170
+ url,
26171
+ accountAddress,
26172
+ enabled = true,
26173
+ reconnectAttempts = 2,
26174
+ reconnectDelayMs = 1e3,
26175
+ webSocketFactory
26176
+ } = params;
26177
+ const [data, setData] = react.useState();
26178
+ const [status, setStatus] = react.useState("idle");
26179
+ const [error, setError] = react.useState();
26180
+ const socketRef = react.useRef(null);
26181
+ const sendAccountAddress = react.useCallback(() => {
26182
+ if (!accountAddress || socketRef.current?.readyState !== 1) {
26183
+ return;
26184
+ }
26185
+ socketRef.current.send(accountAddress);
26186
+ }, [accountAddress]);
26187
+ react.useEffect(() => {
26188
+ if (!enabled || !url || !accountAddress) {
26189
+ setStatus("idle");
26190
+ setData(void 0);
26191
+ setError(void 0);
26192
+ return;
26193
+ }
26194
+ const createSocket = webSocketFactory ?? ((wsUrl) => new WebSocket(wsUrl));
26195
+ let closedByHook = false;
26196
+ let reconnectCount = 0;
26197
+ let reconnectTimer;
26198
+ const connect = () => {
26199
+ setStatus("connecting");
26200
+ const socket = createSocket(url);
26201
+ socketRef.current = socket;
26202
+ socket.onopen = () => {
26203
+ reconnectCount = 0;
26204
+ setStatus("open");
26205
+ setError(void 0);
26206
+ socket.send(accountAddress);
26207
+ };
26208
+ socket.onmessage = (event) => {
26209
+ const parsed = parseMessageData(event.data);
26210
+ const nextMessage = normalizeSymmUpnlWebSocketMessage(parsed);
26211
+ if (nextMessage) {
26212
+ setData(nextMessage);
26213
+ }
26214
+ };
26215
+ socket.onerror = (event) => {
26216
+ setError(event);
26217
+ setStatus("error");
26218
+ };
26219
+ socket.onclose = () => {
26220
+ if (closedByHook) {
26221
+ setStatus("closed");
26222
+ return;
26223
+ }
26224
+ if (reconnectCount < reconnectAttempts) {
26225
+ reconnectCount += 1;
26226
+ reconnectTimer = setTimeout(connect, reconnectDelayMs);
26227
+ return;
26228
+ }
26229
+ setStatus("closed");
26230
+ };
26231
+ };
26232
+ connect();
26233
+ return () => {
26234
+ closedByHook = true;
26235
+ if (reconnectTimer) {
26236
+ clearTimeout(reconnectTimer);
26237
+ }
26238
+ socketRef.current?.close();
26239
+ socketRef.current = null;
26240
+ };
26241
+ }, [
26242
+ accountAddress,
26243
+ enabled,
26244
+ reconnectAttempts,
26245
+ reconnectDelayMs,
26246
+ url,
26247
+ webSocketFactory
26248
+ ]);
26249
+ const balanceInfo = react.useMemo(
26250
+ () => data ? toBalanceInfo(data) : void 0,
26251
+ [data]
26252
+ );
26253
+ return {
26254
+ data,
26255
+ upnl: data?.upnl,
26256
+ balanceInfo,
26257
+ status,
26258
+ error,
26259
+ sendAccountAddress
26260
+ };
26261
+ }
25638
26262
  function useSymmBalances(params) {
25639
26263
  const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
25640
26264
  const { userAddress, multiAccountAddress } = params;
@@ -25642,7 +26266,7 @@ function useSymmBalances(params) {
25642
26266
  const internalEnabled = !!symmCoreClient && !!userAddress;
25643
26267
  return reactQuery.useQuery({
25644
26268
  ...params.query,
25645
- queryKey: symmKeys.balances(userAddress, chainId),
26269
+ queryKey: symmKeys.balances(userAddress, chainId, multiAccountAddress),
25646
26270
  queryFn: () => symmCoreClient.accounts.getBalanceInfo({
25647
26271
  userAddress,
25648
26272
  chainId,
@@ -25781,28 +26405,6 @@ function useSymmUpdatePositionMutation(paramsOrOptions, maybeOptions) {
25781
26405
  }
25782
26406
  });
25783
26407
  }
25784
- function useSymmPositions(params) {
25785
- const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
25786
- const { accountAddress, address } = params;
25787
- const resolvedAddress = accountAddress ? void 0 : address;
25788
- const chainId = params.chainId ?? ctxChainId;
25789
- const internalEnabled = !!symmCoreClient && !!(accountAddress || resolvedAddress);
25790
- const enabled = internalEnabled && (params.query?.enabled ?? true);
25791
- return reactQuery.useQuery({
25792
- ...params.query,
25793
- queryKey: symmKeys.positions({
25794
- accountAddress,
25795
- address: resolvedAddress,
25796
- chainId
25797
- }),
25798
- queryFn: () => symmCoreClient.positions.getOpen({
25799
- accountAddress,
25800
- address: resolvedAddress,
25801
- chainId
25802
- }),
25803
- enabled
25804
- });
25805
- }
25806
26408
  function useSymmOpenOrders(params) {
25807
26409
  const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
25808
26410
  const { accountAddress, address } = params;
@@ -27224,10 +27826,20 @@ function getSymmErrorMessage(error) {
27224
27826
  }
27225
27827
 
27226
27828
  exports.SymmProvider = SymmProvider;
27829
+ exports.computeSymmAccountOverview = computeSymmAccountOverview;
27830
+ exports.computeSymmAccountOverviewFromData = computeSymmAccountOverviewFromData;
27831
+ exports.computeSymmNetDeposited = computeSymmNetDeposited;
27832
+ exports.computeSymmPositionUpnl = computeSymmPositionUpnl;
27833
+ exports.computeSymmPositionsUpnl = computeSymmPositionsUpnl;
27834
+ exports.getSymmAccountBalanceInfo = getSymmAccountBalanceInfo;
27835
+ exports.getSymmAccountData = getSymmAccountData;
27227
27836
  exports.getSymmErrorMessage = getSymmErrorMessage;
27837
+ exports.normalizeSymmUpnlWebSocketMessage = normalizeSymmUpnlWebSocketMessage;
27228
27838
  exports.symmKeys = symmKeys;
27229
27839
  exports.useBinanceMarkPriceStore = useBinanceMarkPriceStore;
27840
+ exports.useSymmAccountCurrentPnl = useSymmAccountCurrentPnl;
27230
27841
  exports.useSymmAccountData = useSymmAccountData;
27842
+ exports.useSymmAccountOverview = useSymmAccountOverview;
27231
27843
  exports.useSymmAccountSummary = useSymmAccountSummary;
27232
27844
  exports.useSymmAccountsApi = useSymmAccountsApi;
27233
27845
  exports.useSymmAccountsLength = useSymmAccountsLength;
@@ -27295,6 +27907,7 @@ exports.useSymmTwapOrder = useSymmTwapOrder;
27295
27907
  exports.useSymmTwapOrdersQuery = useSymmTwapOrdersQuery;
27296
27908
  exports.useSymmUnreadCountQuery = useSymmUnreadCountQuery;
27297
27909
  exports.useSymmUpdatePositionMutation = useSymmUpdatePositionMutation;
27910
+ exports.useSymmUpnlWebSocket = useSymmUpnlWebSocket;
27298
27911
  exports.useSymmWithdraw = useSymmWithdraw;
27299
27912
  exports.useSymmWsStore = useSymmWsStore;
27300
27913
  //# sourceMappingURL=index.js.map