@pear-protocol/symmio-client 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ import { useAccount, usePublicClient, useWalletClient } from 'wagmi';
3
3
  import { createSymmSDK, isAuthExpiredError, isNetworkError, isInsufficientMarginError, isRateLimitedError, isTimeoutError } from '@pear-protocol/symm-core';
4
4
  import { encodeFunctionData, isAddress } from 'viem';
5
5
  import { jsx } from 'react/jsx-runtime';
6
- import { useQueryClient, useQuery, useMutation } from '@tanstack/react-query';
6
+ import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
7
7
 
8
8
  // src/react/provider.tsx
9
9
 
@@ -27,6 +27,10 @@ var CLEARING_HOUSE_ADDRESS = {
27
27
  var SIGNATURE_STORE_ADDRESS = {
28
28
  [42161 /* ARBITRUM */]: "0x94eEa58De1C8945c342dB4bE9670301638E403e2"
29
29
  };
30
+ var DEFAULT_PARTY_B_ADDRESS = {
31
+ [42161 /* ARBITRUM */]: "0x00c069d68bc7420740460DBC3cc3fFF9b3742421",
32
+ [8453 /* BASE */]: "0x1EcAbF0Eba136920677C9575FAccee36f30592cf"
33
+ };
30
34
  function getAddress(addressMap, chainId, name) {
31
35
  const addr = addressMap[chainId];
32
36
  if (!addr || addr === "0x0000000000000000000000000000000000000000") {
@@ -23650,6 +23654,17 @@ async function revokeAccess(walletClient, publicClient, multiAccount, params) {
23650
23654
  chain: walletClient.chain
23651
23655
  });
23652
23656
  }
23657
+ async function hasDelegatedAccess(publicClient, multiAccount, params) {
23658
+ validateAddress(params.account, "subAccount");
23659
+ validateAddress(params.target, "target");
23660
+ const result = await publicClient.readContract({
23661
+ address: multiAccount,
23662
+ abi: MultiAccountABI,
23663
+ functionName: "delegatedAccesses",
23664
+ args: [params.account, params.target, params.selector]
23665
+ });
23666
+ return Boolean(result);
23667
+ }
23653
23668
 
23654
23669
  // src/abis/SignatureStore.ts
23655
23670
  var SignatureStoreABI = [
@@ -23954,6 +23969,51 @@ async function getOpenInstantCloses(chainId, account, accessToken) {
23954
23969
  return response.json();
23955
23970
  }
23956
23971
 
23972
+ // src/actions/stats.ts
23973
+ async function getPartyAStats(publicClient, symmioDiamond, partyA) {
23974
+ const result = await publicClient.readContract({
23975
+ address: symmioDiamond,
23976
+ abi: SymmioDiamondABI,
23977
+ functionName: "partyAStats",
23978
+ args: [partyA]
23979
+ });
23980
+ return {
23981
+ collateralBalance: result[1],
23982
+ allocatedBalance: result[2],
23983
+ availableBalance: result[3],
23984
+ lockedCVA: result[4],
23985
+ lockedLF: result[5],
23986
+ lockedPartyAMM: result[6],
23987
+ lockedPartyBMM: result[7],
23988
+ pendingLockedCVA: result[8],
23989
+ pendingLockedLF: result[9],
23990
+ pendingLockedPartyAMM: result[10],
23991
+ pendingLockedPartyBMM: result[11],
23992
+ positionsCount: Number(result[12]),
23993
+ pendingCount: Number(result[13]),
23994
+ nonces: 0
23995
+ };
23996
+ }
23997
+ function calculateAvailableForOrder(stats, upnl) {
23998
+ const {
23999
+ allocatedBalance,
24000
+ lockedCVA,
24001
+ lockedLF,
24002
+ lockedPartyAMM,
24003
+ pendingLockedCVA,
24004
+ pendingLockedLF,
24005
+ pendingLockedPartyAMM
24006
+ } = stats;
24007
+ const totalPendingLocked = pendingLockedCVA + pendingLockedLF + pendingLockedPartyAMM;
24008
+ if (upnl >= 0n) {
24009
+ const totalLocked = lockedCVA + lockedLF + lockedPartyAMM;
24010
+ return allocatedBalance + upnl - totalLocked - totalPendingLocked;
24011
+ }
24012
+ const absUpnl = -upnl;
24013
+ const consideringMm = absUpnl > lockedPartyAMM ? absUpnl : lockedPartyAMM;
24014
+ return allocatedBalance - lockedCVA - lockedLF - totalPendingLocked - consideringMm;
24015
+ }
24016
+
23957
24017
  // src/client.ts
23958
24018
  var SymmioSDK = class {
23959
24019
  chainId;
@@ -24100,7 +24160,9 @@ var SymmioSDK = class {
24100
24160
  /** Propose to revoke delegated access (starts cooldown). */
24101
24161
  proposeRevoke: (params) => proposeRevoke(wc, pc, ma, params),
24102
24162
  /** Revoke delegated access (after cooldown). */
24103
- revokeAccess: (params) => revokeAccess(wc, pc, ma, params)
24163
+ revokeAccess: (params) => revokeAccess(wc, pc, ma, params),
24164
+ /** Reads whether a selector is delegated to a target for a sub-account. */
24165
+ hasAccess: (params) => hasDelegatedAccess(pc, ma, params)
24104
24166
  };
24105
24167
  }
24106
24168
  // ─── Signature Module ──────────────────────────────────────────
@@ -24156,6 +24218,17 @@ var SymmioSDK = class {
24156
24218
  getOpenCloses: (account, accessToken) => getOpenInstantCloses(this.chainId, account, accessToken)
24157
24219
  };
24158
24220
  }
24221
+ // ─── Stats Module ───────────────────────────────────────────
24222
+ get stats() {
24223
+ const pc = this._publicClient;
24224
+ const sd = this._symmioDiamond;
24225
+ return {
24226
+ /** Reads partyA statistics (balances, locks) from the Diamond contract. */
24227
+ getPartyAStats: (partyA) => getPartyAStats(pc, sd, partyA),
24228
+ /** Calculates available margin for placing orders given uPNL. */
24229
+ calculateAvailableForOrder: (stats, upnl) => calculateAvailableForOrder(stats, upnl)
24230
+ };
24231
+ }
24159
24232
  // ─── Muon Signatures ──────────────────────────────────────────
24160
24233
  async getQuoteSig(partyA, symbolId) {
24161
24234
  return this.muon.getQuoteSig({
@@ -24386,6 +24459,14 @@ function useSymmAuth() {
24386
24459
  };
24387
24460
  }
24388
24461
 
24462
+ // src/constants/selectors.ts
24463
+ var SEND_QUOTE_WITH_AFFILIATE_SELECTOR = "0x40f1310c";
24464
+ var CLOSE_QUOTE_SELECTOR = "0x501e891f";
24465
+ var ALL_TRADING_SELECTORS = [
24466
+ SEND_QUOTE_WITH_AFFILIATE_SELECTOR,
24467
+ CLOSE_QUOTE_SELECTOR
24468
+ ];
24469
+
24389
24470
  // src/react/query-keys.ts
24390
24471
  var symmKeys = {
24391
24472
  all: ["symm"],
@@ -24400,14 +24481,159 @@ var symmKeys = {
24400
24481
  tpslOrders: (address, chainId) => ["symm", "tpslOrders", address, chainId],
24401
24482
  twapOrders: (address, chainId) => ["symm", "twapOrders", address, chainId],
24402
24483
  markets: (chainId, search) => ["symm", "markets", chainId, search],
24403
- hedgerMarkets: (chainId, search) => ["symm", "hedgerMarkets", chainId, search],
24484
+ hedgerMarkets: (request) => ["symm", "hedgerMarkets", request],
24404
24485
  fundingRates: (chainId) => ["symm", "fundingRates", chainId],
24405
24486
  portfolio: (address, chainId) => ["symm", "portfolio", address, chainId],
24406
24487
  notifications: (address, chainId) => ["symm", "notifications", address, chainId],
24407
- unreadCount: (address, chainId) => ["symm", "unreadCount", address, chainId]
24488
+ unreadCount: (address, chainId) => ["symm", "unreadCount", address, chainId],
24489
+ availableMargin: (address, chainId) => ["symm", "availableMargin", address, chainId],
24490
+ delegation: (account, target, selectors, chainId) => ["symm", "delegation", account, target, selectors, chainId]
24408
24491
  };
24409
24492
 
24410
- // src/react/hooks/use-symm-accounts.ts
24493
+ // src/react/hooks/use-symm-delegation.ts
24494
+ function useSymmDelegation(params) {
24495
+ const { symmioClient, chainId, address } = useSymmContext();
24496
+ const accountAddress = params?.accountAddress ?? address;
24497
+ const target = params?.target ?? DEFAULT_PARTY_B_ADDRESS[chainId];
24498
+ const selectors = params?.selectors ?? ALL_TRADING_SELECTORS;
24499
+ const enabled = (params?.enabled ?? true) && !!symmioClient && !!accountAddress && !!target && selectors.length > 0;
24500
+ return useQuery({
24501
+ queryKey: symmKeys.delegation(accountAddress, target, selectors, chainId),
24502
+ enabled,
24503
+ queryFn: async () => {
24504
+ if (!symmioClient) throw new Error("symmio client not available");
24505
+ if (!accountAddress) throw new Error("account address is required");
24506
+ if (!target) throw new Error("delegation target is not configured");
24507
+ const entries = await Promise.all(
24508
+ selectors.map(async (selector) => [
24509
+ selector,
24510
+ await symmioClient.delegation.hasAccess({
24511
+ account: accountAddress,
24512
+ target,
24513
+ selector
24514
+ })
24515
+ ])
24516
+ );
24517
+ const accessBySelector = Object.fromEntries(entries);
24518
+ return {
24519
+ hasAccess: selectors.every((selector) => accessBySelector[selector] === true),
24520
+ account: accountAddress,
24521
+ target,
24522
+ selectors,
24523
+ accessBySelector,
24524
+ openAccess: accessBySelector[SEND_QUOTE_WITH_AFFILIATE_SELECTOR] ?? void 0,
24525
+ closeAccess: accessBySelector[CLOSE_QUOTE_SELECTOR] ?? void 0
24526
+ };
24527
+ }
24528
+ });
24529
+ }
24530
+
24531
+ // src/react/cache.ts
24532
+ function invalidateBalances(qc) {
24533
+ qc.invalidateQueries({ queryKey: ["symm", "balances"] });
24534
+ qc.invalidateQueries({ queryKey: ["symm", "accountSummary"] });
24535
+ qc.invalidateQueries({ queryKey: ["symm", "portfolio"] });
24536
+ }
24537
+ function invalidatePositions(qc) {
24538
+ qc.invalidateQueries({ queryKey: ["symm", "positions"] });
24539
+ qc.invalidateQueries({ queryKey: ["symm", "openOrders"] });
24540
+ qc.invalidateQueries({ queryKey: ["symm", "tradeHistory"] });
24541
+ qc.invalidateQueries({ queryKey: ["symm", "portfolio"] });
24542
+ }
24543
+ function invalidateOrders(qc) {
24544
+ qc.invalidateQueries({ queryKey: ["symm", "openOrders"] });
24545
+ qc.invalidateQueries({ queryKey: ["symm", "tpslOrders"] });
24546
+ qc.invalidateQueries({ queryKey: ["symm", "twapOrders"] });
24547
+ }
24548
+
24549
+ // src/react/hooks/use-symm-instant-trade.ts
24550
+ function useSymmInstantTrade(params) {
24551
+ const {
24552
+ symmioClient,
24553
+ symmCoreClient,
24554
+ chainId,
24555
+ address,
24556
+ refreshAuth
24557
+ } = useSymmContext();
24558
+ const queryClient = useQueryClient();
24559
+ const defaultAccountAddress = params?.accountAddress ?? address;
24560
+ const defaultTarget = params?.target ?? DEFAULT_PARTY_B_ADDRESS[chainId];
24561
+ const defaultSelectors = params?.selectors ?? ALL_TRADING_SELECTORS;
24562
+ const delegation = useSymmDelegation({
24563
+ accountAddress: defaultAccountAddress,
24564
+ target: defaultTarget,
24565
+ selectors: defaultSelectors,
24566
+ enabled: params?.enabled
24567
+ });
24568
+ const ensureReady = useMutation({
24569
+ mutationFn: async (request) => {
24570
+ if (!symmioClient) throw new Error("symmio client not available");
24571
+ const accountAddress = request?.accountAddress ?? defaultAccountAddress;
24572
+ const target = request?.target ?? defaultTarget;
24573
+ const selectors = request?.selectors ?? defaultSelectors;
24574
+ if (!accountAddress) throw new Error("account address is required");
24575
+ if (!target) throw new Error("delegation target is not configured");
24576
+ if (selectors.length === 0) {
24577
+ throw new Error("at least one delegation selector is required");
24578
+ }
24579
+ const accessToken = await refreshAuth(accountAddress);
24580
+ if (!accessToken) {
24581
+ throw new Error("failed to refresh instant-trading auth");
24582
+ }
24583
+ const accessStates = await Promise.all(
24584
+ selectors.map(
24585
+ (selector) => symmioClient.delegation.hasAccess({
24586
+ account: accountAddress,
24587
+ target,
24588
+ selector
24589
+ })
24590
+ )
24591
+ );
24592
+ if (!accessStates.every(Boolean)) {
24593
+ await symmioClient.delegation.delegateAccess({
24594
+ account: accountAddress,
24595
+ target,
24596
+ selectors: [...selectors],
24597
+ activate: true
24598
+ });
24599
+ await queryClient.invalidateQueries({
24600
+ queryKey: symmKeys.delegation(accountAddress, target, selectors, chainId)
24601
+ });
24602
+ }
24603
+ return {
24604
+ accessToken,
24605
+ accountAddress,
24606
+ target,
24607
+ selectors
24608
+ };
24609
+ }
24610
+ });
24611
+ const execute = useMutation({
24612
+ mutationFn: async (request) => {
24613
+ if (!symmCoreClient) throw new Error("symm-core client not available");
24614
+ const setup = await ensureReady.mutateAsync({
24615
+ accountAddress: request.accountAddress,
24616
+ target: request.target,
24617
+ selectors: request.selectors
24618
+ });
24619
+ return request.action({
24620
+ symmCoreClient,
24621
+ accessToken: setup.accessToken,
24622
+ accountAddress: setup.accountAddress
24623
+ });
24624
+ },
24625
+ onSuccess: (_data, variables) => {
24626
+ if (variables.invalidatePositionsOnSuccess !== false) {
24627
+ invalidatePositions(queryClient);
24628
+ }
24629
+ }
24630
+ });
24631
+ return {
24632
+ delegation,
24633
+ ensureReady,
24634
+ execute
24635
+ };
24636
+ }
24411
24637
  function useSymmAccounts(userAddress) {
24412
24638
  const { symmioClient } = useSymmContext();
24413
24639
  const queryClient = useQueryClient();
@@ -24489,26 +24715,6 @@ function useSymmApproval(params) {
24489
24715
  approve: approve2
24490
24716
  };
24491
24717
  }
24492
-
24493
- // src/react/cache.ts
24494
- function invalidateBalances(qc) {
24495
- qc.invalidateQueries({ queryKey: ["symm", "balances"] });
24496
- qc.invalidateQueries({ queryKey: ["symm", "accountSummary"] });
24497
- qc.invalidateQueries({ queryKey: ["symm", "portfolio"] });
24498
- }
24499
- function invalidatePositions(qc) {
24500
- qc.invalidateQueries({ queryKey: ["symm", "positions"] });
24501
- qc.invalidateQueries({ queryKey: ["symm", "openOrders"] });
24502
- qc.invalidateQueries({ queryKey: ["symm", "tradeHistory"] });
24503
- qc.invalidateQueries({ queryKey: ["symm", "portfolio"] });
24504
- }
24505
- function invalidateOrders(qc) {
24506
- qc.invalidateQueries({ queryKey: ["symm", "openOrders"] });
24507
- qc.invalidateQueries({ queryKey: ["symm", "tpslOrders"] });
24508
- qc.invalidateQueries({ queryKey: ["symm", "twapOrders"] });
24509
- }
24510
-
24511
- // src/react/hooks/use-symm-deposit.ts
24512
24718
  function useSymmDeposit() {
24513
24719
  const { symmioClient } = useSymmContext();
24514
24720
  const queryClient = useQueryClient();
@@ -24628,6 +24834,31 @@ function useSymmSignature(userAddress) {
24628
24834
  signTerms
24629
24835
  };
24630
24836
  }
24837
+ function useSymmAvailableMargin(params) {
24838
+ const { symmioClient } = useSymmContext();
24839
+ const { accountAddress, upnl } = params;
24840
+ const query = useQuery({
24841
+ queryKey: symmKeys.availableMargin(accountAddress, symmioClient?.chainId),
24842
+ queryFn: async () => {
24843
+ const stats = await symmioClient.stats.getPartyAStats(accountAddress);
24844
+ const resolvedUpnl = upnl ?? 0n;
24845
+ const availableForOrder = calculateAvailableForOrder(stats, resolvedUpnl);
24846
+ return {
24847
+ ...stats,
24848
+ upnl: resolvedUpnl,
24849
+ availableForOrder
24850
+ };
24851
+ },
24852
+ enabled: !!symmioClient && !!accountAddress,
24853
+ staleTime: 1e4
24854
+ });
24855
+ return {
24856
+ availableForOrder: query.data?.availableForOrder ?? null,
24857
+ stats: query.data ?? null,
24858
+ isLoading: query.isLoading,
24859
+ refetch: query.refetch
24860
+ };
24861
+ }
24631
24862
  function useSymmBalances(params) {
24632
24863
  const { symmCoreClient, chainId: ctxChainId } = useSymmContext();
24633
24864
  const { userAddress, multiAccountAddress } = params;
@@ -24842,19 +25073,34 @@ function useSymmHedgerMarkets(params) {
24842
25073
  const chainId = params?.chainId ?? ctxChainId;
24843
25074
  const searchText = params?.searchText?.trim();
24844
25075
  const isEnabled = params?.enabled ?? true;
25076
+ const request = {
25077
+ ...params,
25078
+ chainId,
25079
+ searchText: searchText || void 0
25080
+ };
24845
25081
  const query = useQuery({
24846
- queryKey: symmKeys.hedgerMarkets(chainId, searchText),
25082
+ queryKey: symmKeys.hedgerMarkets(request),
24847
25083
  queryFn: async () => {
24848
- return symmCoreClient.markets.listHedger({
24849
- chainId,
24850
- searchText: searchText || void 0
24851
- });
25084
+ const { enabled: _enabled, ...queryRequest } = request;
25085
+ return symmCoreClient.markets.listSymmHedger(queryRequest);
24852
25086
  },
24853
25087
  enabled: !!symmCoreClient && isEnabled,
24854
25088
  staleTime: 3e4
24855
25089
  });
25090
+ const data = query.data ?? null;
25091
+ const emptyMap = /* @__PURE__ */ new Map();
25092
+ const emptySymbolMap = /* @__PURE__ */ new Map();
24856
25093
  return {
24857
- markets: query.data?.data?.markets ?? [],
25094
+ data,
25095
+ markets: data?.markets ?? [],
25096
+ rawMarkets: data?.rawMarkets ?? [],
25097
+ filteredMarkets: data?.filteredMarkets ?? [],
25098
+ allSymbols: data?.allSymbols ?? [],
25099
+ filteredSymbols: data?.filteredSymbols ?? [],
25100
+ marketsById: data?.marketsById ?? emptyMap,
25101
+ marketsBySymbol: data?.marketsBySymbol ?? emptySymbolMap,
25102
+ category: data?.category ?? params?.category ?? "all",
25103
+ resolvedSearchText: data?.searchText ?? searchText ?? "",
24858
25104
  isLoading: query.isLoading,
24859
25105
  isFetching: query.isFetching,
24860
25106
  refetch: query.refetch
@@ -25987,6 +26233,6 @@ function getSymmErrorMessage(error) {
25987
26233
  return "An unexpected error occurred.";
25988
26234
  }
25989
26235
 
25990
- export { SymmProvider, getSymmErrorMessage, symmKeys, useSymmAccounts, useSymmApproval, useSymmAuth, useSymmBalances, useSymmChartCandles, useSymmChartSelection, useSymmCollateral, useSymmContext, useSymmCoreClient, useSymmDeposit, useSymmFunding, useSymmHedgerMarkets, useSymmMarkets, useSymmNotifications, useSymmOpenOrders, useSymmPerformanceOverlays, useSymmPortfolio, useSymmPositions, useSymmSignature, useSymmTokenSelectionMetadata, useSymmTpsl, useSymmTrade, useSymmTradeHistory, useSymmTwap, useSymmWithdraw, useSymmWs, useSymmioClient };
26236
+ export { SymmProvider, getSymmErrorMessage, symmKeys, useSymmAccounts, useSymmApproval, useSymmAuth, useSymmAvailableMargin, useSymmBalances, useSymmChartCandles, useSymmChartSelection, useSymmCollateral, useSymmContext, useSymmCoreClient, useSymmDelegation, useSymmDeposit, useSymmFunding, useSymmHedgerMarkets, useSymmInstantTrade, useSymmMarkets, useSymmNotifications, useSymmOpenOrders, useSymmPerformanceOverlays, useSymmPortfolio, useSymmPositions, useSymmSignature, useSymmTokenSelectionMetadata, useSymmTpsl, useSymmTrade, useSymmTradeHistory, useSymmTwap, useSymmWithdraw, useSymmWs, useSymmioClient };
25991
26237
  //# sourceMappingURL=index.mjs.map
25992
26238
  //# sourceMappingURL=index.mjs.map