@sodax/dapp-kit 1.5.7-beta → 2.0.0-rc.2

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.
Files changed (202) hide show
  1. package/README.md +300 -422
  2. package/ai-exported/AGENTS.md +134 -0
  3. package/ai-exported/integration/README.md +49 -0
  4. package/ai-exported/integration/ai-rules.md +79 -0
  5. package/ai-exported/integration/architecture.md +274 -0
  6. package/ai-exported/integration/features/README.md +29 -0
  7. package/ai-exported/integration/features/auxiliary-services.md +169 -0
  8. package/ai-exported/integration/features/bitcoin.md +87 -0
  9. package/ai-exported/integration/features/bridge.md +91 -0
  10. package/ai-exported/integration/features/dex.md +152 -0
  11. package/ai-exported/integration/features/migration.md +118 -0
  12. package/ai-exported/integration/features/money-market.md +116 -0
  13. package/ai-exported/integration/features/staking.md +123 -0
  14. package/ai-exported/integration/features/swap.md +101 -0
  15. package/ai-exported/integration/quickstart.md +187 -0
  16. package/ai-exported/integration/recipes/README.md +136 -0
  17. package/ai-exported/integration/recipes/backend-queries.md +157 -0
  18. package/ai-exported/integration/recipes/bitcoin.md +193 -0
  19. package/ai-exported/integration/recipes/bridge.md +174 -0
  20. package/ai-exported/integration/recipes/dex.md +204 -0
  21. package/ai-exported/integration/recipes/invalidations.md +115 -0
  22. package/ai-exported/integration/recipes/migration.md +212 -0
  23. package/ai-exported/integration/recipes/money-market.md +206 -0
  24. package/ai-exported/integration/recipes/mutation-error-handling.md +118 -0
  25. package/ai-exported/integration/recipes/observability.md +93 -0
  26. package/ai-exported/integration/recipes/setup.md +144 -0
  27. package/ai-exported/integration/recipes/staking.md +202 -0
  28. package/ai-exported/integration/recipes/swap.md +272 -0
  29. package/ai-exported/integration/recipes/wallet-connectivity.md +101 -0
  30. package/ai-exported/integration/reference/README.md +12 -0
  31. package/ai-exported/integration/reference/glossary.md +188 -0
  32. package/ai-exported/integration/reference/hooks-index.md +190 -0
  33. package/ai-exported/integration/reference/public-api.md +110 -0
  34. package/ai-exported/integration/reference/querykey-conventions.md +179 -0
  35. package/ai-exported/migration/README.md +60 -0
  36. package/ai-exported/migration/ai-rules.md +81 -0
  37. package/ai-exported/migration/breaking-changes/hook-signatures.md +233 -0
  38. package/ai-exported/migration/breaking-changes/querykey-conventions.md +108 -0
  39. package/ai-exported/migration/breaking-changes/result-handling.md +211 -0
  40. package/ai-exported/migration/breaking-changes/sdk-leakage.md +165 -0
  41. package/ai-exported/migration/checklist.md +89 -0
  42. package/ai-exported/migration/features/README.md +34 -0
  43. package/ai-exported/migration/features/auxiliary-services.md +114 -0
  44. package/ai-exported/migration/features/bitcoin.md +88 -0
  45. package/ai-exported/migration/features/bridge.md +123 -0
  46. package/ai-exported/migration/features/dex.md +101 -0
  47. package/ai-exported/migration/features/migration.md +120 -0
  48. package/ai-exported/migration/features/money-market.md +97 -0
  49. package/ai-exported/migration/features/staking.md +109 -0
  50. package/ai-exported/migration/features/swap.md +118 -0
  51. package/ai-exported/migration/recipes.md +188 -0
  52. package/ai-exported/migration/reference/README.md +15 -0
  53. package/ai-exported/migration/reference/deleted-hooks.md +110 -0
  54. package/ai-exported/migration/reference/error-shape-crosswalk.md +144 -0
  55. package/ai-exported/migration/reference/renamed-hooks.md +66 -0
  56. package/dist/index.cjs +2642 -0
  57. package/dist/index.cjs.map +1 -0
  58. package/dist/index.d.cts +1550 -0
  59. package/dist/index.d.ts +1020 -2051
  60. package/dist/index.mjs +1581 -1531
  61. package/dist/index.mjs.map +1 -1
  62. package/package.json +21 -11
  63. package/src/contexts/index.ts +0 -3
  64. package/src/hooks/_mutationContract.test.ts +99 -0
  65. package/src/hooks/backend/README.md +2 -2
  66. package/src/hooks/backend/index.ts +13 -13
  67. package/src/hooks/backend/unwrapResult.ts +1 -0
  68. package/src/hooks/backend/useBackendAllMoneyMarketAssets.ts +13 -45
  69. package/src/hooks/backend/useBackendAllMoneyMarketBorrowers.ts +29 -59
  70. package/src/hooks/backend/useBackendIntentByHash.ts +21 -47
  71. package/src/hooks/backend/useBackendIntentByTxHash.ts +23 -50
  72. package/src/hooks/backend/useBackendMoneyMarketAsset.ts +21 -54
  73. package/src/hooks/backend/useBackendMoneyMarketAssetBorrowers.ts +30 -57
  74. package/src/hooks/backend/useBackendMoneyMarketAssetSuppliers.ts +31 -58
  75. package/src/hooks/backend/useBackendMoneyMarketPosition.ts +22 -38
  76. package/src/hooks/backend/useBackendOrderbook.ts +27 -49
  77. package/src/hooks/backend/useBackendSubmitSwapTx.ts +30 -36
  78. package/src/hooks/backend/useBackendSubmitSwapTxStatus.ts +38 -58
  79. package/src/hooks/backend/useBackendUserIntents.ts +25 -63
  80. package/src/hooks/bitcoin/index.ts +9 -8
  81. package/src/hooks/bitcoin/useBitcoinBalance.ts +20 -5
  82. package/src/hooks/bitcoin/useExpiredUtxos.ts +26 -16
  83. package/src/hooks/bitcoin/useFundTradingWallet.ts +33 -30
  84. package/src/hooks/bitcoin/useRadfiAuth.ts +43 -40
  85. package/src/hooks/bitcoin/useRadfiSession.ts +53 -59
  86. package/src/hooks/bitcoin/useRadfiWithdraw.ts +35 -53
  87. package/src/hooks/bitcoin/useRenewUtxos.ts +30 -50
  88. package/src/hooks/bitcoin/useTradingWallet.ts +1 -1
  89. package/src/hooks/bitcoin/useTradingWalletBalance.ts +25 -14
  90. package/src/hooks/bridge/index.ts +5 -5
  91. package/src/hooks/bridge/useBridge.ts +29 -55
  92. package/src/hooks/bridge/useBridgeAllowance.ts +38 -38
  93. package/src/hooks/bridge/useBridgeApprove.ts +32 -57
  94. package/src/hooks/bridge/useGetBridgeableAmount.ts +23 -37
  95. package/src/hooks/bridge/useGetBridgeableTokens.ts +27 -50
  96. package/src/hooks/dex/index.ts +16 -16
  97. package/src/hooks/dex/useClaimRewards.ts +35 -54
  98. package/src/hooks/dex/useCreateDecreaseLiquidityParams.ts +7 -20
  99. package/src/hooks/dex/useCreateDepositParams.ts +7 -21
  100. package/src/hooks/dex/useCreateSupplyLiquidityParams.ts +13 -28
  101. package/src/hooks/dex/useCreateWithdrawParams.ts +7 -20
  102. package/src/hooks/dex/useDecreaseLiquidity.ts +40 -66
  103. package/src/hooks/dex/useDexAllowance.ts +29 -75
  104. package/src/hooks/dex/useDexApprove.ts +32 -43
  105. package/src/hooks/dex/useDexDeposit.ts +42 -49
  106. package/src/hooks/dex/useDexWithdraw.ts +32 -43
  107. package/src/hooks/dex/useLiquidityAmounts.ts +13 -82
  108. package/src/hooks/dex/usePoolBalances.ts +50 -72
  109. package/src/hooks/dex/usePoolData.ts +17 -43
  110. package/src/hooks/dex/usePools.ts +11 -38
  111. package/src/hooks/dex/usePositionInfo.ts +27 -62
  112. package/src/hooks/dex/useSupplyLiquidity.ts +80 -75
  113. package/src/hooks/index.ts +12 -10
  114. package/src/hooks/migrate/index.ts +13 -4
  115. package/src/hooks/migrate/useMigrateBaln.ts +42 -0
  116. package/src/hooks/migrate/useMigrateIcxToSoda.ts +44 -0
  117. package/src/hooks/migrate/useMigratebnUSD.ts +47 -0
  118. package/src/hooks/migrate/useMigrationAllowance.ts +76 -0
  119. package/src/hooks/migrate/useMigrationApprove.ts +66 -0
  120. package/src/hooks/migrate/useRevertMigrateSodaToIcx.ts +39 -0
  121. package/src/hooks/mm/index.ts +14 -12
  122. package/src/hooks/mm/useAToken.ts +25 -41
  123. package/src/hooks/mm/useATokensBalances.ts +29 -60
  124. package/src/hooks/mm/useBorrow.ts +38 -56
  125. package/src/hooks/mm/useMMAllowance.ts +37 -73
  126. package/src/hooks/mm/useMMApprove.ts +36 -43
  127. package/src/hooks/mm/useRepay.ts +33 -53
  128. package/src/hooks/mm/useReservesData.ts +12 -38
  129. package/src/hooks/mm/useReservesHumanized.ts +12 -31
  130. package/src/hooks/mm/useReservesList.ts +11 -31
  131. package/src/hooks/mm/useReservesUsdFormat.ts +15 -35
  132. package/src/hooks/mm/useSupply.ts +45 -51
  133. package/src/hooks/mm/useUserFormattedSummary.ts +32 -84
  134. package/src/hooks/mm/useUserReservesData.ts +27 -77
  135. package/src/hooks/mm/useWithdraw.ts +38 -54
  136. package/src/hooks/partner/index.ts +6 -0
  137. package/src/hooks/partner/useApproveToken.ts +42 -0
  138. package/src/hooks/partner/useFeeClaimSwap.ts +38 -0
  139. package/src/hooks/partner/useFetchAssetsBalances.ts +37 -0
  140. package/src/hooks/partner/useGetAutoSwapPreferences.ts +37 -0
  141. package/src/hooks/partner/useIsTokenApproved.ts +39 -0
  142. package/src/hooks/partner/useSetSwapPreference.ts +50 -0
  143. package/src/hooks/provider/index.ts +1 -2
  144. package/src/hooks/provider/useHubProvider.ts +1 -1
  145. package/src/hooks/recovery/index.ts +2 -0
  146. package/src/hooks/recovery/useHubAssetBalances.ts +43 -0
  147. package/src/hooks/recovery/useWithdrawHubAsset.ts +48 -0
  148. package/src/hooks/shared/index.ts +10 -6
  149. package/src/hooks/shared/types.ts +77 -0
  150. package/src/hooks/shared/unwrapResult.ts +19 -0
  151. package/src/hooks/shared/useDeriveUserWalletAddress.ts +22 -40
  152. package/src/hooks/shared/useEstimateGas.ts +18 -15
  153. package/src/hooks/shared/useGetUserHubWalletAddress.ts +25 -26
  154. package/src/hooks/shared/useRequestTrustline.ts +28 -61
  155. package/src/hooks/shared/useSafeMutation.test.ts +43 -0
  156. package/src/hooks/shared/useSafeMutation.ts +68 -0
  157. package/src/hooks/shared/useSodaxContext.ts +1 -1
  158. package/src/hooks/shared/useStellarTrustlineCheck.ts +30 -64
  159. package/src/hooks/shared/useXBalances.test.ts +113 -0
  160. package/src/hooks/shared/useXBalances.ts +61 -0
  161. package/src/hooks/staking/index.ts +18 -18
  162. package/src/hooks/staking/useCancelUnstake.ts +30 -41
  163. package/src/hooks/staking/useClaim.ts +27 -36
  164. package/src/hooks/staking/useConvertedAssets.ts +24 -34
  165. package/src/hooks/staking/useInstantUnstake.ts +33 -40
  166. package/src/hooks/staking/useInstantUnstakeAllowance.ts +37 -45
  167. package/src/hooks/staking/useInstantUnstakeApprove.ts +42 -42
  168. package/src/hooks/staking/useInstantUnstakeRatio.ts +24 -41
  169. package/src/hooks/staking/useStake.ts +32 -37
  170. package/src/hooks/staking/useStakeAllowance.ts +30 -43
  171. package/src/hooks/staking/useStakeApprove.ts +40 -40
  172. package/src/hooks/staking/useStakeRatio.ts +24 -40
  173. package/src/hooks/staking/useStakingConfig.ts +14 -27
  174. package/src/hooks/staking/useStakingInfo.ts +30 -38
  175. package/src/hooks/staking/useUnstake.ts +29 -43
  176. package/src/hooks/staking/useUnstakeAllowance.ts +37 -44
  177. package/src/hooks/staking/useUnstakeApprove.ts +40 -43
  178. package/src/hooks/staking/useUnstakingInfo.ts +29 -41
  179. package/src/hooks/staking/useUnstakingInfoWithPenalty.ts +31 -47
  180. package/src/hooks/swap/index.ts +8 -8
  181. package/src/hooks/swap/useCancelLimitOrder.ts +24 -41
  182. package/src/hooks/swap/useCancelSwap.ts +24 -33
  183. package/src/hooks/swap/useCreateLimitOrder.ts +29 -62
  184. package/src/hooks/swap/useQuote.ts +17 -43
  185. package/src/hooks/swap/useStatus.ts +22 -29
  186. package/src/hooks/swap/useSwap.ts +31 -49
  187. package/src/hooks/swap/useSwapAllowance.ts +38 -35
  188. package/src/hooks/swap/useSwapApprove.ts +48 -57
  189. package/src/index.ts +5 -3
  190. package/src/providers/SodaxProvider.tsx +17 -11
  191. package/src/providers/createSodaxQueryClient.ts +96 -0
  192. package/src/providers/index.ts +2 -1
  193. package/src/utils/dex-utils.ts +27 -5
  194. package/src/utils/index.ts +1 -1
  195. package/dist/index.d.mts +0 -2581
  196. package/dist/index.js +0 -2574
  197. package/dist/index.js.map +0 -1
  198. package/src/hooks/migrate/types.ts +0 -15
  199. package/src/hooks/migrate/useMigrate.tsx +0 -110
  200. package/src/hooks/migrate/useMigrationAllowance.tsx +0 -79
  201. package/src/hooks/migrate/useMigrationApprove.tsx +0 -129
  202. package/src/hooks/provider/useSpokeProvider.ts +0 -172
