@sodax/dapp-kit 1.5.6-beta → 2.0.0-rc.1
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.
- package/README.md +300 -422
- package/ai-exported/AGENTS.md +134 -0
- package/ai-exported/integration/README.md +49 -0
- package/ai-exported/integration/ai-rules.md +79 -0
- package/ai-exported/integration/architecture.md +274 -0
- package/ai-exported/integration/features/README.md +29 -0
- package/ai-exported/integration/features/auxiliary-services.md +169 -0
- package/ai-exported/integration/features/bitcoin.md +87 -0
- package/ai-exported/integration/features/bridge.md +91 -0
- package/ai-exported/integration/features/dex.md +152 -0
- package/ai-exported/integration/features/migration.md +118 -0
- package/ai-exported/integration/features/money-market.md +116 -0
- package/ai-exported/integration/features/staking.md +123 -0
- package/ai-exported/integration/features/swap.md +101 -0
- package/ai-exported/integration/quickstart.md +187 -0
- package/ai-exported/integration/recipes/README.md +136 -0
- package/ai-exported/integration/recipes/backend-queries.md +157 -0
- package/ai-exported/integration/recipes/bitcoin.md +193 -0
- package/ai-exported/integration/recipes/bridge.md +174 -0
- package/ai-exported/integration/recipes/dex.md +204 -0
- package/ai-exported/integration/recipes/invalidations.md +115 -0
- package/ai-exported/integration/recipes/migration.md +212 -0
- package/ai-exported/integration/recipes/money-market.md +206 -0
- package/ai-exported/integration/recipes/mutation-error-handling.md +118 -0
- package/ai-exported/integration/recipes/observability.md +93 -0
- package/ai-exported/integration/recipes/setup.md +144 -0
- package/ai-exported/integration/recipes/staking.md +202 -0
- package/ai-exported/integration/recipes/swap.md +272 -0
- package/ai-exported/integration/recipes/wallet-connectivity.md +101 -0
- package/ai-exported/integration/reference/README.md +12 -0
- package/ai-exported/integration/reference/glossary.md +188 -0
- package/ai-exported/integration/reference/hooks-index.md +194 -0
- package/ai-exported/integration/reference/public-api.md +110 -0
- package/ai-exported/integration/reference/querykey-conventions.md +179 -0
- package/ai-exported/migration/README.md +60 -0
- package/ai-exported/migration/ai-rules.md +81 -0
- package/ai-exported/migration/breaking-changes/hook-signatures.md +233 -0
- package/ai-exported/migration/breaking-changes/querykey-conventions.md +108 -0
- package/ai-exported/migration/breaking-changes/result-handling.md +211 -0
- package/ai-exported/migration/breaking-changes/sdk-leakage.md +165 -0
- package/ai-exported/migration/checklist.md +89 -0
- package/ai-exported/migration/features/README.md +34 -0
- package/ai-exported/migration/features/auxiliary-services.md +114 -0
- package/ai-exported/migration/features/bitcoin.md +88 -0
- package/ai-exported/migration/features/bridge.md +123 -0
- package/ai-exported/migration/features/dex.md +101 -0
- package/ai-exported/migration/features/migration.md +120 -0
- package/ai-exported/migration/features/money-market.md +97 -0
- package/ai-exported/migration/features/staking.md +109 -0
- package/ai-exported/migration/features/swap.md +118 -0
- package/ai-exported/migration/recipes.md +188 -0
- package/ai-exported/migration/reference/README.md +15 -0
- package/ai-exported/migration/reference/deleted-hooks.md +110 -0
- package/ai-exported/migration/reference/error-shape-crosswalk.md +144 -0
- package/ai-exported/migration/reference/renamed-hooks.md +66 -0
- package/dist/index.cjs +2642 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1550 -0
- package/dist/index.d.ts +1020 -2051
- package/dist/index.mjs +1594 -1532
- package/dist/index.mjs.map +1 -1
- package/package.json +20 -10
- package/src/contexts/index.ts +0 -3
- package/src/hooks/_mutationContract.test.ts +99 -0
- package/src/hooks/backend/README.md +2 -2
- package/src/hooks/backend/index.ts +13 -13
- package/src/hooks/backend/unwrapResult.ts +1 -0
- package/src/hooks/backend/useBackendAllMoneyMarketAssets.ts +13 -45
- package/src/hooks/backend/useBackendAllMoneyMarketBorrowers.ts +29 -59
- package/src/hooks/backend/useBackendIntentByHash.ts +21 -47
- package/src/hooks/backend/useBackendIntentByTxHash.ts +23 -50
- package/src/hooks/backend/useBackendMoneyMarketAsset.ts +21 -54
- package/src/hooks/backend/useBackendMoneyMarketAssetBorrowers.ts +30 -57
- package/src/hooks/backend/useBackendMoneyMarketAssetSuppliers.ts +31 -58
- package/src/hooks/backend/useBackendMoneyMarketPosition.ts +22 -38
- package/src/hooks/backend/useBackendOrderbook.ts +27 -49
- package/src/hooks/backend/useBackendSubmitSwapTx.ts +30 -36
- package/src/hooks/backend/useBackendSubmitSwapTxStatus.ts +38 -58
- package/src/hooks/backend/useBackendUserIntents.ts +25 -63
- package/src/hooks/bitcoin/index.ts +9 -8
- package/src/hooks/bitcoin/useBitcoinBalance.ts +20 -5
- package/src/hooks/bitcoin/useExpiredUtxos.ts +26 -16
- package/src/hooks/bitcoin/useFundTradingWallet.ts +33 -30
- package/src/hooks/bitcoin/useRadfiAuth.ts +43 -40
- package/src/hooks/bitcoin/useRadfiSession.ts +53 -59
- package/src/hooks/bitcoin/useRadfiWithdraw.ts +35 -53
- package/src/hooks/bitcoin/useRenewUtxos.ts +30 -50
- package/src/hooks/bitcoin/useTradingWallet.ts +1 -1
- package/src/hooks/bitcoin/useTradingWalletBalance.ts +25 -14
- package/src/hooks/bridge/index.ts +5 -5
- package/src/hooks/bridge/useBridge.ts +29 -55
- package/src/hooks/bridge/useBridgeAllowance.ts +38 -38
- package/src/hooks/bridge/useBridgeApprove.ts +32 -57
- package/src/hooks/bridge/useGetBridgeableAmount.ts +23 -37
- package/src/hooks/bridge/useGetBridgeableTokens.ts +27 -50
- package/src/hooks/dex/index.ts +16 -16
- package/src/hooks/dex/useClaimRewards.ts +35 -54
- package/src/hooks/dex/useCreateDecreaseLiquidityParams.ts +7 -20
- package/src/hooks/dex/useCreateDepositParams.ts +7 -21
- package/src/hooks/dex/useCreateSupplyLiquidityParams.ts +13 -28
- package/src/hooks/dex/useCreateWithdrawParams.ts +7 -20
- package/src/hooks/dex/useDecreaseLiquidity.ts +40 -66
- package/src/hooks/dex/useDexAllowance.ts +29 -75
- package/src/hooks/dex/useDexApprove.ts +32 -43
- package/src/hooks/dex/useDexDeposit.ts +42 -49
- package/src/hooks/dex/useDexWithdraw.ts +32 -43
- package/src/hooks/dex/useLiquidityAmounts.ts +27 -84
- package/src/hooks/dex/usePoolBalances.ts +50 -72
- package/src/hooks/dex/usePoolData.ts +17 -43
- package/src/hooks/dex/usePools.ts +11 -38
- package/src/hooks/dex/usePositionInfo.ts +27 -62
- package/src/hooks/dex/useSupplyLiquidity.ts +80 -75
- package/src/hooks/index.ts +12 -10
- package/src/hooks/migrate/index.ts +13 -4
- package/src/hooks/migrate/useMigrateBaln.ts +42 -0
- package/src/hooks/migrate/useMigrateIcxToSoda.ts +44 -0
- package/src/hooks/migrate/useMigratebnUSD.ts +47 -0
- package/src/hooks/migrate/useMigrationAllowance.ts +76 -0
- package/src/hooks/migrate/useMigrationApprove.ts +66 -0
- package/src/hooks/migrate/useRevertMigrateSodaToIcx.ts +39 -0
- package/src/hooks/mm/index.ts +14 -12
- package/src/hooks/mm/useAToken.ts +25 -41
- package/src/hooks/mm/useATokensBalances.ts +29 -60
- package/src/hooks/mm/useBorrow.ts +38 -56
- package/src/hooks/mm/useMMAllowance.ts +37 -73
- package/src/hooks/mm/useMMApprove.ts +36 -43
- package/src/hooks/mm/useRepay.ts +33 -53
- package/src/hooks/mm/useReservesData.ts +12 -38
- package/src/hooks/mm/useReservesHumanized.ts +12 -31
- package/src/hooks/mm/useReservesList.ts +11 -31
- package/src/hooks/mm/useReservesUsdFormat.ts +15 -35
- package/src/hooks/mm/useSupply.ts +45 -51
- package/src/hooks/mm/useUserFormattedSummary.ts +32 -84
- package/src/hooks/mm/useUserReservesData.ts +27 -77
- package/src/hooks/mm/useWithdraw.ts +38 -54
- package/src/hooks/partner/index.ts +6 -0
- package/src/hooks/partner/useApproveToken.ts +42 -0
- package/src/hooks/partner/useFeeClaimSwap.ts +38 -0
- package/src/hooks/partner/useFetchAssetsBalances.ts +37 -0
- package/src/hooks/partner/useGetAutoSwapPreferences.ts +37 -0
- package/src/hooks/partner/useIsTokenApproved.ts +39 -0
- package/src/hooks/partner/useSetSwapPreference.ts +50 -0
- package/src/hooks/provider/index.ts +1 -2
- package/src/hooks/provider/useHubProvider.ts +1 -1
- package/src/hooks/recovery/index.ts +2 -0
- package/src/hooks/recovery/useHubAssetBalances.ts +43 -0
- package/src/hooks/recovery/useWithdrawHubAsset.ts +48 -0
- package/src/hooks/shared/index.ts +10 -6
- package/src/hooks/shared/types.ts +77 -0
- package/src/hooks/shared/unwrapResult.ts +19 -0
- package/src/hooks/shared/useDeriveUserWalletAddress.ts +22 -40
- package/src/hooks/shared/useEstimateGas.ts +18 -15
- package/src/hooks/shared/useGetUserHubWalletAddress.ts +25 -26
- package/src/hooks/shared/useRequestTrustline.ts +28 -61
- package/src/hooks/shared/useSafeMutation.test.ts +43 -0
- package/src/hooks/shared/useSafeMutation.ts +68 -0
- package/src/hooks/shared/useSodaxContext.ts +1 -1
- package/src/hooks/shared/useStellarTrustlineCheck.ts +30 -64
- package/src/hooks/shared/useXBalances.test.ts +113 -0
- package/src/hooks/shared/useXBalances.ts +61 -0
- package/src/hooks/staking/index.ts +18 -18
- package/src/hooks/staking/useCancelUnstake.ts +30 -41
- package/src/hooks/staking/useClaim.ts +27 -36
- package/src/hooks/staking/useConvertedAssets.ts +24 -34
- package/src/hooks/staking/useInstantUnstake.ts +33 -40
- package/src/hooks/staking/useInstantUnstakeAllowance.ts +37 -45
- package/src/hooks/staking/useInstantUnstakeApprove.ts +42 -42
- package/src/hooks/staking/useInstantUnstakeRatio.ts +24 -41
- package/src/hooks/staking/useStake.ts +32 -37
- package/src/hooks/staking/useStakeAllowance.ts +30 -43
- package/src/hooks/staking/useStakeApprove.ts +40 -40
- package/src/hooks/staking/useStakeRatio.ts +24 -40
- package/src/hooks/staking/useStakingConfig.ts +14 -27
- package/src/hooks/staking/useStakingInfo.ts +30 -38
- package/src/hooks/staking/useUnstake.ts +29 -43
- package/src/hooks/staking/useUnstakeAllowance.ts +37 -44
- package/src/hooks/staking/useUnstakeApprove.ts +40 -43
- package/src/hooks/staking/useUnstakingInfo.ts +29 -41
- package/src/hooks/staking/useUnstakingInfoWithPenalty.ts +31 -47
- package/src/hooks/swap/index.ts +8 -8
- package/src/hooks/swap/useCancelLimitOrder.ts +24 -41
- package/src/hooks/swap/useCancelSwap.ts +24 -33
- package/src/hooks/swap/useCreateLimitOrder.ts +29 -62
- package/src/hooks/swap/useQuote.ts +17 -43
- package/src/hooks/swap/useStatus.ts +22 -29
- package/src/hooks/swap/useSwap.ts +31 -49
- package/src/hooks/swap/useSwapAllowance.ts +38 -35
- package/src/hooks/swap/useSwapApprove.ts +48 -57
- package/src/index.ts +5 -3
- package/src/providers/SodaxProvider.tsx +17 -11
- package/src/providers/createSodaxQueryClient.ts +96 -0
- package/src/providers/index.ts +2 -1
- package/src/utils/dex-utils.ts +27 -5
- package/src/utils/index.ts +1 -1
- package/dist/index.d.mts +0 -2581
- package/dist/index.js +0 -2562
- package/dist/index.js.map +0 -1
- package/src/hooks/migrate/types.ts +0 -15
- package/src/hooks/migrate/useMigrate.tsx +0 -110
- package/src/hooks/migrate/useMigrationAllowance.tsx +0 -79
- package/src/hooks/migrate/useMigrationApprove.tsx +0 -129
- 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
|
-
|
|
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,70 +24,45 @@ 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
|
-
|
|
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
|
-
|
|
113
|
-
|
|
59
|
+
const amount1BigInt = ClService.calculateAmount1FromAmount0(
|
|
60
|
+
amount0BigInt,
|
|
61
|
+
tickLower,
|
|
62
|
+
tickUpper,
|
|
63
|
+
currentTick,
|
|
64
|
+
poolData.sqrtPriceX96,
|
|
65
|
+
);
|
|
114
66
|
const amount1 = Number(amount1BigInt) / 10 ** poolData.token1.decimals;
|
|
115
67
|
setLiquidityToken1Amount(amount1.toFixed(6));
|
|
116
68
|
} catch (err) {
|
|
@@ -120,28 +72,24 @@ export function useLiquidityAmounts(
|
|
|
120
72
|
[poolData, tickLower, tickUpper, currentTick, isValidPriceRange],
|
|
121
73
|
);
|
|
122
74
|
|
|
123
|
-
// Auto-calculate token0 amount when token1 amount changes
|
|
124
75
|
const handleToken1AmountChange = useCallback(
|
|
125
76
|
(value: string): void => {
|
|
126
77
|
setLiquidityToken1Amount(value);
|
|
127
78
|
setLastEditedToken('token1');
|
|
128
79
|
|
|
129
|
-
|
|
130
|
-
if (!value || !poolData || !tickLower || !tickUpper || !currentTick) {
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
|
|
80
|
+
if (!value || !poolData || !tickLower || !tickUpper || !currentTick) return;
|
|
134
81
|
const amount1 = Number.parseFloat(value);
|
|
135
|
-
|
|
136
|
-
if (amount1 <= 0 || !isValidPriceRange) {
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
82
|
+
if (amount1 <= 0 || !isValidPriceRange) return;
|
|
139
83
|
|
|
140
84
|
try {
|
|
141
85
|
const amount1BigInt = BigInt(Math.floor(amount1 * 10 ** poolData.token1.decimals));
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
86
|
+
const amount0BigInt = ClService.calculateAmount0FromAmount1(
|
|
87
|
+
amount1BigInt,
|
|
88
|
+
tickLower,
|
|
89
|
+
tickUpper,
|
|
90
|
+
currentTick,
|
|
91
|
+
poolData.sqrtPriceX96,
|
|
92
|
+
);
|
|
145
93
|
const amount0 = Number(amount0BigInt) / 10 ** poolData.token0.decimals;
|
|
146
94
|
setLiquidityToken0Amount(amount0.toFixed(6));
|
|
147
95
|
} catch (err) {
|
|
@@ -151,13 +99,8 @@ export function useLiquidityAmounts(
|
|
|
151
99
|
[poolData, tickLower, tickUpper, currentTick, isValidPriceRange],
|
|
152
100
|
);
|
|
153
101
|
|
|
154
|
-
// Recalculate amounts when price range changes
|
|
155
102
|
useEffect(() => {
|
|
156
|
-
if (!poolData || !tickLower || !tickUpper || !lastEditedToken || !isValidPriceRange)
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Recalculate based on which token was last edited
|
|
103
|
+
if (!poolData || !tickLower || !tickUpper || !lastEditedToken || !isValidPriceRange) return;
|
|
161
104
|
if (lastEditedToken === 'token0' && liquidityToken0Amount) {
|
|
162
105
|
handleToken0AmountChange(liquidityToken0Amount);
|
|
163
106
|
} else if (lastEditedToken === 'token1' && liquidityToken1Amount) {
|
|
@@ -1,90 +1,68 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {
|
|
3
|
-
import {
|
|
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
|
|
8
|
+
export type UsePoolBalancesResponse = {
|
|
6
9
|
token0Balance: bigint;
|
|
7
10
|
token1Balance: bigint;
|
|
8
|
-
}
|
|
11
|
+
};
|
|
9
12
|
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
-
|
|
37
|
+
return useQuery<UsePoolBalancesResponse, Error>({
|
|
38
|
+
queryKey: ['dex', 'poolBalances', poolData?.poolId, spokeChainKey, userAddress],
|
|
73
39
|
queryFn: async () => {
|
|
74
|
-
if (!poolData || !
|
|
75
|
-
throw new Error('
|
|
40
|
+
if (!poolData || !poolKey || !spokeChainKey || !userAddress) {
|
|
41
|
+
throw new Error('poolData, poolKey, spokeChainKey, and userAddress are required');
|
|
76
42
|
}
|
|
77
43
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
sodax.
|
|
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 {
|
|
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
|
|
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
|
|
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
|
-
|
|
49
|
-
queryFn: async ()
|
|
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
|
-
|
|
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 {
|
|
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
|
|
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
|
|
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(
|
|
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 {
|
|
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
|
|
6
|
+
export type UsePositionInfoResponse = {
|
|
6
7
|
positionInfo: ClPositionInfo;
|
|
7
8
|
isValid: boolean;
|
|
8
|
-
}
|
|
9
|
+
};
|
|
9
10
|
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
|
72
|
-
|
|
73
|
-
const info =
|
|
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
|
}
|