@pear-protocol/symmio-client 0.2.5 → 0.2.7

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.
@@ -1,7 +1,8 @@
1
1
  'use client';
2
- import { createContext, useContext, useState, useEffect, useMemo, useRef, useCallback } from 'react';
2
+ import { createContext, useContext, useEffect, useMemo, useRef, useCallback } from 'react';
3
3
  import { createSymmSDK, isAuthExpiredError, isNetworkError, isInsufficientMarginError, isRateLimitedError, isTimeoutError } from '@pear-protocol/symm-core';
4
4
  import { useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
5
+ import { create } from 'zustand';
5
6
  import { jsx } from 'react/jsx-runtime';
6
7
  import { isAddress, encodeFunctionData } from 'viem';
7
8
 
@@ -22,13 +23,13 @@ var symmKeys = {
22
23
  accountsLength: (address, chainId) => ["symm", "accountsLength", address, chainId],
23
24
  accountsWithPositions: (address, chainId) => ["symm", "accountsWithPositions", address, chainId],
24
25
  accountSummary: (address, chainId) => ["symm", "accountSummary", address, chainId],
25
- accountData: (address, chainId) => ["symm", "accountData", address, chainId],
26
+ accountData: (address, chainId, upnl) => ["symm", "accountData", address, chainId, upnl],
26
27
  signature: (address, chainId) => ["symm", "signature", address, chainId],
27
- approval: (owner, spender, chainId) => ["symm", "approval", owner, spender, chainId],
28
+ approval: (owner, spender, chainId, token) => ["symm", "approval", owner, spender, chainId, token],
28
29
  balances: (address, chainId) => ["symm", "balances", address, chainId],
29
- positions: (address, chainId) => ["symm", "positions", address, chainId],
30
- openOrders: (address, chainId) => ["symm", "openOrders", address, chainId],
31
- tradeHistory: (address, chainId) => ["symm", "tradeHistory", address, chainId],
30
+ positions: (params) => ["symm", "positions", params],
31
+ openOrders: (params) => ["symm", "openOrders", params],
32
+ tradeHistory: (params) => ["symm", "tradeHistory", params],
32
33
  tpslOrders: (address, chainId) => ["symm", "tpslOrders", address, chainId],
33
34
  tpslOrdersList: (params) => ["symm", "tpslOrders", params],
34
35
  twapOrders: (address, chainId) => ["symm", "twapOrders", address, chainId],
@@ -42,7 +43,7 @@ var symmKeys = {
42
43
  fundingRates: (chainId) => ["symm", "fundingRates", chainId],
43
44
  fundingPayments: (params) => ["symm", "fundingPayments", params],
44
45
  fundingHistory: (params) => ["symm", "fundingHistory", params],
45
- portfolio: (address, chainId) => ["symm", "portfolio", address, chainId],
46
+ portfolio: (params) => ["symm", "portfolio", params],
46
47
  notifications: (address, chainId) => ["symm", "notifications", address, chainId],
47
48
  unreadCount: (address, chainId) => ["symm", "unreadCount", address, chainId],
48
49
  availableMargin: (address, chainId) => ["symm", "availableMargin", address, chainId],
@@ -52,43 +53,46 @@ var symmKeys = {
52
53
  delegation: (account, target, selectors, chainId) => ["symm", "delegation", account, target, selectors, chainId],
53
54
  chartMetadata: (symbolsKey, positionKey) => ["symm", "chartMetadata", symbolsKey, positionKey]
54
55
  };
56
+ var useSymmWsStore = create((set) => ({
57
+ isConnected: false,
58
+ setConnected: (isConnected) => set({ isConnected })
59
+ }));
55
60
 
56
61
  // src/react/hooks/use-symm-ws.ts
57
62
  function asUnsubscribeFn(value) {
58
63
  return typeof value === "function" ? value : null;
59
64
  }
60
65
  function useSymmWs(params) {
61
- const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
62
66
  const queryClient = useQueryClient();
63
- const { accountAddress } = params;
64
- const chainId = params.chainId ?? ctxChainId;
65
- const [isConnected, setIsConnected] = useState(false);
67
+ const isConnected = useSymmWsStore((state) => state.isConnected);
68
+ const setConnected = useSymmWsStore((state) => state.setConnected);
69
+ const { symmCoreClient, accountAddress, chainId } = params;
66
70
  useEffect(() => {
67
71
  if (!symmCoreClient || !accountAddress) {
68
- setIsConnected(false);
72
+ setConnected(false);
69
73
  return;
70
74
  }
71
75
  const ws = symmCoreClient.ws;
72
76
  const addr = accountAddress;
73
77
  const unsubscribers = [];
74
- const removeOnConnect = ws.onConnect(() => setIsConnected(true));
75
- const removeOnDisconnect = ws.onDisconnect(() => setIsConnected(false));
78
+ const removeOnConnect = ws.onConnect(() => setConnected(true));
79
+ const removeOnDisconnect = ws.onDisconnect(() => setConnected(false));
76
80
  unsubscribers.push(removeOnConnect, removeOnDisconnect);
77
81
  const positionsUnsub = asUnsubscribeFn(ws.subscribeToPositions(addr, chainId, () => {
78
82
  queryClient.invalidateQueries({
79
- queryKey: symmKeys.positions(accountAddress, chainId)
83
+ queryKey: ["symm", "positions"]
80
84
  });
81
85
  }));
82
86
  if (positionsUnsub) unsubscribers.push(positionsUnsub);
83
87
  const openOrdersUnsub = asUnsubscribeFn(ws.subscribeToOpenOrders(addr, chainId, () => {
84
88
  queryClient.invalidateQueries({
85
- queryKey: symmKeys.openOrders(accountAddress, chainId)
89
+ queryKey: ["symm", "openOrders"]
86
90
  });
87
91
  }));
88
92
  if (openOrdersUnsub) unsubscribers.push(openOrdersUnsub);
89
93
  const tradesUnsub = asUnsubscribeFn(ws.subscribeToTrades(addr, chainId, () => {
90
94
  queryClient.invalidateQueries({
91
- queryKey: symmKeys.tradeHistory(accountAddress, chainId)
95
+ queryKey: ["symm", "tradeHistory"]
92
96
  });
93
97
  }));
94
98
  if (tradesUnsub) unsubscribers.push(tradesUnsub);
@@ -127,10 +131,10 @@ function useSymmWs(params) {
127
131
  if (triggerOrdersUnsub) unsubscribers.push(triggerOrdersUnsub);
128
132
  const executionsUnsub = asUnsubscribeFn(ws.subscribeToExecutions(addr, chainId, () => {
129
133
  queryClient.invalidateQueries({
130
- queryKey: symmKeys.positions(accountAddress, chainId)
134
+ queryKey: ["symm", "positions"]
131
135
  });
132
136
  queryClient.invalidateQueries({
133
- queryKey: symmKeys.portfolio(accountAddress, chainId)
137
+ queryKey: ["symm", "portfolio"]
134
138
  });
135
139
  }));
136
140
  if (executionsUnsub) unsubscribers.push(executionsUnsub);
@@ -143,7 +147,7 @@ function useSymmWs(params) {
143
147
  ws.unsubscribeAll();
144
148
  }
145
149
  };
146
- }, [symmCoreClient, accountAddress, chainId, queryClient]);
150
+ }, [symmCoreClient, accountAddress, chainId, queryClient, setConnected]);
147
151
  return { isConnected };
148
152
  }
149
153
  var noopRefreshAuth = async () => null;
@@ -165,7 +169,7 @@ function SymmProvider({
165
169
  });
166
170
  }, [chainId, symmCoreConfig.apiUrl, symmCoreConfig.wsUrl]);