@@ -1,7 +1,7 @@
1
1
  import { useState, useEffect, useCallback, useMemo } from 'react';
2
2
  import { ClService, type PoolData } from '@sodax/sdk';
3
3
 
4
- interface UseLiquidityAmountsResult {
4
+ export type UseLiquidityAmountsResult = {
5
5
  liquidityToken0Amount: string;
6
6
  liquidityToken1Amount: string;
7
7
  lastEditedToken: 'token0' | 'token1' | null;
@@ -9,34 +9,11 @@ interface UseLiquidityAmountsResult {
9
9
  setLiquidityToken1Amount: (value: string) => void;
10
10
  handleToken0AmountChange: (value: string) => void;
11
11
  handleToken1AmountChange: (value: string) => void;
12
- }
12
+ };
13
13
 
14
14
  /**
15
- * Hook for calculating liquidity amounts based on price range.
16
- *
17
- * This hook manages the state and calculations for liquidity token amounts.
18
- * It automatically calculates the corresponding token amount when one is changed,
19
- * based on the current price range and pool data.
20
- *
21
- * @param {string} minPrice - Minimum price for the liquidity range
22
- * @param {string} maxPrice - Maximum price for the liquidity range
23
- * @param {PoolData | null} poolData - The pool data containing token information
24
- * @returns {UseLiquidityAmountsResult} Object containing amounts, state, and handlers
25
- *
26
- * @example
27
- * ```typescript
28
- * const {
29
- * liquidityToken0Amount,
30
- * liquidityToken1Amount,
31
- * handleToken0AmountChange,
32
- * handleToken1AmountChange,
33
- * } = useLiquidityAmounts(minPrice, maxPrice, poolData);
34
- *
35
- * <Input
36
- * value={liquidityToken0Amount}
37
- * onChange={(e) => handleToken0AmountChange(e.target.value)}
38
- * />
39
- * ```
15
+ * Hook for calculating concentrated-liquidity amounts based on the price range. Pure state +
16
+ * math; no SDK calls beyond the static {@link ClService} helpers.
40
17
  */
41
18
  export function useLiquidityAmounts(
42
19
  minPrice: string,
@@ -47,68 +24,38 @@ export function useLiquidityAmounts(
47
24
  const [liquidityToken1Amount, setLiquidityToken1Amount] = useState<string>('');
48
25
  const [lastEditedToken, setLastEditedToken] = useState<'token0' | 'token1' | null>(null);
49
26
 
50
- // Memoize parsed price values to avoid repeated parsing
51
27
  const { minPriceNum, maxPriceNum, isValidPriceRange } = useMemo(() => {
52
28
  const parsedMin = Number.parseFloat(minPrice);
53
29
  const parsedMax = Number.parseFloat(maxPrice);
54
30
  const isValid = parsedMin > 0 && parsedMax > 0 && parsedMin < parsedMax;
55
-
56
- return {
57
- minPriceNum: parsedMin,
58
- maxPriceNum: parsedMax,
59
- isValidPriceRange: isValid,
60
- };
31
+ return { minPriceNum: parsedMin, maxPriceNum: parsedMax, isValidPriceRange: isValid };
61
32
  }, [minPrice, maxPrice]);
62
33
 
63
- // Memoize tick calculations - these only depend on prices and pool data
64
34
  const { tickLower, tickUpper, currentTick } = useMemo(() => {
65
35
  if (!poolData || !isValidPriceRange) {
66
- return {
67
- tickLower: null,
68
- tickUpper: null,
69
- currentTick: null,
70
- };
36
+ return { tickLower: null, tickUpper: null, currentTick: null };
71
37
  }
72
-
73
38
  try {
74
39
  const lower = ClService.priceToTick(minPriceNum, poolData.token0, poolData.token1, poolData.tickSpacing);
75
40
  const upper = ClService.priceToTick(maxPriceNum, poolData.token0, poolData.token1, poolData.tickSpacing);
76
-
77
- return {
78
- tickLower: lower,
79
- tickUpper: upper,
80
- currentTick: BigInt(poolData.currentTick),
81
- };
41
+ return { tickLower: lower, tickUpper: upper, currentTick: BigInt(poolData.currentTick) };
82
42
  } catch (err) {
83
43
  console.error('Failed to calculate ticks:', err);
84
- return {
85
- tickLower: null,
86
- tickUpper: null,
87
- currentTick: null,
88
- };
44
+ return { tickLower: null, tickUpper: null, currentTick: null };
89
45
  }
90
46
  }, [minPriceNum, maxPriceNum, poolData, isValidPriceRange]);
91
47
 
92
- // Auto-calculate token1 amount when token0 amount changes
93
48
  const handleToken0AmountChange = useCallback(
94
49
  (value: string): void => {
95
50
  setLiquidityToken0Amount(value);
96
51
  setLastEditedToken('token0');
97
52
 
98
- // Only calculate if we have all required values
99
- if (!value || !poolData || !tickLower || !tickUpper || !currentTick) {
100
- return;
101
- }
102
-
53
+ if (!value || !poolData || !tickLower || !tickUpper || !currentTick) return;
103
54
  const amount0 = Number.parseFloat(value);
104
-
105
- if (amount0 <= 0 || !isValidPriceRange) {
106
- return;
107
- }
55
+ if (amount0 <= 0 || !isValidPriceRange) return;
108
56
 
109
57
  try {
110
58
  const amount0BigInt = BigInt(Math.floor(amount0 * 10 ** poolData.token0.decimals));
111
-
112
59
  const amount1BigInt = ClService.calculateAmount1FromAmount0(
113
60
  amount0BigInt,
114
61
  tickLower,
@@ -116,7 +63,6 @@ export function useLiquidityAmounts(
116
63
  currentTick,
117
64
  poolData.sqrtPriceX96,
118
65
  );
119
-
120
66
  const amount1 = Number(amount1BigInt) / 10 ** poolData.token1.decimals;
121
67
  setLiquidityToken1Amount(amount1.toFixed(6));
122
68
  } catch (err) {
@@ -126,26 +72,17 @@ export function useLiquidityAmounts(
126
72
  [poolData, tickLower, tickUpper, currentTick, isValidPriceRange],
127
73
  );
128
74
 
129
- // Auto-calculate token0 amount when token1 amount changes
130
75
  const handleToken1AmountChange = useCallback(
131
76
  (value: string): void => {
132
77
  setLiquidityToken1Amount(value);
133
78
  setLastEditedToken('token1');
134
79
 
135
- // Only calculate if we have all required values
136
- if (!value || !poolData || !tickLower || !tickUpper || !currentTick) {
137
- return;
138
- }
139
-
80
+ if (!value || !poolData || !tickLower || !tickUpper || !currentTick) return;
140
81
  const amount1 = Number.parseFloat(value);
141
-
142
- if (amount1 <= 0 || !isValidPriceRange) {
143
- return;
144
- }
82
+ if (amount1 <= 0 || !isValidPriceRange) return;
145
83
 
146
84
  try {
147
85
  const amount1BigInt = BigInt(Math.floor(amount1 * 10 ** poolData.token1.decimals));
148
-
149
86
  const amount0BigInt = ClService.calculateAmount0FromAmount1(
150
87
  amount1BigInt,
151
88
  tickLower,
@@ -153,7 +90,6 @@ export function useLiquidityAmounts(
153
90
  currentTick,
154
91
  poolData.sqrtPriceX96,
155
92
  );
156
-
157
93
  const amount0 = Number(amount0BigInt) / 10 ** poolData.token0.decimals;
158
94
  setLiquidityToken0Amount(amount0.toFixed(6));
159
95
  } catch (err) {
@@ -163,13 +99,8 @@ export function useLiquidityAmounts(
163
99
  [poolData, tickLower, tickUpper, currentTick, isValidPriceRange],
164
100
  );
165
101
 
166
- // Recalculate amounts when price range changes
167
102
  useEffect(() => {
168
- if (!poolData || !tickLower || !tickUpper || !lastEditedToken || !isValidPriceRange) {
169
- return;
170
- }
171
-
172
- // Recalculate based on which token was last edited
103
+ if (!poolData || !tickLower || !tickUpper || !lastEditedToken || !isValidPriceRange) return;
173
104
  if (lastEditedToken === 'token0' && liquidityToken0Amount) {
174
105
  handleToken0AmountChange(liquidityToken0Amount);
175
106
  } else if (lastEditedToken === 'token1' && liquidityToken1Amount) {
@@ -1,90 +1,68 @@
1
- import { type QueryObserverOptions, useQuery, type UseQueryResult } from '@tanstack/react-query';
2
- import type { PoolData, PoolKey, SpokeProvider } from '@sodax/sdk';
3
- import { useSodaxContext } from '../shared/useSodaxContext';
1
+ import type { PoolData, PoolKey } from '@sodax/sdk';
2
+ import type { SpokeChainKey } from '@sodax/sdk';
3
+ import { useQuery, type UseQueryResult } from '@tanstack/react-query';
4
+ import { erc20Abi } from 'viem';
5
+ import { useSodaxContext } from '../shared/useSodaxContext.js';
6
+ import type { ReadHookParams } from '../shared/types.js';
4
7
 
5
- export interface UsePoolBalancesResponse {
8
+ export type UsePoolBalancesResponse = {
6
9
  token0Balance: bigint;
7
10
  token1Balance: bigint;
8
- }
11
+ };
9
12
 
10
- export interface UsePoolBalancesProps {
11
- poolData: PoolData | null;
12
- poolKey: PoolKey | null;
13
- spokeProvider: SpokeProvider | null;
14
- enabled?: boolean;
15
- queryOptions?: QueryObserverOptions<UsePoolBalancesResponse, Error>;
16
- }
13
+ export type UsePoolBalancesParams = ReadHookParams<
14
+ UsePoolBalancesResponse,
15
+ {
16
+ poolData: PoolData | null;
17
+ poolKey: PoolKey | null;
18
+ spokeChainKey: SpokeChainKey | undefined;
19
+ userAddress: string | undefined;
20
+ }
21
+ >;
17
22
 
18
23
  /**
19
- * React hook to query a user's token balances for a DEX pool.
20
- *
21
- * Given the pool data (with token addresses), the pool's key, and a SpokeProvider,
22
- * fetches the user's protocol balances for both token0 and token1 for the specified pool.
23
- * Queries are auto-refreshed; advanced options can be customized via `queryOptions`.
24
- *
25
- * @param {UsePoolBalancesProps} props
26
- * Object containing:
27
- * - `poolData`: {PoolData | null} - Pool info (must include token0 and token1 addresses). Required unless disabling.
28
- * - `poolKey`: {PoolKey | null} - Unique key for the DEX pool. Required unless disabling.
29
- * - `spokeProvider`: {SpokeProvider | null} - Provider instance for the chain. Required unless disabling.
30
- * - `enabled`: {boolean} (optional) - Whether to enable the query. Defaults to `true` if all other arguments are provided.
31
- * - `queryOptions`: {QueryObserverOptions<UsePoolBalancesResponse, Error>} (optional) - Advanced react-query options.
32
- *
33
- * @returns {UseQueryResult<UsePoolBalancesResponse, Error>}
34
- * React Query result object:
35
- * - `data`: `{ token0Balance: bigint, token1Balance: bigint }` if loaded, undefined otherwise.
36
- * - `isLoading`, `isError`, etc. for status handling.
37
- *
38
- * @remarks
39
- * - Throws an error if any of `poolData`, `poolKey`, or `spokeProvider` is missing when enabled.
40
- * - Suitable for tracking current protocol/wallet balances for both pool tokens.
41
- * - The hook is designed for use within a React component tree that provides the Sodax context.
42
- * - Data are automatically refreshed at the provided or default polling interval (default: refetch every 10s).
43
- *
44
- * @example
45
- * ```typescript
46
- * const { data, isLoading } = usePoolBalances({ poolData, poolKey, spokeProvider });
47
- * if (data) {
48
- * console.log('Balances:', data.token0Balance, data.token1Balance);
49
- * }
50
- * ```
24
+ * React hook to query the user's hub-side deposit balances for both pool tokens. Derives the hub
25
+ * wallet once and reads both pool-token balances in parallel via the hub `publicClient`.
51
26
  */
52
27
  export function usePoolBalances({
53
- poolData,
54
- poolKey,
55
- spokeProvider,
56
- enabled = true,
57
- queryOptions = {
58
- queryKey: [
59
- 'dex',
60
- 'poolBalances',
61
- poolData?.poolKey,
62
- spokeProvider?.chainConfig.chain.id,
63
- ],
64
- enabled: enabled && poolData !== null && poolKey !== null && spokeProvider !== null,
65
- staleTime: 5000, // Consider data stale after 5 seconds
66
- refetchInterval: 10000, // Refetch every 10 seconds
67
- },
68
- }: UsePoolBalancesProps): UseQueryResult<UsePoolBalancesResponse, Error> {
28
+ params,
29
+ queryOptions,
30
+ }: UsePoolBalancesParams = {}): UseQueryResult<UsePoolBalancesResponse, Error> {
69
31
  const { sodax } = useSodaxContext();
32
+ const poolData = params?.poolData ?? null;
33
+ const poolKey = params?.poolKey ?? null;
34
+ const spokeChainKey = params?.spokeChainKey;
35
+ const userAddress = params?.userAddress;
70
36
 
71
- return useQuery({
72
- ...queryOptions,
37
+ return useQuery<UsePoolBalancesResponse, Error>({
38
+ queryKey: ['dex', 'poolBalances', poolData?.poolId, spokeChainKey, userAddress],
73
39
  queryFn: async () => {
74
- if (!poolData || !spokeProvider || !poolKey) {
75
- throw new Error('Pool data, pool key, and spoke provider are required');
40
+ if (!poolData || !poolKey || !spokeChainKey || !userAddress) {
41
+ throw new Error('poolData, poolKey, spokeChainKey, and userAddress are required');
76
42
  }
77
43
 
78
- // Get balances from AssetService
79
- const [balance0, balance1] = await Promise.all([
80
- sodax.dex.assetService.getDeposit(poolData.token0.address, spokeProvider),
81
- sodax.dex.assetService.getDeposit(poolData.token1.address, spokeProvider),
44
+ const hubWallet = await sodax.hubProvider.getUserHubWalletAddress(userAddress, spokeChainKey);
45
+
46
+ const [token0Balance, token1Balance] = await Promise.all([
47
+ sodax.hubProvider.publicClient.readContract({
48
+ address: poolData.token0.address,
49
+ abi: erc20Abi,
50
+ functionName: 'balanceOf',
51
+ args: [hubWallet],
52
+ }),
53
+ sodax.hubProvider.publicClient.readContract({
54
+ address: poolData.token1.address,
55
+ abi: erc20Abi,
56
+ functionName: 'balanceOf',
57
+ args: [hubWallet],
58
+ }),
82
59
  ]);
83
60
 
84
- return {
85
- token0Balance: balance0,
86
- token1Balance: balance1,
87
- };
61
+ return { token0Balance, token1Balance };
88
62
  },
63
+ enabled: !!poolData && !!poolKey && !!spokeChainKey && !!userAddress,
64
+ staleTime: 5_000,
65
+ refetchInterval: 10_000,
66
+ ...queryOptions,
89
67
  });
90
68
  }
@@ -1,57 +1,31 @@
1
- import { type QueryObserverOptions, useQuery, type UseQueryResult } from '@tanstack/react-query';
2
1
  import type { PoolData, PoolKey } from '@sodax/sdk';
3
- import { useSodaxContext } from '../shared/useSodaxContext';
2
+ import { useQuery, type UseQueryResult } from '@tanstack/react-query';
3
+ import { useSodaxContext } from '../shared/useSodaxContext.js';
4
+ import type { ReadHookParams } from '../shared/types.js';
4
5
 
5
- export type UsePoolDataProps = {
6
- poolKey: PoolKey | null;
7
- enabled?: boolean;
8
- queryOptions?: QueryObserverOptions<PoolData, Error>;
9
- };
6
+ export type UsePoolDataParams = ReadHookParams<PoolData, { poolKey: PoolKey | null }>;
10
7
 
11
8
  /**
12
- * React hook to fetch on-chain data for a given DEX pool.
13
- *
14
- * @param {UsePoolDataProps} props - The props object:
15
- * - `poolKey`: PoolKey | null — The unique identifier for the pool to fetch data for. If null, disables the query.
16
- * - `enabled`: boolean (optional) — Whether the query is enabled. Defaults to enabled if a poolKey is provided, otherwise false.
17
- * - `queryOptions`: QueryObserverOptions<PoolData, Error> (optional) — Additional React Query options (e.g., staleTime, refetchInterval).
18
- *
19
- * @returns {UseQueryResult<PoolData, Error>} React Query result containing pool data (`data`), loading state (`isLoading`), error (`error`), and status fields.
20
- *
21
- * @example
22
- * ```typescript
23
- * const { data: poolData, isLoading, error } = usePoolData({ poolKey });
24
- * if (isLoading) return <div>Loading…</div>;
25
- * if (error) return <div>Error!</div>;
26
- * if (poolData) {
27
- * // poolData is available
28
- * }
29
- * ```
30
- *
31
- * @remarks
32
- * - Refetches pool data every 30 seconds by default, and may be configured via `queryOptions`.
33
- * - If `poolKey` is `null`, the query is disabled and no network request is performed.
34
- * - Throws an error if `poolKey` is missing when the query is enabled.
9
+ * React hook to fetch on-chain pool data (sqrt price, tick, fees, token info, etc.) for a given
10
+ * pool key. Reads via the hub `publicClient`. Disabled when `poolKey` is null.
35
11
  */
36
- export function usePoolData({
37
- poolKey,
38
- queryOptions = {
39
- queryKey: ['dex', 'poolData', poolKey],
40
- enabled: poolKey !== null,
41
- staleTime: 10000,
42
- refetchInterval: 30000,
43
- },
44
- }: UsePoolDataProps): UseQueryResult<PoolData, Error> {
12
+ export function usePoolData({ params, queryOptions }: UsePoolDataParams = {}): UseQueryResult<PoolData, Error> {
45
13
  const { sodax } = useSodaxContext();
14
+ const poolKey = params?.poolKey ?? null;
46
15
 
47
- return useQuery({
48
- ...queryOptions,
49
- queryFn: async (): Promise<PoolData> => {
16
+ return useQuery<PoolData, Error>({
17
+ queryKey: ['dex', 'poolData', poolKey],
18
+ queryFn: async () => {
50
19
  if (!poolKey) {
51
20
  throw new Error('Pool key is required');
52
21
  }
53
- return await sodax.dex.clService.getPoolData(poolKey, sodax.hubProvider.publicClient);
22
+ const result = await sodax.dex.clService.getPoolData(poolKey, sodax.hubProvider.publicClient);
23
+ if (!result.ok) throw result.error;
24
+ return result.value;
54
25
  },
55
26
  enabled: poolKey !== null,
27
+ staleTime: 10_000,
28
+ refetchInterval: 30_000,
29
+ ...queryOptions,
56
30
  });
57
31
  }
@@ -1,48 +1,21 @@
1
- import { type QueryObserverOptions, useQuery, type UseQueryResult } from '@tanstack/react-query';
2
1
  import type { PoolKey } from '@sodax/sdk';
3
- import { useSodaxContext } from '../shared/useSodaxContext';
2
+ import { useQuery, type UseQueryResult } from '@tanstack/react-query';
3
+ import { useSodaxContext } from '../shared/useSodaxContext.js';
4
+ import type { ReadHookParams } from '../shared/types.js';
4
5
 
5
- export type UsePoolsProps = {
6
- /**
7
- * Optional react-query QueryObserverOptions for customizing query behavior such as
8
- * staleTime, refetchInterval, cacheTime, etc. These are merged with sensible defaults.
9
- */
10
- queryOptions?: QueryObserverOptions<PoolKey[], Error>;
11
- };
6
+ export type UsePoolsParams = ReadHookParams<PoolKey[]>;
12
7
 
13
8
  /**
14
- * Loads and caches the available list of pools from the DEX service's ConcentratedLiquidityService.
15
- *
16
- * By default, the query result is cached indefinitely (with `staleTime` set to Infinity), reflecting the
17
- * assumption that the pools list is mostly static.
18
- *
19
- * @param params
20
- * Optional configuration object:
21
- * - queryOptions: Partial QueryObserverOptions for react-query (merged with built-in defaults).
22
- *
23
- * @returns
24
- * A UseQueryResult object from @tanstack/react-query containing:
25
- * - `data`: Array of PoolKey objects or undefined if not loaded or errored.
26
- * - Status fields: `isLoading`, `isError`, `error`, etc.
27
- *
28
- * @example
29
- * const { data: pools, isLoading, error } = usePools();
30
- * if (isLoading) return <div>Loading pools...</div>;
31
- * if (error) return <div>Error: {error.message}</div>;
32
- * if (pools) pools.forEach((pool, idx) => console.log(pool.id, pool.fee));
9
+ * Loads the list of concentrated-liquidity pools known to the SDK config. The SDK's `getPools()`
10
+ * is synchronous in v2 (no network), so this hook caches indefinitely by default.
33
11
  */
34
- export function usePools(params?: UsePoolsProps): UseQueryResult<PoolKey[], Error> {
12
+ export function usePools({ queryOptions }: UsePoolsParams = {}): UseQueryResult<PoolKey[], Error> {
35
13
  const { sodax } = useSodaxContext();
36
- const defaultQueryOptions = {
37
- queryKey: ['dex', 'pools'],
38
- staleTime: Number.POSITIVE_INFINITY, // Pools list is static, cache indefinitely
39
- };
40
- const queryOptions = { ...defaultQueryOptions, ...params?.queryOptions };
41
14
 
42
- return useQuery({
15
+ return useQuery<PoolKey[], Error>({
16
+ queryKey: ['dex', 'pools'],
17
+ queryFn: () => sodax.dex.clService.getPools(),
18
+ staleTime: Number.POSITIVE_INFINITY,
43
19
  ...queryOptions,
44
- queryFn: async (): Promise<PoolKey[]> => {
45
- return sodax.dex.clService.getPools();
46
- },
47
20
  });
48
21
  }
@@ -1,88 +1,53 @@
1
- import { type QueryObserverOptions, useQuery, type UseQueryResult } from '@tanstack/react-query';
2
1
  import type { ClPositionInfo, PoolKey } from '@sodax/sdk';
3
- import { useSodaxContext } from '../shared/useSodaxContext';
2
+ import { useQuery, type UseQueryResult } from '@tanstack/react-query';
3
+ import { useSodaxContext } from '../shared/useSodaxContext.js';
4
+ import type { ReadHookParams } from '../shared/types.js';
4
5
 
5
- export interface UsePositionInfoResponse {
6
+ export type UsePositionInfoResponse = {
6
7
  positionInfo: ClPositionInfo;
7
8
  isValid: boolean;
8
- }
9
+ };
9
10
 
10
- export interface UsePositionInfoProps {
11
- tokenId: string | null;
12
- poolKey: PoolKey | null;
13
- queryOptions?: QueryObserverOptions<UsePositionInfoResponse, Error>;
14
- }
11
+ export type UsePositionInfoParams = ReadHookParams<
12
+ UsePositionInfoResponse,
13
+ {
14
+ tokenId: string | null;
15
+ poolKey: PoolKey | null;
16
+ }
17
+ >;
15
18
 
16
19
  /**
17
- * React hook to fetch and validate CL position details by position NFT token ID.
18
- *
19
- * Fetches position data on-chain for a given tokenId, and checks if it matches the expected PoolKey.
20
- * This is commonly used in DEX dashboards to show or pre-validate user positions by ID.
21
- *
22
- * @param {string | null} tokenId
23
- * Position NFT token ID to query, as a string. Pass `null` or empty string to disable.
24
- * @param {PoolKey | null} poolKey
25
- * PoolKey to match against the position's underlying pool. Pass `null` to disable.
26
- * @param {QueryObserverOptions<UsePositionInfoResponse, Error>} [queryOptions]
27
- * Optional react-query options for polling/refresh and config. Merged with sensible defaults.
28
- *
29
- * @returns {UseQueryResult<UsePositionInfoResponse, Error>}
30
- * Standard React Query result object:
31
- * - `data`: { positionInfo, isValid } if loaded, or undefined if not loaded/error
32
- * - `isLoading`: boolean (query active)
33
- * - `isError`: boolean (query failed)
34
- * - ...other react-query helpers (refetch, status, etc)
35
- *
36
- * @example
37
- * ```typescript
38
- * const { data, isLoading, error } = usePositionInfo({ tokenId, poolKey });
39
- * if (isLoading) return <div>Loading position...</div>;
40
- * if (error) return <div>Error: {error.message}</div>;
41
- * if (data) {
42
- * console.log('Valid for pool:', data.isValid);
43
- * console.log('Liquidity:', data.positionInfo.liquidity);
44
- * }
45
- * ```
46
- *
47
- * @remarks
48
- * - Validates the underlying position's pool definition (currency0, currency1, fee) with the supplied PoolKey.
49
- * - Returns `isValid: false` if any field mismatches.
50
- * - Pass `null` as tokenId or poolKey to disable the query.
51
- * - Defaults: 10s stale, not enabled if missing arguments. Customizable via `queryOptions`.
52
- * - Throws error if called with invalid/null tokenId or poolKey when enabled.
20
+ * React hook to fetch a CL position by NFT token id and validate it against an expected pool key.
21
+ * Reads via the hub `publicClient`. Disabled when `tokenId` or `poolKey` is missing.
53
22
  */
54
23
  export function usePositionInfo({
55
- tokenId,
56
- poolKey,
57
- queryOptions = {
58
- queryKey: ['dex', 'positionInfo', tokenId, poolKey],
59
- enabled: tokenId !== null && poolKey !== null && tokenId !== '',
60
- staleTime: 10000, // Consider data stale after 10 seconds
61
- },
62
- }: UsePositionInfoProps): UseQueryResult<UsePositionInfoResponse, Error> {
24
+ params,
25
+ queryOptions,
26
+ }: UsePositionInfoParams = {}): UseQueryResult<UsePositionInfoResponse, Error> {
63
27
  const { sodax } = useSodaxContext();
28
+ const tokenId = params?.tokenId ?? null;
29
+ const poolKey = params?.poolKey ?? null;
64
30
 
65
- return useQuery({
31
+ return useQuery<UsePositionInfoResponse, Error>({
32
+ queryKey: ['dex', 'positionInfo', tokenId, poolKey],
66
33
  queryFn: async () => {
67
34
  if (!tokenId || !poolKey) {
68
35
  throw new Error('Token ID and pool key are required');
69
36
  }
70
37
 
71
- const tokenIdBigInt = BigInt(tokenId);
72
- const publicClient = sodax.hubProvider.publicClient;
73
- const info = await sodax.dex.clService.getPositionInfo(tokenIdBigInt, publicClient);
38
+ const infoResult = await sodax.dex.clService.getPositionInfo(BigInt(tokenId), sodax.hubProvider.publicClient);
39
+ if (!infoResult.ok) throw infoResult.error;
40
+ const info = infoResult.value;
74
41
 
75
- // Validate that position belongs to current pool
76
42
  const isValid =
77
43
  info.poolKey.currency0.toLowerCase() === poolKey.currency0.toLowerCase() &&
78
44
  info.poolKey.currency1.toLowerCase() === poolKey.currency1.toLowerCase() &&
79
45
  info.poolKey.fee === poolKey.fee;
80
46
 
81
- return {
82
- positionInfo: info,
83
- isValid,
84
- };
47
+ return { positionInfo: info, isValid };
85
48
  },
49
+ enabled: tokenId !== null && tokenId !== '' && poolKey !== null,
50
+ staleTime: 10_000,
86
51
  ...queryOptions,
87
52
  });
88
53
  }