@pear-protocol/symmio-client 0.1.6 → 0.1.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.
@@ -855,7 +855,7 @@ interface SymmPerformanceOverlay {
855
855
  */
856
856
  declare function useSymmPerformanceOverlays(selection: SymmChartSelection): {
857
857
  overlays: SymmPerformanceOverlay[];
858
- generateOverlaySymbols: () => string[];
858
+ overlaySymbols: string[];
859
859
  };
860
860
 
861
861
  declare const symmKeys: {
@@ -878,6 +878,7 @@ declare const symmKeys: {
878
878
  unreadCount: (address?: Address, chainId?: number) => readonly ["symm", "unreadCount", `0x${string}` | undefined, number | undefined];
879
879
  availableMargin: (address?: Address, chainId?: number) => readonly ["symm", "availableMargin", `0x${string}` | undefined, number | undefined];
880
880
  delegation: (account?: Address, target?: Address, selectors?: readonly Hex[], chainId?: number) => readonly ["symm", "delegation", `0x${string}` | undefined, `0x${string}` | undefined, readonly `0x${string}`[] | undefined, number | undefined];
881
+ chartMetadata: (symbolsKey: string, positionKey: string) => readonly ["symm", "chartMetadata", string, string];
881
882
  };
882
883
 
883
884
  declare function getSymmErrorMessage(error: unknown): string;
@@ -855,7 +855,7 @@ interface SymmPerformanceOverlay {
855
855
  */
856
856
  declare function useSymmPerformanceOverlays(selection: SymmChartSelection): {
857
857
  overlays: SymmPerformanceOverlay[];
858
- generateOverlaySymbols: () => string[];
858
+ overlaySymbols: string[];
859
859
  };
860
860
 
861
861
  declare const symmKeys: {
@@ -878,6 +878,7 @@ declare const symmKeys: {
878
878
  unreadCount: (address?: Address, chainId?: number) => readonly ["symm", "unreadCount", `0x${string}` | undefined, number | undefined];
879
879
  availableMargin: (address?: Address, chainId?: number) => readonly ["symm", "availableMargin", `0x${string}` | undefined, number | undefined];
880
880
  delegation: (account?: Address, target?: Address, selectors?: readonly Hex[], chainId?: number) => readonly ["symm", "delegation", `0x${string}` | undefined, `0x${string}` | undefined, readonly `0x${string}`[] | undefined, number | undefined];
881
+ chartMetadata: (symbolsKey: string, positionKey: string) => readonly ["symm", "chartMetadata", string, string];
881
882
  };
882
883
 
883
884
  declare function getSymmErrorMessage(error: unknown): string;
@@ -24405,8 +24405,8 @@ function SymmProvider({
24405
24405
  setAccessToken(null);
24406
24406
  return;
24407
24407
  }
24408
- setAccessToken(null);
24409
24408
  if (previousAddress && (addressChanged || chainChanged)) {
24409
+ setAccessToken(null);
24410
24410
  clearCachedToken(previousAddress, previousChainId);
24411
24411
  }
24412
24412
  }, [address, walletClient, chainId]);
@@ -24489,7 +24489,8 @@ var symmKeys = {
24489
24489
  notifications: (address, chainId) => ["symm", "notifications", address, chainId],
24490
24490
  unreadCount: (address, chainId) => ["symm", "unreadCount", address, chainId],
24491
24491
  availableMargin: (address, chainId) => ["symm", "availableMargin", address, chainId],
24492
- delegation: (account, target, selectors, chainId) => ["symm", "delegation", account, target, selectors, chainId]
24492
+ delegation: (account, target, selectors, chainId) => ["symm", "delegation", account, target, selectors, chainId],
24493
+ chartMetadata: (symbolsKey, positionKey) => ["symm", "chartMetadata", symbolsKey, positionKey]
24493
24494
  };
24494
24495
 
24495
24496
  // src/react/hooks/use-symm-delegation.ts
@@ -24636,6 +24637,7 @@ function useSymmInstantTrade(params) {
24636
24637
  execute
24637
24638
  };
24638
24639
  }
24640
+ var EMPTY_ACCOUNTS = [];
24639
24641
  function useSymmAccounts(userAddress) {
24640
24642
  const { symmioClient } = useSymmContext();
24641
24643
  const queryClient = reactQuery.useQueryClient();
@@ -24666,7 +24668,7 @@ function useSymmAccounts(userAddress) {
24666
24668
  }
24667
24669
  });
24668
24670
  return {
24669
- accounts: accountsQuery.data ?? [],
24671
+ accounts: accountsQuery.data ?? EMPTY_ACCOUNTS,
24670
24672
  count: accountsQuery.data?.length ?? 0,
24671
24673
  isLoading: accountsQuery.isLoading,
24672
24674
  error: accountsQuery.error,
@@ -24681,21 +24683,23 @@ function useSymmApproval(params) {
24681
24683
  const { owner, amount, spender, collateralToken } = params;
24682
24684
  const resolvedSpender = spender ?? symmioClient?.addresses.multiAccount;
24683
24685
  const resolvedToken = collateralToken ?? symmioClient?.addresses.collateral;
24686
+ const selectWithAmount = react.useCallback(
24687
+ (data) => ({
24688
+ ...data,
24689
+ state: data.allowance >= amount ? "APPROVED" /* APPROVED */ : "NOT_APPROVED" /* NOT_APPROVED */
24690
+ }),
24691
+ [amount]
24692
+ );
24684
24693
  const approvalQuery = reactQuery.useQuery({
24685
24694
  queryKey: symmKeys.approval(owner, resolvedSpender),
24686
24695
  queryFn: async () => {
24687
- const [state, allowance, balance] = await Promise.all([
24688
- symmioClient.approval.getState(
24689
- resolvedToken,
24690
- owner,
24691
- resolvedSpender,
24692
- amount
24693
- ),
24696
+ const [allowance, balance] = await Promise.all([
24694
24697
  symmioClient.approval.getAllowance(resolvedToken, owner, resolvedSpender),
24695
24698
  symmioClient.approval.getBalance(resolvedToken, owner)
24696
24699
  ]);
24697
- return { state, allowance, balance };
24700
+ return { allowance, balance };
24698
24701
  },
24702
+ select: selectWithAmount,
24699
24703
  enabled: !!symmioClient && !!owner && !!resolvedSpender && !!resolvedToken
24700
24704
  });
24701
24705
  const approve2 = reactQuery.useMutation({
@@ -24839,18 +24843,19 @@ function useSymmSignature(userAddress) {
24839
24843
  function useSymmAvailableMargin(params) {
24840
24844
  const { symmioClient } = useSymmContext();
24841
24845
  const { accountAddress, upnl } = params;
24846
+ const resolvedUpnl = upnl ?? 0n;
24847
+ const selectWithUpnl = react.useCallback(
24848
+ (stats) => ({
24849
+ ...stats,
24850
+ upnl: resolvedUpnl,
24851
+ availableForOrder: calculateAvailableForOrder(stats, resolvedUpnl)
24852
+ }),
24853
+ [resolvedUpnl]
24854
+ );
24842
24855
  const query = reactQuery.useQuery({
24843
24856
  queryKey: symmKeys.availableMargin(accountAddress, symmioClient?.chainId),
24844
- queryFn: async () => {
24845
- const stats = await symmioClient.stats.getPartyAStats(accountAddress);
24846
- const resolvedUpnl = upnl ?? 0n;
24847
- const availableForOrder = calculateAvailableForOrder(stats, resolvedUpnl);
24848
- return {
24849
- ...stats,
24850
- upnl: resolvedUpnl,
24851
- availableForOrder
24852
- };
24853
- },
24857
+ queryFn: () => symmioClient.stats.getPartyAStats(accountAddress),
24858
+ select: selectWithUpnl,
24854
24859
  enabled: !!symmioClient && !!accountAddress,
24855
24860
  staleTime: 1e4
24856
24861
  });
@@ -25070,37 +25075,37 @@ function useSymmMarkets(params) {
25070
25075
  refetch: query.refetch
25071
25076
  };
25072
25077
  }
25078
+ var EMPTY_MARKETS = [];
25079
+ var EMPTY_SYMBOLS = [];
25080
+ var EMPTY_MAP_BY_ID = /* @__PURE__ */ new Map();
25081
+ var EMPTY_MAP_BY_SYMBOL = /* @__PURE__ */ new Map();
25073
25082
  function useSymmHedgerMarkets(params) {
25074
25083
  const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
25075
25084
  const chainId = params?.chainId ?? ctxChainId;
25076
25085
  const searchText = params?.searchText?.trim();
25077
25086
  const isEnabled = params?.enabled ?? true;
25087
+ const { enabled: _, ...restParams } = params ?? {};
25078
25088
  const request = {
25079
- ...params,
25089
+ ...restParams,
25080
25090
  chainId,
25081
25091
  searchText: searchText || void 0
25082
25092
  };
25083
25093
  const query = reactQuery.useQuery({
25084
25094
  queryKey: symmKeys.hedgerMarkets(request),
25085
- queryFn: async () => {
25086
- const { enabled: _enabled, ...queryRequest } = request;
25087
- return symmCoreClient.markets.listSymmHedger(queryRequest);
25088
- },
25095
+ queryFn: () => symmCoreClient.markets.listSymmHedger(request),
25089
25096
  enabled: !!symmCoreClient && isEnabled,
25090
25097
  staleTime: 3e4
25091
25098
  });
25092
25099
  const data = query.data ?? null;
25093
- const emptyMap = /* @__PURE__ */ new Map();
25094
- const emptySymbolMap = /* @__PURE__ */ new Map();
25095
25100
  return {
25096
25101
  data,
25097
- markets: data?.markets ?? [],
25098
- rawMarkets: data?.rawMarkets ?? [],
25099
- filteredMarkets: data?.filteredMarkets ?? [],
25100
- allSymbols: data?.allSymbols ?? [],
25101
- filteredSymbols: data?.filteredSymbols ?? [],
25102
- marketsById: data?.marketsById ?? emptyMap,
25103
- marketsBySymbol: data?.marketsBySymbol ?? emptySymbolMap,
25102
+ markets: data?.markets ?? EMPTY_MARKETS,
25103
+ rawMarkets: data?.rawMarkets ?? EMPTY_MARKETS,
25104
+ filteredMarkets: data?.filteredMarkets ?? EMPTY_MARKETS,
25105
+ allSymbols: data?.allSymbols ?? EMPTY_SYMBOLS,
25106
+ filteredSymbols: data?.filteredSymbols ?? EMPTY_SYMBOLS,
25107
+ marketsById: data?.marketsById ?? EMPTY_MAP_BY_ID,
25108
+ marketsBySymbol: data?.marketsBySymbol ?? EMPTY_MAP_BY_SYMBOL,
25104
25109
  category: data?.category ?? params?.category ?? "all",
25105
25110
  resolvedSearchText: data?.searchText ?? searchText ?? "",
25106
25111
  isLoading: query.isLoading,
@@ -25192,13 +25197,15 @@ function useSymmNotifications(params) {
25192
25197
  refetch: notificationsQuery.refetch
25193
25198
  };
25194
25199
  }
25200
+ function asUnsubscribeFn(value) {
25201
+ return typeof value === "function" ? value : null;
25202
+ }
25195
25203
  function useSymmWs(params) {
25196
25204
  const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
25197
25205
  const queryClient = reactQuery.useQueryClient();
25198
25206
  const { accountAddress } = params;
25199
25207
  const chainId = params.chainId ?? ctxChainId;
25200
25208
  const [isConnected, setIsConnected] = react.useState(false);
25201
- const cleanupRef = react.useRef([]);
25202
25209
  react.useEffect(() => {
25203
25210
  if (!symmCoreClient || !accountAddress) {
25204
25211
  setIsConnected(false);
@@ -25206,61 +25213,75 @@ function useSymmWs(params) {
25206
25213
  }
25207
25214
  const ws = symmCoreClient.ws;
25208
25215
  const addr = accountAddress;
25216
+ const unsubscribers = [];
25209
25217
  const removeOnConnect = ws.onConnect(() => setIsConnected(true));
25210
25218
  const removeOnDisconnect = ws.onDisconnect(() => setIsConnected(false));
25211
- ws.subscribeToPositions(addr, chainId, () => {
25219
+ unsubscribers.push(removeOnConnect, removeOnDisconnect);
25220
+ const positionsUnsub = asUnsubscribeFn(ws.subscribeToPositions(addr, chainId, () => {
25212
25221
  queryClient.invalidateQueries({
25213
25222
  queryKey: symmKeys.positions(accountAddress, chainId)
25214
25223
  });
25215
- });
25216
- ws.subscribeToOpenOrders(addr, chainId, () => {
25224
+ }));
25225
+ if (positionsUnsub) unsubscribers.push(positionsUnsub);
25226
+ const openOrdersUnsub = asUnsubscribeFn(ws.subscribeToOpenOrders(addr, chainId, () => {
25217
25227
  queryClient.invalidateQueries({
25218
25228
  queryKey: symmKeys.openOrders(accountAddress, chainId)
25219
25229
  });
25220
- });
25221
- ws.subscribeToTrades(addr, chainId, () => {
25230
+ }));
25231
+ if (openOrdersUnsub) unsubscribers.push(openOrdersUnsub);
25232
+ const tradesUnsub = asUnsubscribeFn(ws.subscribeToTrades(addr, chainId, () => {
25222
25233
  queryClient.invalidateQueries({
25223
25234
  queryKey: symmKeys.tradeHistory(accountAddress, chainId)
25224
25235
  });
25225
- });
25226
- ws.subscribeToAccountSummary(addr, chainId, () => {
25236
+ }));
25237
+ if (tradesUnsub) unsubscribers.push(tradesUnsub);
25238
+ const accountSummaryUnsub = asUnsubscribeFn(ws.subscribeToAccountSummary(addr, chainId, () => {
25227
25239
  queryClient.invalidateQueries({
25228
25240
  queryKey: symmKeys.balances(accountAddress, chainId)
25229
25241
  });
25230
25242
  queryClient.invalidateQueries({
25231
25243
  queryKey: symmKeys.accountSummary(accountAddress, chainId)
25232
25244
  });
25233
- });
25234
- ws.subscribeToNotifications(addr, chainId, () => {
25245
+ }));
25246
+ if (accountSummaryUnsub) unsubscribers.push(accountSummaryUnsub);
25247
+ const notificationsUnsub = asUnsubscribeFn(ws.subscribeToNotifications(addr, chainId, () => {
25235
25248
  queryClient.invalidateQueries({
25236
25249
  queryKey: symmKeys.notifications(accountAddress, chainId)
25237
25250
  });
25238
25251
  queryClient.invalidateQueries({
25239
25252
  queryKey: symmKeys.unreadCount(accountAddress, chainId)
25240
25253
  });
25241
- });
25242
- ws.subscribeToTpsl(addr, chainId, () => {
25254
+ }));
25255
+ if (notificationsUnsub) unsubscribers.push(notificationsUnsub);
25256
+ const tpslUnsub = asUnsubscribeFn(ws.subscribeToTpsl(addr, chainId, () => {
25243
25257
  queryClient.invalidateQueries({
25244
25258
  queryKey: symmKeys.tpslOrders(accountAddress, chainId)
25245
25259
  });
25246
- });
25247
- ws.subscribeToTwapOrders(addr, chainId, () => {
25260
+ }));
25261
+ if (tpslUnsub) unsubscribers.push(tpslUnsub);
25262
+ const twapUnsub = asUnsubscribeFn(ws.subscribeToTwapOrders(addr, chainId, () => {
25248
25263
  queryClient.invalidateQueries({
25249
25264
  queryKey: symmKeys.twapOrders(accountAddress, chainId)
25250
25265
  });
25251
- });
25252
- ws.subscribeToExecutions(addr, chainId, () => {
25266
+ }));
25267
+ if (twapUnsub) unsubscribers.push(twapUnsub);
25268
+ const executionsUnsub = asUnsubscribeFn(ws.subscribeToExecutions(addr, chainId, () => {
25253
25269
  queryClient.invalidateQueries({
25254
25270
  queryKey: symmKeys.positions(accountAddress, chainId)
25255
25271
  });
25256
25272
  queryClient.invalidateQueries({
25257
25273
  queryKey: symmKeys.portfolio(accountAddress, chainId)
25258
25274
  });
25259
- });
25260
- cleanupRef.current = [removeOnConnect, removeOnDisconnect];
25275
+ }));
25276
+ if (executionsUnsub) unsubscribers.push(executionsUnsub);
25261
25277
  return () => {
25262
- cleanupRef.current.forEach((fn) => fn());
25263
- ws.unsubscribeAll();
25278
+ if (unsubscribers.length > 2) {
25279
+ unsubscribers.forEach((unsubscribe) => unsubscribe());
25280
+ } else {
25281
+ removeOnConnect();
25282
+ removeOnDisconnect();
25283
+ ws.unsubscribeAll();
25284
+ }
25264
25285
  };
25265
25286
  }, [symmCoreClient, accountAddress, chainId, queryClient]);
25266
25287
  return { isConnected };
@@ -25587,8 +25608,12 @@ function useSymmTokenSelectionMetadata(selection) {
25587
25608
  const isUnsupported = unsupportedSymbols.length > 0;
25588
25609
  const unavailableReason = isUnsupported ? `Binance market data is unavailable for ${unsupportedSymbols.join(", ")}.` : null;
25589
25610
  const symbolsKey = [...selectedSymbols].sort().join(",");
25611
+ const positionKey = [
25612
+ longTokens.map((token) => `${token.symbol}:${token.weight}`).join("|"),
25613
+ shortTokens.map((token) => `${token.symbol}:${token.weight}`).join("|")
25614
+ ].join("::");
25590
25615
  const query = reactQuery.useQuery({
25591
- queryKey: ["symm", "chart-metadata", symbolsKey],
25616
+ queryKey: symmKeys.chartMetadata(symbolsKey, positionKey),
25592
25617
  queryFn: async () => {
25593
25618
  const allSymbols = [
25594
25619
  ...longTokens.map((t) => ({ symbol: t.symbol, side: "long" })),
@@ -26023,7 +26048,6 @@ function useSymmChartCandles(selection) {
26023
26048
  low: longValues.l * shortValues.l,
26024
26049
  close: longValues.c * shortValues.c
26025
26050
  };
26026
- if (!bar) return;
26027
26051
  listenersRef.current.forEach((cb) => {
26028
26052
  try {
26029
26053
  cb(bar);
@@ -26048,11 +26072,14 @@ function useSymmChartCandles(selection) {
26048
26072
  }
26049
26073
  }, [emitRealtimeBar, isUnsupported, selectedSymbols]);
26050
26074
  react.useEffect(() => {
26075
+ if (listenersRef.current.size > 0) {
26076
+ setupWsSubscriptions();
26077
+ }
26051
26078
  return () => {
26052
26079
  wsUnsubsRef.current.forEach((unsub) => unsub());
26053
26080
  wsUnsubsRef.current = [];
26054
26081
  };
26055
- }, [longTokens, shortTokens]);
26082
+ }, [setupWsSubscriptions]);
26056
26083
  const fetchBasketCandles = react.useCallback(
26057
26084
  async (start, end, interval) => {
26058
26085
  const longSymbol = longTokens[0]?.symbol;
@@ -26218,10 +26245,8 @@ function useSymmPerformanceOverlays(selection) {
26218
26245
  weight: -token.weight
26219
26246
  }))
26220
26247
  ], [longTokens, shortTokens]);
26221
- const generateOverlaySymbols = react.useCallback(() => {
26222
- return overlays.map((o) => o.symbol);
26223
- }, [overlays]);
26224
- return { overlays, generateOverlaySymbols };
26248
+ const overlaySymbols = react.useMemo(() => overlays.map((o) => o.symbol), [overlays]);
26249
+ return { overlays, overlaySymbols };
26225
26250
  }
26226
26251
  function getSymmErrorMessage(error) {
26227
26252
  if (error instanceof SymmioSDKError) return error.message;