167
171
  const resolvedAuthToken = authToken ?? accessToken;
168
- useSymmWs({ chainId });
172
+ useSymmWs({ symmCoreClient, accountAddress: address, chainId });
169
173
  const value = useMemo(
170
174
  () => ({
171
175
  symmCoreClient,
@@ -371,20 +375,60 @@ async function fetchAccessToken(walletClient, signerAddress, accountAddress, cha
371
375
  writeStoredToken(accountAddress, chainId, cachedToken);
372
376
  return accessToken;
373
377
  }
378
+ function symmAuthTokenKey(address, chainId) {
379
+ return `${address.toLowerCase()}:${chainId}`;
380
+ }
381
+ var useSymmAuthStore = create((set, get) => ({
382
+ tokensByKey: {},
383
+ setToken: (address, chainId, token) => {
384
+ const key = symmAuthTokenKey(address, chainId);
385
+ set((state) => ({
386
+ tokensByKey: {
387
+ ...state.tokensByKey,
388
+ [key]: token
389
+ }
390
+ }));
391
+ },
392
+ getToken: (address, chainId) => {
393
+ const key = symmAuthTokenKey(address, chainId);
394
+ return get().tokensByKey[key] ?? null;
395
+ },
396
+ clearToken: (address, chainId) => {
397
+ const key = symmAuthTokenKey(address, chainId);
398
+ set((state) => {
399
+ if (!(key in state.tokensByKey)) return state;
400
+ const next = { ...state.tokensByKey };
401
+ delete next[key];
402
+ return { tokensByKey: next };
403
+ });
404
+ },
405
+ clearAll: () => {
406
+ set({ tokensByKey: {} });
407
+ }
408
+ }));
374
409
 
375
410
  // src/react/hooks/use-symm-auth.ts
376
411
  function useSymmAuth(params) {
377
412
  const { address, chainId, walletClient, siweDomain } = params;
378
- const [accessToken, setAccessToken] = useState(null);
413
+ const accessToken = useSymmAuthStore(
414
+ (state) => address ? state.tokensByKey[symmAuthTokenKey(address, chainId)] ?? null : null
415
+ );
416
+ const setToken = useSymmAuthStore((state) => state.setToken);
417
+ const getToken = useSymmAuthStore((state) => state.getToken);
418
+ const clearToken = useSymmAuthStore((state) => state.clearToken);
379
419
  const previousAddressRef = useRef(address);
380
420
  const previousChainIdRef = useRef(chainId);
381
421
  const refreshAuth = useCallback(
382
422
  async (accountAddress) => {
383
423
  if (!walletClient || !address) return null;
384
424
  const resolvedAccountAddress = accountAddress ?? address;
425
+ const inMemory = getToken(resolvedAccountAddress, chainId);
426
+ if (inMemory) {
427
+ return inMemory;
428
+ }
385
429
  const cached = getCachedToken(resolvedAccountAddress, chainId);
386
430
  if (cached) {
387
- setAccessToken(cached);
431
+ setToken(resolvedAccountAddress, chainId, cached);
388
432
  return cached;
389
433
  }
390
434
  try {
@@ -395,21 +439,21 @@ function useSymmAuth(params) {
395
439
  chainId,
396
440
  siweDomain
397
441
  );
398
- setAccessToken(token);
442
+ setToken(resolvedAccountAddress, chainId, token);
399
443
  return token;
400
444
  } catch {
401
- setAccessToken(null);
445
+ clearToken(resolvedAccountAddress, chainId);
402
446
  return null;
403
447
  }
404
448
  },
405
- [walletClient, address, chainId, siweDomain]
449
+ [walletClient, address, chainId, siweDomain, getToken, setToken, clearToken]
406
450
  );
407
451
  const clearAuth = useCallback(() => {
408
452
  if (address) {
409
453
  clearCachedToken(address, chainId);
454
+ clearToken(address, chainId);
410
455
  }
411
- setAccessToken(null);
412
- }, [address, chainId]);
456
+ }, [address, chainId, clearToken]);
413
457
  useEffect(() => {
414
458
  const previousAddress = previousAddressRef.current;
415
459
  const previousChainId = previousChainIdRef.current;
@@ -418,15 +462,19 @@ function useSymmAuth(params) {
418
462
  previousAddressRef.current = address;
419
463
  previousChainIdRef.current = chainId;
420
464
  if (!address || !walletClient) {
421
- setAccessToken(null);
422
465
  return;
423
466
  }
424
467
  if (previousAddress && (addressChanged || chainChanged)) {
425
468
  clearCachedToken(previousAddress, previousChainId);
469
+ clearToken(previousAddress, previousChainId);
426
470
  }
427
471
  const cached = getCachedToken(address, chainId);
428
- setAccessToken(cached);
429
- }, [address, walletClient, chainId]);
472
+ if (cached) {
473
+ setToken(address, chainId, cached);
474
+ } else {
475
+ clearToken(address, chainId);
476
+ }
477
+ }, [address, walletClient, chainId, setToken, clearToken]);
430
478
  return {
431
479
  accessToken,
432
480
  authToken: accessToken,
@@ -1040,7 +1088,7 @@ function useSymmInstantTrade(params) {
1040
1088
  if (selectors.length === 0) {
1041
1089
  throw new Error("at least one delegation selector is required");
1042
1090
  }
1043
- const accessToken = await refreshAuth(accountAddress);
1091
+ const accessToken = useSymmAuthStore.getState().getToken(accountAddress, chainId) ?? await refreshAuth(accountAddress);
1044
1092
  if (!accessToken) {
1045
1093
  throw new Error("failed to refresh instant-trading auth");
1046
1094
  }
@@ -1396,7 +1444,7 @@ function useSymmApproval(params) {
1396
1444
  const internalEnabled = !!publicClient && !!owner && !!resolvedSpender && !!resolvedToken;
1397
1445
  const approvalQuery = useQuery({
1398
1446
  ...params.query,
1399
- queryKey: symmKeys.approval(owner, resolvedSpender, chainId),
1447
+ queryKey: symmKeys.approval(owner, resolvedSpender, chainId, resolvedToken),
1400
1448
  queryFn: async () => {
1401
1449
  const [allowanceVal, balanceVal] = await Promise.all([
1402
1450
  getAllowance(publicClient, resolvedToken, owner, resolvedSpender),
@@ -1414,7 +1462,7 @@ function useSymmApproval(params) {
1414
1462
  },
1415
1463
  onSuccess: () => {
1416
1464
  queryClient.invalidateQueries({
1417
- queryKey: symmKeys.approval(owner, resolvedSpender, chainId)
1465
+ queryKey: symmKeys.approval(owner, resolvedSpender, chainId, resolvedToken)
1418
1466
  });
1419
1467
  }
1420
1468
  });
@@ -1439,7 +1487,7 @@ function useSymmCancelClose() {
1439
1487
  if (!symmCoreClient) {
1440
1488
  throw new Error("symm-core client not available");
1441
1489
  }
1442
- const resolvedAuthToken = authToken ?? ctxAuthToken ?? (accountAddress ? await refreshAuth(accountAddress) : null);
1490
+ const resolvedAuthToken = authToken ?? (accountAddress ? useSymmAuthStore.getState().getToken(accountAddress, chainId) : null) ?? ctxAuthToken ?? (accountAddress ? await refreshAuth(accountAddress) : null);
1443
1491
  if (!resolvedAuthToken) {
1444
1492
  throw new Error("auth token is required to cancel a pending close");
1445
1493
  }
@@ -24549,7 +24597,7 @@ function useSymmAccountData(params) {
24549
24597
  const internalEnabled = !!symmCoreClient && !!address;
24550
24598
  const query = useQuery({
24551
24599
  ...params.query,
24552
- queryKey: symmKeys.accountData(address, chainId),
24600
+ queryKey: symmKeys.accountData(address, chainId, upnl),
24553
24601
  queryFn: () => symmCoreClient.accounts.getData({
24554
24602
  address,
24555
24603
  chainId,
@@ -24639,13 +24687,17 @@ function useSymmTrade() {
24639
24687
  }
24640
24688
  function useSymmPositions(params) {
24641
24689
  const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
24642
- const { accountAddress, mainAddress, address } = params;
24643
- const resolvedAddress = address ?? mainAddress;
24690
+ const { accountAddress, address } = params;
24691
+ const resolvedAddress = accountAddress ? void 0 : address;
24644
24692
  const chainId = params.chainId ?? ctxChainId;
24645
24693
  const internalEnabled = !!symmCoreClient && !!(accountAddress || resolvedAddress);
24646
24694
  const query = useQuery({
24647
24695
  ...params.query,
24648
- queryKey: symmKeys.positions(accountAddress ?? resolvedAddress, chainId),
24696
+ queryKey: symmKeys.positions({
24697
+ accountAddress,
24698
+ address: resolvedAddress,
24699
+ chainId
24700
+ }),
24649
24701
  queryFn: () => symmCoreClient.positions.getOpen({
24650
24702
  accountAddress,
24651
24703
  address: resolvedAddress,
@@ -24661,15 +24713,19 @@ function useSymmPositions(params) {
24661
24713
  }
24662
24714
  function useSymmOpenOrders(params) {
24663
24715
  const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
24664
- const { accountAddress, mainAddress } = params;
24716
+ const { accountAddress, address } = params;
24717
+ const resolvedAddress = accountAddress ? void 0 : address;
24665
24718
  const chainId = params.chainId ?? ctxChainId;
24666
- const internalEnabled = !!symmCoreClient && !!(accountAddress || mainAddress);
24719
+ const internalEnabled = !!symmCoreClient && !!(accountAddress || resolvedAddress);
24667
24720
  const query = useQuery({
24668
24721
  ...params.query,
24669
- queryKey: symmKeys.openOrders(accountAddress ?? mainAddress, chainId),
24722
+ queryKey: symmKeys.openOrders({
24723
+ accountAddress,
24724
+ address: resolvedAddress,
24725
+ chainId
24726
+ }),
24670
24727
  queryFn: () => symmCoreClient.orders.list({
24671
- address: accountAddress,
24672
- mainAddress,
24728
+ address: accountAddress ?? resolvedAddress,
24673
24729
  chainId
24674
24730
  }),
24675
24731
  enabled: internalEnabled && (params.query?.enabled ?? true)
@@ -24682,17 +24738,25 @@ function useSymmOpenOrders(params) {
24682
24738
  }
24683
24739
  function useSymmTradeHistory(params) {
24684
24740
  const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
24685
- const { accountAddress, mainAddress } = params;
24741
+ const { accountAddress, address } = params;
24742
+ const resolvedAddress = accountAddress ? void 0 : address;
24686
24743
  const chainId = params.chainId ?? ctxChainId;
24687
- const internalEnabled = !!symmCoreClient && !!(accountAddress || mainAddress);
24744
+ const internalEnabled = !!symmCoreClient && !!(accountAddress || resolvedAddress);
24688
24745
  const query = useQuery({
24689
24746
  ...params.query,
24690
- queryKey: symmKeys.tradeHistory(accountAddress ?? mainAddress, chainId),
24691
- queryFn: () => symmCoreClient.positions.getTradeHistory({
24747
+ queryKey: symmKeys.tradeHistory({
24692
24748
  accountAddress,
24693
- mainAddress,
24749
+ address: resolvedAddress,
24694
24750
  chainId
24695
24751
  }),
24752
+ queryFn: () => {
24753
+ const request = {
24754
+ accountAddress,
24755
+ address: resolvedAddress,
24756
+ chainId
24757
+ };
24758
+ return symmCoreClient.positions.getTradeHistory(request);
24759
+ },
24696
24760
  enabled: internalEnabled && (params.query?.enabled ?? true)
24697
24761
  });
24698
24762
  return {
@@ -24728,12 +24792,12 @@ function useSymmTpsl() {
24728
24792
  }
24729
24793
  function useSymmTpslOrders(params) {
24730
24794
  const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
24731
- const { accountAddress, mainAddress, positionId, type, status } = params;
24795
+ const { accountAddress, address, positionId, type, status } = params;
24796
+ const resolvedAddress = accountAddress ? void 0 : address;
24732
24797
  const chainId = params.chainId ?? ctxChainId;
24733
- const internalEnabled = !!symmCoreClient && !!(accountAddress || mainAddress || positionId);
24798
+ const internalEnabled = !!symmCoreClient && !!(accountAddress || resolvedAddress || positionId);
24734
24799
  const request = {
24735
- address: accountAddress,
24736
- mainAddress,
24800
+ address: accountAddress ?? resolvedAddress,
24737
24801
  positionId,
24738
24802
  type,
24739
24803
  status,
@@ -24743,7 +24807,7 @@ function useSymmTpslOrders(params) {
24743
24807
  ...params.query,
24744
24808
  queryKey: symmKeys.tpslOrdersList({
24745
24809
  accountAddress,
24746
- mainAddress,
24810
+ address: resolvedAddress,
24747
24811
  positionId,
24748
24812
  type,
24749
24813
  status,
@@ -24762,15 +24826,15 @@ function useSymmTpslOrders(params) {
24762
24826
  function useSymmTwap(params) {
24763
24827
  const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
24764
24828
  const queryClient = useQueryClient();
24765
- const { accountAddress, mainAddress } = params;
24829
+ const { accountAddress, address } = params;
24830
+ const resolvedAddress = accountAddress ? void 0 : address;
24766
24831
  const chainId = params.chainId ?? ctxChainId;
24767
- const internalEnabled = !!symmCoreClient && !!(accountAddress || mainAddress);
24832
+ const internalEnabled = !!symmCoreClient && !!(accountAddress || resolvedAddress);
24768
24833
  const query = useQuery({
24769
24834
  ...params.query,
24770
- queryKey: symmKeys.twapOrders(accountAddress ?? mainAddress, chainId),
24835
+ queryKey: symmKeys.twapOrders(accountAddress ?? resolvedAddress, chainId),
24771
24836
  queryFn: () => symmCoreClient.orders.getTwapOrders({
24772
- address: accountAddress,
24773
- mainAddress,
24837
+ address: accountAddress ?? resolvedAddress,
24774
24838
  chainId
24775
24839
  }),
24776
24840
  enabled: internalEnabled && (params.query?.enabled ?? true)
@@ -24839,12 +24903,12 @@ function useSymmTriggerConfig(params) {
24839
24903
  }
24840
24904
  function useSymmTriggerOrders(params) {
24841
24905
  const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
24842
- const { accountAddress, mainAddress, status, limit, offset } = params;
24906
+ const { accountAddress, address, status, limit, offset } = params;
24907
+ const resolvedAddress = accountAddress ? void 0 : address;
24843
24908
  const chainId = params.chainId ?? ctxChainId;
24844
- const internalEnabled = !!symmCoreClient && !!(accountAddress || mainAddress);
24909
+ const internalEnabled = !!symmCoreClient && !!(accountAddress || resolvedAddress);
24845
24910
  const request = {
24846
- address: accountAddress,
24847
- mainAddress,
24911
+ address: accountAddress ?? resolvedAddress,
24848
24912
  chainId,
24849
24913
  status,
24850
24914
  limit,
@@ -24854,7 +24918,7 @@ function useSymmTriggerOrders(params) {
24854
24918
  ...params.query,
24855
24919
  queryKey: symmKeys.triggerOrders({
24856
24920
  accountAddress,
24857
- mainAddress,
24921
+ address: resolvedAddress,
24858
24922
  chainId,
24859
24923
  status,
24860
24924
  limit,
@@ -25071,17 +25135,25 @@ function useSymmFundingPayments(params) {
25071
25135
  }
25072
25136
  function useSymmPortfolio(params) {
25073
25137
  const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
25074
- const { accountAddress, mainAddress } = params;
25138
+ const { accountAddress, address } = params;
25139
+ const resolvedAddress = accountAddress ? void 0 : address;
25075
25140
  const chainId = params.chainId ?? ctxChainId;
25076
- const internalEnabled = !!symmCoreClient && !!(accountAddress || mainAddress);
25141
+ const internalEnabled = !!symmCoreClient && !!(accountAddress || resolvedAddress);
25077
25142
  const query = useQuery({
25078
25143
  ...params.query,
25079
- queryKey: symmKeys.portfolio(accountAddress ?? mainAddress, chainId),
25080
- queryFn: () => symmCoreClient.portfolio.getMetrics({
25144
+ queryKey: symmKeys.portfolio({
25081
25145
  accountAddress,
25082
- mainAddress,
25146
+ address: resolvedAddress,
25083
25147
  chainId
25084
25148
  }),
25149
+ queryFn: () => {
25150
+ const request = {
25151
+ accountAddress,
25152
+ address: resolvedAddress,
25153
+ chainId
25154
+ };
25155
+ return symmCoreClient.portfolio.getMetrics(request);
25156
+ },
25085
25157
  enabled: internalEnabled && (params.query?.enabled ?? true)
25086
25158
  });
25087
25159
  return {
@@ -25176,7 +25248,7 @@ function useSymmPendingInstantOpens(params) {
25176
25248
  ...params.query,
25177
25249
  queryKey: symmKeys.pendingInstantOpens(accountAddress, chainId),
25178
25250
  queryFn: async () => {
25179
- const authToken = providedAuthToken ?? ctxAuthToken ?? await refreshAuth(accountAddress);
25251
+ const authToken = providedAuthToken ?? useSymmAuthStore.getState().getToken(accountAddress, chainId) ?? ctxAuthToken ?? await refreshAuth(accountAddress);
25180
25252
  if (!authToken) {
25181
25253
  throw new Error("failed to acquire auth token for pending instant opens");
25182
25254
  }
@@ -25688,6 +25760,74 @@ function getBinanceWsManager() {
25688
25760
  return _instance;
25689
25761
  }
25690
25762
 
25763
+ // src/react/stores/use-binance-mark-price-store.ts
25764
+ var refCounts = /* @__PURE__ */ new Map();
25765
+ var streamUnsubs = /* @__PURE__ */ new Map();
25766
+ var streamSymbols = /* @__PURE__ */ new Map();
25767
+ function normalizeBinanceSymbol(symbol) {
25768
+ return symbol.toUpperCase().trim();
25769
+ }
25770
+ function getNextRefCount(binanceSymbol) {
25771
+ return (refCounts.get(binanceSymbol) ?? 0) + 1;
25772
+ }
25773
+ function getPrevRefCount(binanceSymbol) {
25774
+ return Math.max(0, (refCounts.get(binanceSymbol) ?? 0) - 1);
25775
+ }
25776
+ var useBinanceMarkPriceStore = create((set) => ({
25777
+ markPrices: {},
25778
+ subscribeSymbol: (symmSymbol, rawBinanceSymbol) => {
25779
+ const binanceSymbol = normalizeBinanceSymbol(rawBinanceSymbol);
25780
+ const nextRefCount = getNextRefCount(binanceSymbol);
25781
+ refCounts.set(binanceSymbol, nextRefCount);
25782
+ const symbols = streamSymbols.get(binanceSymbol) ?? /* @__PURE__ */ new Set();
25783
+ symbols.add(symmSymbol);
25784
+ streamSymbols.set(binanceSymbol, symbols);
25785
+ if (nextRefCount === 1) {
25786
+ const wsManager = getBinanceWsManager();
25787
+ const unsubscribe = wsManager.subscribeMarkPrice(binanceSymbol, (data) => {
25788
+ const canonicalSymbol = normalizeBinanceSymbol(data.symbol);
25789
+ const mappedSymbols = streamSymbols.get(canonicalSymbol);
25790
+ if (!mappedSymbols || mappedSymbols.size === 0) return;
25791
+ set((state) => {
25792
+ const nextMarkPrices = { ...state.markPrices };
25793
+ mappedSymbols.forEach((mappedSymbol) => {
25794
+ nextMarkPrices[mappedSymbol] = data.markPrice;
25795
+ });
25796
+ return { markPrices: nextMarkPrices };
25797
+ });
25798
+ });
25799
+ streamUnsubs.set(binanceSymbol, unsubscribe);
25800
+ }
25801
+ },
25802
+ unsubscribeSymbol: (symmSymbol, rawBinanceSymbol) => {
25803
+ const binanceSymbol = normalizeBinanceSymbol(rawBinanceSymbol);
25804
+ const symbols = streamSymbols.get(binanceSymbol);
25805
+ if (symbols) {
25806
+ symbols.delete(symmSymbol);
25807
+ if (symbols.size === 0) {
25808
+ streamSymbols.delete(binanceSymbol);
25809
+ } else {
25810
+ streamSymbols.set(binanceSymbol, symbols);
25811
+ }
25812
+ }
25813
+ const nextRefCount = getPrevRefCount(binanceSymbol);
25814
+ if (nextRefCount === 0) {
25815
+ const unsubscribe = streamUnsubs.get(binanceSymbol);
25816
+ if (unsubscribe) unsubscribe();
25817
+ streamUnsubs.delete(binanceSymbol);
25818
+ refCounts.delete(binanceSymbol);
25819
+ } else {
25820
+ refCounts.set(binanceSymbol, nextRefCount);
25821
+ }
25822
+ set((state) => {
25823
+ if (state.markPrices[symmSymbol] == null) return state;
25824
+ const nextMarkPrices = { ...state.markPrices };
25825
+ delete nextMarkPrices[symmSymbol];
25826
+ return { markPrices: nextMarkPrices };
25827
+ });
25828
+ }
25829
+ }));
25830
+
25691
25831
  // src/react/hooks/use-symm-token-selection-metadata.ts
25692
25832
  async function fetchTickerSnapshot(symbol) {
25693
25833
  const resolution = resolveBinanceSymbol(symbol);
@@ -25729,9 +25869,9 @@ function useSymmTokenSelectionMetadata(selection, options = {}) {
25729
25869
  ),
25730
25870
  [selectedSymbols]
25731
25871
  );
25732
- const [liveMarkPrices, setLiveMarkPrices] = useState(
25733
- {}
25734
- );
25872
+ const liveMarkPrices = useBinanceMarkPriceStore((state) => state.markPrices);
25873
+ const subscribeSymbol = useBinanceMarkPriceStore((state) => state.subscribeSymbol);
25874
+ const unsubscribeSymbol = useBinanceMarkPriceStore((state) => state.unsubscribeSymbol);
25735
25875
  const query = useQuery({
25736
25876
  queryKey: ["symm", "chart-metadata", symbolsKey],
25737
25877
  queryFn: async () => {
@@ -25759,36 +25899,25 @@ function useSymmTokenSelectionMetadata(selection, options = {}) {
25759
25899
  });
25760
25900
  useEffect(() => {
25761
25901
  if (!enabled || isUnsupported || selectedSymbols.length === 0) {
25762
- setLiveMarkPrices({});
25763
25902
  return;
25764
25903
  }
25765
- setLiveMarkPrices((current) => {
25766
- const next = {};
25767
- for (const symbol of selectedSymbols) {
25768
- if (current[symbol] != null) {
25769
- next[symbol] = current[symbol];
25770
- }
25771
- }
25772
- return next;
25773
- });
25774
- const wsManager = getBinanceWsManager();
25775
- const unsubscribes = Array.from(symbolToBinanceMap.entries()).map(
25776
- ([symbol, binanceSymbol]) => wsManager.subscribeMarkPrice(binanceSymbol, (data) => {
25777
- setLiveMarkPrices((current) => {
25778
- if (current[symbol] === data.markPrice) return current;
25779
- return {
25780
- ...current,
25781
- [symbol]: data.markPrice
25782
- };
25783
- });
25784
- })
25904
+ const symbolEntries = Array.from(symbolToBinanceMap.entries());
25905
+ symbolEntries.forEach(
25906
+ ([symbol, binanceSymbol]) => subscribeSymbol(symbol, binanceSymbol)
25785
25907
  );
25786
25908
  return () => {
25787
- for (const unsubscribe of unsubscribes) {
25788
- unsubscribe();
25789
- }
25909
+ symbolEntries.forEach(
25910
+ ([symbol, binanceSymbol]) => unsubscribeSymbol(symbol, binanceSymbol)
25911
+ );
25790
25912
  };
25791
- }, [enabled, isUnsupported, selectedSymbols, symbolToBinanceMap]);
25913
+ }, [
25914
+ enabled,
25915
+ isUnsupported,
25916
+ selectedSymbols.length,
25917
+ symbolToBinanceMap,
25918
+ subscribeSymbol,
25919
+ unsubscribeSymbol
25920
+ ]);
25792
25921
  return useMemo(() => {
25793
25922
  const tickerSnapshots = query.data?.tickerSnapshots ?? {};
25794
25923
  const longMeta = {};
@@ -26228,6 +26357,6 @@ function getSymmErrorMessage(error) {
26228
26357
  return "An unexpected error occurred.";
26229
26358
  }
26230
26359
 
26231
- export { SymmProvider, getSymmErrorMessage, symmKeys, useSymmAccountData, useSymmAccountSummary, useSymmAccounts, useSymmAccountsApi, useSymmAccountsLength, useSymmAccountsWithPositions, useSymmApproval, useSymmAuth, useSymmAvailableMargin, useSymmBalances, useSymmCancelClose, useSymmChartCandles, useSymmChartSelection, useSymmCloseOrder, useSymmCollateral, useSymmContext, useSymmCoreClient, useSymmDelegation, useSymmDeposit, useSymmFunding, useSymmFundingHistory, useSymmFundingPayments, useSymmHedgerMarketById, useSymmHedgerMarketBySymbol, useSymmHedgerMarkets, useSymmInstantTrade, useSymmLockedParams, useSymmMarkets, useSymmNotifications, useSymmOpenOrders, useSymmPendingIds, useSymmPendingInstantOpens, useSymmPerformanceOverlays, useSymmPortfolio, useSymmPositions, useSymmSignature, useSymmTokenSelectionMetadata, useSymmTpsl, useSymmTpslOrders, useSymmTrade, useSymmTradeHistory, useSymmTriggerConfig, useSymmTriggerOrders, useSymmTwap, useSymmTwapOrder, useSymmWithdraw, useSymmWs };
26360
+ export { SymmProvider, getSymmErrorMessage, symmKeys, useBinanceMarkPriceStore, useSymmAccountData, useSymmAccountSummary, useSymmAccounts, useSymmAccountsApi, useSymmAccountsLength, useSymmAccountsWithPositions, useSymmApproval, useSymmAuth, useSymmAuthStore, useSymmAvailableMargin, useSymmBalances, useSymmCancelClose, useSymmChartCandles, useSymmChartSelection, useSymmCloseOrder, useSymmCollateral, useSymmContext, useSymmCoreClient, useSymmDelegation, useSymmDeposit, useSymmFunding, useSymmFundingHistory, useSymmFundingPayments, useSymmHedgerMarketById, useSymmHedgerMarketBySymbol, useSymmHedgerMarkets, useSymmInstantTrade, useSymmLockedParams, useSymmMarkets, useSymmNotifications, useSymmOpenOrders, useSymmPendingIds, useSymmPendingInstantOpens, useSymmPerformanceOverlays, useSymmPortfolio, useSymmPositions, useSymmSignature, useSymmTokenSelectionMetadata, useSymmTpsl, useSymmTpslOrders, useSymmTrade, useSymmTradeHistory, useSymmTriggerConfig, useSymmTriggerOrders, useSymmTwap, useSymmTwapOrder, useSymmWithdraw, useSymmWs, useSymmWsStore };
26232
26361
  //# sourceMappingURL=index.mjs.map
26233
26362
  //# sourceMappingURL=index.mjs.map