@sodax/dapp-kit 1.3.1-beta-rc3 → 1.3.1-beta

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 (35) hide show
  1. package/README.md +36 -0
  2. package/dist/index.d.mts +581 -11
  3. package/dist/index.d.ts +581 -11
  4. package/dist/index.js +691 -62
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +672 -62
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +3 -3
  9. package/src/hooks/bitcoin/index.ts +1 -0
  10. package/src/hooks/bitcoin/useRadfiAuth.ts +7 -25
  11. package/src/hooks/bitcoin/useRadfiSession.ts +25 -47
  12. package/src/hooks/bitcoin/useRadfiWithdraw.ts +85 -0
  13. package/src/hooks/bitcoin/useRenewUtxos.ts +1 -1
  14. package/src/hooks/dex/index.ts +16 -0
  15. package/src/hooks/dex/useClaimRewards.ts +68 -0
  16. package/src/hooks/dex/useCreateDecreaseLiquidityParams.ts +41 -0
  17. package/src/hooks/dex/useCreateDepositParams.ts +43 -0
  18. package/src/hooks/dex/useCreateSupplyLiquidityParams.ts +84 -0
  19. package/src/hooks/dex/useCreateWithdrawParams.ts +44 -0
  20. package/src/hooks/dex/useDecreaseLiquidity.ts +78 -0
  21. package/src/hooks/dex/useDexAllowance.ts +87 -0
  22. package/src/hooks/dex/useDexApprove.ts +55 -0
  23. package/src/hooks/dex/useDexDeposit.ts +64 -0
  24. package/src/hooks/dex/useDexWithdraw.ts +54 -0
  25. package/src/hooks/dex/useLiquidityAmounts.ts +187 -0
  26. package/src/hooks/dex/usePoolBalances.ts +90 -0
  27. package/src/hooks/dex/usePoolData.ts +57 -0
  28. package/src/hooks/dex/usePools.ts +48 -0
  29. package/src/hooks/dex/usePositionInfo.ts +88 -0
  30. package/src/hooks/dex/useSupplyLiquidity.ts +91 -0
  31. package/src/hooks/index.ts +1 -0
  32. package/src/index.ts +1 -0
  33. package/src/utils/dex-utils.ts +177 -0
  34. package/src/utils/index.ts +1 -0
  35. package/src/hooks/bitcoin/radfiConstants.ts +0 -2
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sodax/dapp-kit",
3
3
  "license": "MIT",
4
- "version": "1.3.1-beta-rc3",
4
+ "version": "1.3.1-beta",
5
5
  "description": "dapp-kit of New World",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -16,8 +16,8 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "viem": "2.29.2",
19
- "@sodax/sdk": "1.3.1-beta-rc3",
20
- "@sodax/types": "1.3.1-beta-rc3"
19
+ "@sodax/sdk": "1.3.1-beta",
20
+ "@sodax/types": "1.3.1-beta"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/react": "19.0.8",
@@ -5,3 +5,4 @@ export * from './useBitcoinBalance';
5
5
  export * from './useTradingWalletBalance';
6
6
  export * from './useExpiredUtxos';
7
7
  export * from './useRenewUtxos';
8
+ export * from './useRadfiWithdraw';
@@ -1,14 +1,11 @@
1
1
  import type { BitcoinSpokeProvider } from '@sodax/sdk';
2
2
  import { useMutation, type UseMutationResult } from '@tanstack/react-query';
3
- import { ACCESS_TOKEN_TTL, REFRESH_TOKEN_TTL } from './radfiConstants';
4
3
 
5
4
  export type RadfiSession = {
6
5
  accessToken: string;
7
6
  refreshToken: string;
8
7
  tradingAddress: string;
9
8
  publicKey: string;
10
- accessTokenExpiry: number;
11
- refreshTokenExpiry: number;
12
9
  };
13
10
 
14
11
  type RadfiAuthResult = {
@@ -41,21 +38,9 @@ export function clearRadfiSession(address: string): void {
41
38
  } catch {}
42
39
  }
43
40
 
44
- export function isAccessTokenExpired(address: string): boolean {
45
- const session = loadRadfiSession(address);
46
- if (!session) return true;
47
- return Date.now() >= session.accessTokenExpiry;
48
- }
49
-
50
- export function isRefreshTokenExpired(address: string): boolean {
51
- const session = loadRadfiSession(address);
52
- if (!session) return true;
53
- return Date.now() >= session.refreshTokenExpiry;
54
- }
55
-
56
41
  /**
57
42
  * Hook to authenticate with Radfi using BIP322 message signing.
58
- * Saves full session (accessToken, refreshToken, tradingAddress, expiry) to localStorage.
43
+ * Saves session (accessToken, refreshToken, tradingAddress, publicKey) to localStorage.
59
44
  */
60
45
  export function useRadfiAuth(
61
46
  spokeProvider: BitcoinSpokeProvider | undefined,
@@ -78,8 +63,6 @@ export function useRadfiAuth(
78
63
  refreshToken,
79
64
  tradingAddress,
80
65
  publicKey,
81
- accessTokenExpiry: Date.now() + ACCESS_TOKEN_TTL,
82
- refreshTokenExpiry: Date.now() + REFRESH_TOKEN_TTL,
83
66
  };
84
67
 
85
68
  saveRadfiSession(walletAddress, session);
@@ -92,23 +75,22 @@ export function useRadfiAuth(
92
75
  err instanceof Error &&
93
76
  (err.message.includes('duplicatedPubKey') || err.message.includes('4008'));
94
77
 
95
- if (isAlreadyRegistered) {
96
- if (existingSession && !isRefreshTokenExpired(walletAddress)) {
97
- // Try silent refresh
78
+ if (isAlreadyRegistered && existingSession?.refreshToken) {
79
+ try {
98
80
  const refreshed = await spokeProvider.radfi.refreshAccessToken(existingSession.refreshToken);
99
81
  const session: RadfiSession = {
100
82
  ...existingSession,
101
83
  accessToken: refreshed.accessToken,
102
84
  refreshToken: refreshed.refreshToken,
103
- accessTokenExpiry: Date.now() + ACCESS_TOKEN_TTL,
104
- refreshTokenExpiry: Date.now() + REFRESH_TOKEN_TTL,
105
85
  };
106
- spokeProvider.setRadfiAccessToken(refreshed.accessToken);
86
+ spokeProvider.setRadfiAccessToken(refreshed.accessToken, refreshed.refreshToken);
107
87
  saveRadfiSession(walletAddress, session);
108
88
  return { accessToken: refreshed.accessToken, refreshToken: refreshed.refreshToken, tradingAddress: existingSession.tradingAddress };
89
+ } catch {
90
+ // Refresh also failed — clear stale session and guide user
91
+ clearRadfiSession(walletAddress);
109
92
  }
110
93
 
111
- // No valid session to refresh — guide the user
112
94
  throw new Error(
113
95
  'This wallet is already registered with Radfi from another session. ' +
114
96
  'Please clear your browser storage for this site and try again, ' +
@@ -5,13 +5,10 @@ import {
5
5
  loadRadfiSession,
6
6
  saveRadfiSession,
7
7
  clearRadfiSession,
8
- isAccessTokenExpired,
9
- isRefreshTokenExpired,
10
8
  type RadfiSession,
11
9
  } from './useRadfiAuth';
12
10
 
13
- import { ACCESS_TOKEN_TTL } from './radfiConstants';
14
- const POLL_INTERVAL = 30_000; // 30 s — access tokens expire every 10 min, no need to poll faster
11
+ const REFRESH_INTERVAL = 5 * 60 * 1000; // 5 min — refresh before access token expires (10 min TTL)
15
12
 
16
13
  export type UseRadfiSessionReturn = {
17
14
  walletAddress: string | undefined;
@@ -23,8 +20,9 @@ export type UseRadfiSessionReturn = {
23
20
 
24
21
  /**
25
22
  * Manages the full Radfi session lifecycle:
26
- * - Restores session from localStorage on mount
27
- * - Polls every 2s: silently refreshes accessToken before expiry, resets auth when refreshToken expires
23
+ * - On mount / wallet switch: refreshes token to validate session
24
+ * - Single interval (~5 min): refreshes access token. If refresh fails clears session, isAuthed=false
25
+ * - ensureRadfiAccessToken (SDK layer) acts as safety net before swap/bridge
28
26
  * - Exposes login() and isAuthed for UI
29
27
  */
30
28
  export function useRadfiSession(
@@ -52,17 +50,15 @@ export function useRadfiSession(
52
50
  ...session,
53
51
  accessToken,
54
52
  refreshToken,
55
- accessTokenExpiry: Date.now() + ACCESS_TOKEN_TTL,
56
- // Keep the original refreshTokenExpiry — don't roll it forward on every silent refresh
57
53
  };
58
54
 
59
55
  saveRadfiSession(address, updated);
60
- spokeProvider.setRadfiAccessToken(accessToken);
56
+ spokeProvider.setRadfiAccessToken(accessToken, refreshToken);
61
57
  setIsAuthed(true);
62
58
  setTradingAddress(updated.tradingAddress || undefined);
63
59
  } catch {
64
60
  clearRadfiSession(address);
65
- spokeProvider.setRadfiAccessToken('');
61
+ spokeProvider.setRadfiAccessToken('', '');
66
62
  setIsAuthed(false);
67
63
  setTradingAddress(undefined);
68
64
  } finally {
@@ -70,52 +66,34 @@ export function useRadfiSession(
70
66
  }
71
67
  }, [spokeProvider]);
72
68
 
73
- // ── Poll wallet address + restore session eagerly ────────────────────────
69
+ // ── On mount / wallet switch: reset state + refresh to validate session ──
74
70
  useEffect(() => {
75
71
  if (!spokeProvider) return;
76
72
 
77
- const fetchAndRestore = () => {
78
- spokeProvider.walletProvider.getWalletAddress()
79
- .then((addr) => {
80
- setWalletAddress(addr);
81
- // Eagerly restore session in the same tick to avoid extra render cycle
82
- const session = loadRadfiSession(addr);
83
- if (!session || isRefreshTokenExpired(addr)) return;
84
-
85
- if (!isAccessTokenExpired(addr)) {
86
- spokeProvider.setRadfiAccessToken(session.accessToken);
87
- setIsAuthed(true);
88
- setTradingAddress(session.tradingAddress || undefined);
89
- } else {
90
- // Access token expired but refresh valid — trigger silent refresh
91
- silentRefresh(addr);
92
- }
93
- })
94
- .catch(() => {});
95
- };
96
-
97
- fetchAndRestore();
98
- const id = setInterval(fetchAndRestore, 3000);
99
- return () => clearInterval(id);
73
+ // Reset state immediately to avoid stale data from previous wallet
74
+ setIsAuthed(false);
75
+ setTradingAddress(undefined);
76
+ setWalletAddress(undefined);
77
+
78
+ spokeProvider.walletProvider.getWalletAddress()
79
+ .then((addr) => {
80
+ setWalletAddress(addr);
81
+ const session = loadRadfiSession(addr);
82
+ if (!session?.refreshToken) return;
83
+
84
+ // Always refresh on mount to validate the session is actually valid
85
+ silentRefresh(addr);
86
+ })
87
+ .catch(() => {});
100
88
  }, [spokeProvider, silentRefresh]);
101
89
 
102
- // ── Polling: check expiry every 30s ──────────────────────────────────────
90
+ // ── Interval: refresh token every 5 min to keep access token fresh ──────
103
91
  useEffect(() => {
104
92
  if (!walletAddress || !spokeProvider) return;
105
93
 
106
94
  const id = setInterval(() => {
107
- if (isRefreshTokenExpired(walletAddress)) {
108
- clearRadfiSession(walletAddress);
109
- spokeProvider.setRadfiAccessToken('');
110
- setIsAuthed(false);
111
- setTradingAddress(undefined);
112
- return;
113
- }
114
-
115
- if (isAccessTokenExpired(walletAddress)) {
116
- silentRefresh(walletAddress);
117
- }
118
- }, POLL_INTERVAL);
95
+ silentRefresh(walletAddress);
96
+ }, REFRESH_INTERVAL);
119
97
 
120
98
  return () => clearInterval(id);
121
99
  }, [walletAddress, spokeProvider, silentRefresh]);
@@ -0,0 +1,85 @@
1
+ import { normalizePsbtToBase64, type BitcoinSpokeProvider } from '@sodax/sdk';
2
+ import { useMutation, useQueryClient, type UseMutationResult } from '@tanstack/react-query';
3
+ import { loadRadfiSession } from './useRadfiAuth';
4
+
5
+ type WithdrawToUserParams = {
6
+ amount: string;
7
+ tokenId: string;
8
+ withdrawTo: string;
9
+ };
10
+
11
+ type WithdrawResult = {
12
+ txId: string;
13
+ fee: number;
14
+ };
15
+
16
+ /**
17
+ * Hook to withdraw BTC from Radfi trading wallet to user's personal wallet.
18
+ *
19
+ * Flow:
20
+ * 1. Build withdraw transaction via Radfi API (returns unsigned PSBT)
21
+ * 2. User signs the PSBT with their wallet
22
+ * 3. Submit signed PSBT back to Radfi for co-signing and broadcasting
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * const { mutateAsync: withdraw, isPending } = useRadfiWithdraw(spokeProvider);
27
+ *
28
+ * const handleWithdraw = async () => {
29
+ * const result = await withdraw({
30
+ * amount: '10000',
31
+ * tokenId: '0:0',
32
+ * withdrawTo: 'bc1q...', // user's segwit address
33
+ * });
34
+ * console.log('Withdrawn:', result.txId);
35
+ * };
36
+ * ```
37
+ */
38
+ export function useRadfiWithdraw(
39
+ spokeProvider: BitcoinSpokeProvider | undefined,
40
+ ): UseMutationResult<WithdrawResult, Error, WithdrawToUserParams> {
41
+ const queryClient = useQueryClient();
42
+
43
+ return useMutation<WithdrawResult, Error, WithdrawToUserParams>({
44
+ mutationFn: async ({ amount, tokenId, withdrawTo }: WithdrawToUserParams) => {
45
+ if (!spokeProvider) {
46
+ throw new Error('Bitcoin spoke provider not found');
47
+ }
48
+
49
+ const userAddress = await spokeProvider.walletProvider.getWalletAddress();
50
+ const session = loadRadfiSession(userAddress);
51
+ const accessToken = session?.accessToken || spokeProvider.radfiAccessToken;
52
+
53
+ if (!accessToken) {
54
+ throw new Error('Radfi authentication required. Please login first.');
55
+ }
56
+
57
+ // Step 1: Build the withdraw transaction
58
+ const buildResult = await spokeProvider.radfi.withdrawToUser(
59
+ { userAddress, amount, tokenId, withdrawTo },
60
+ accessToken,
61
+ );
62
+
63
+ // Step 2: Sign the PSBT with user's wallet
64
+ const signedTx = await spokeProvider.walletProvider.signTransaction(
65
+ buildResult.base64Psbt,
66
+ false,
67
+ );
68
+
69
+ const signedBase64Tx = normalizePsbtToBase64(signedTx);
70
+
71
+ // Step 3: Submit to Radfi for co-signing and broadcasting
72
+ const txId = await spokeProvider.radfi.signAndBroadcastWithdraw(
73
+ { userAddress, signedBase64Tx },
74
+ accessToken,
75
+ );
76
+
77
+ return { txId, fee: buildResult.fee.totalFee };
78
+ },
79
+ onSuccess: () => {
80
+ queryClient.invalidateQueries({ queryKey: ['trading-wallet-balance'] });
81
+ queryClient.invalidateQueries({ queryKey: ['btc-balance'] });
82
+ queryClient.invalidateQueries({ queryKey: ['xBalances'] });
83
+ },
84
+ });
85
+ }
@@ -19,7 +19,7 @@ type RenewUtxosParams = {
19
19
  * const { mutateAsync: renewUtxos, isPending } = useRenewUtxos(spokeProvider);
20
20
  *
21
21
  * const handleRenew = async (expiredUtxos: RadfiUtxo[]) => {
22
- * const txIdVouts = expiredUtxos.map(u => `${u.txId}:${u.vout}`);
22
+ * const txIdVouts = expiredUtxos.map(u => u.txidVout);
23
23
  * const txId = await renewUtxos({ txIdVouts });
24
24
  * console.log('Renewed:', txId);
25
25
  * };
@@ -0,0 +1,16 @@
1
+ export * from './usePools';
2
+ export * from './usePoolData';
3
+ export * from './usePoolBalances';
4
+ export * from './usePositionInfo';
5
+ export * from './useDexDeposit';
6
+ export * from './useDexWithdraw';
7
+ export * from './useDexAllowance';
8
+ export * from './useDexApprove';
9
+ export * from './useLiquidityAmounts';
10
+ export * from './useSupplyLiquidity';
11
+ export * from './useDecreaseLiquidity';
12
+ export * from './useCreateDepositParams';
13
+ export * from './useCreateSupplyLiquidityParams';
14
+ export * from './useCreateDecreaseLiquidityParams';
15
+ export * from './useCreateWithdrawParams';
16
+ export * from './useClaimRewards';
@@ -0,0 +1,68 @@
1
+ import type {
2
+ ConcentratedLiquidityClaimRewardsParams,
3
+ ConcentratedLiquidityError,
4
+ ConcentratedLiquidityErrorCode,
5
+ SpokeProvider,
6
+ SpokeTxHash,
7
+ HubTxHash,
8
+ } from '@sodax/sdk';
9
+ import { useSodaxContext } from '../shared/useSodaxContext';
10
+ import { useMutation, type UseMutationResult, useQueryClient } from '@tanstack/react-query';
11
+
12
+ export type UseClaimRewardsParams = {
13
+ params: ConcentratedLiquidityClaimRewardsParams;
14
+ spokeProvider: SpokeProvider;
15
+ };
16
+
17
+ /**
18
+ * React hook for creating a mutation to claim DEX rewards for a concentrated liquidity position.
19
+ *
20
+ * @returns {UseMutationResult<[SpokeTxHash, HubTxHash], ConcentratedLiquidityError<ConcentratedLiquidityErrorCode>, UseClaimRewardsParams>}
21
+ * Returns a react-query mutation result object:
22
+ * - On success: resolves to a tuple `[SpokeTxHash, HubTxHash]`.
23
+ * - On error: the error is of type `ConcentratedLiquidityError<ConcentratedLiquidityErrorCode>`.
24
+ * - The mutation function expects an argument of type {@link UseClaimRewardsParams}
25
+ * containing `params` (the claim parameters) and `spokeProvider` (the target provider).
26
+ * - On mutation success, invalidates the queries `'dex/poolBalances'` and `'dex/positionInfo'`.
27
+ *
28
+ * @example
29
+ * const claimRewardsMutation = useClaimRewards();
30
+ * claimRewardsMutation.mutateAsync({
31
+ * params: { poolKey, tokenId, tickLower, tickUpper },
32
+ * spokeProvider,
33
+ * });
34
+ */
35
+ export function useClaimRewards(): UseMutationResult<
36
+ [SpokeTxHash, HubTxHash],
37
+ ConcentratedLiquidityError<ConcentratedLiquidityErrorCode>,
38
+ UseClaimRewardsParams
39
+ > {
40
+ const { sodax } = useSodaxContext();
41
+ const queryClient = useQueryClient();
42
+
43
+ return useMutation({
44
+ mutationFn: async ({ params, spokeProvider }: UseClaimRewardsParams) => {
45
+ if (!spokeProvider) {
46
+ throw new Error('Spoke provider is required');
47
+ }
48
+ const result = await sodax.dex.clService.claimRewards({
49
+ params,
50
+ spokeProvider,
51
+ });
52
+
53
+ if (!result.ok) {
54
+ throw new Error(`Claim rewards failed: ${result.error?.code || 'Unknown error'}`);
55
+ }
56
+
57
+ return result.value;
58
+ },
59
+ onSuccess: (_, { params, spokeProvider }) => {
60
+ // Invalidate relevant queries
61
+ queryClient.invalidateQueries({
62
+ queryKey: ['dex', 'poolBalances', params.poolKey, spokeProvider.chainConfig.chain.id],
63
+ });
64
+ queryClient.invalidateQueries({ queryKey: ['dex', 'positionInfo', params.tokenId, params.poolKey] });
65
+ queryClient.invalidateQueries({ queryKey: ['dex', 'poolData', params.poolKey] });
66
+ },
67
+ });
68
+ }
@@ -0,0 +1,41 @@
1
+ import { createDecreaseLiquidityParamsProps } from '@/utils/dex-utils';
2
+ import type { ClPositionInfo, ConcentratedLiquidityDecreaseLiquidityParams, PoolKey } from '@sodax/sdk';
3
+ import { useMemo } from 'react';
4
+
5
+ export type UseCreateDecreaseLiquidityParamsProps = {
6
+ poolKey: PoolKey;
7
+ tokenId: string | bigint;
8
+ percentage: string | number;
9
+ positionInfo: ClPositionInfo;
10
+ slippageTolerance: string | number;
11
+ };
12
+
13
+
14
+ /**
15
+ * React hook to create the decrease liquidity parameters for a given pool and position.
16
+ *
17
+ * Purpose:
18
+ * - Provides a hook which memoizes the decrease liquidity parameters for a given pool and position.
19
+ *
20
+ * Usage:
21
+ * - Call the function with the pool key, token ID, percentage, position info, and slippage tolerance to create the decrease liquidity parameters.
22
+ *
23
+ * Params:
24
+ * @param poolKey - The pool key of the pool to decrease the liquidity from.
25
+ * @param tokenId - The token ID of the position to decrease the liquidity from.
26
+ * @param percentage - The percentage of liquidity to decrease.
27
+ * @param positionInfo - The position info of the position to decrease the liquidity from.
28
+ * @param slippageTolerance - The slippage tolerance to use for the decrease.
29
+ * @returns The decrease liquidity parameters.
30
+ */
31
+ export function useCreateDecreaseLiquidityParams({
32
+ poolKey,
33
+ tokenId,
34
+ percentage,
35
+ positionInfo,
36
+ slippageTolerance,
37
+ }: UseCreateDecreaseLiquidityParamsProps): ConcentratedLiquidityDecreaseLiquidityParams {
38
+ return useMemo<ConcentratedLiquidityDecreaseLiquidityParams>(() => {
39
+ return createDecreaseLiquidityParamsProps({ poolKey, tokenId, percentage, positionInfo, slippageTolerance });
40
+ }, [poolKey, tokenId, percentage, positionInfo, slippageTolerance]);
41
+ }
@@ -0,0 +1,43 @@
1
+ import { useMemo } from 'react';
2
+ import type { CreateAssetDepositParams, PoolData, PoolSpokeAssets } from '@sodax/sdk';
3
+ import { createDepositParamsProps } from '@/utils/dex-utils';
4
+
5
+ export type UseCreateDepositParamsProps = {
6
+ tokenIndex: 0 | 1;
7
+ amount: string | number;
8
+ poolData: PoolData;
9
+ poolSpokeAssets: PoolSpokeAssets;
10
+ };
11
+
12
+
13
+ /**
14
+ * React hook to create the deposit parameters for a given pool and token.
15
+ *
16
+ * Purpose:
17
+ * - Provides a hook which memoizes the deposit parameters for a given pool and token.
18
+ *
19
+ * Usage:
20
+ * - Call the function with the token index, amount, pool data, pool key, and spoke provider to create the deposit parameters.
21
+ *
22
+ * Params:
23
+ * @param tokenIndex - The index of the token to deposit.
24
+ * @param amount - The amount of the token to deposit.
25
+ * @param poolData - The pool data of the pool to deposit to.
26
+ * @param poolKey - The pool key of the pool to deposit to.
27
+ * @param spokeProvider - The spoke provider to use for the deposit.
28
+ * @returns The deposit parameters or undefined if the pool key, spoke provider, or amount is not set.
29
+ */
30
+ export function useCreateDepositParams({
31
+ tokenIndex,
32
+ amount,
33
+ poolData,
34
+ poolSpokeAssets,
35
+ }: UseCreateDepositParamsProps): CreateAssetDepositParams | undefined {
36
+ return useMemo<CreateAssetDepositParams | undefined>(() => {
37
+ if (!amount || Number.parseFloat(String(amount)) <= 0) {
38
+ return undefined;
39
+ }
40
+
41
+ return createDepositParamsProps({ tokenIndex, amount, poolData, poolSpokeAssets });
42
+ }, [tokenIndex, amount, poolData, poolSpokeAssets]);
43
+ }
@@ -0,0 +1,84 @@
1
+ import { createSupplyLiquidityParamsProps } from '@/utils/dex-utils';
2
+ import type {
3
+ ConcentratedLiquiditySupplyParams,
4
+ ConcentratedLiquidityIncreaseLiquidityParams,
5
+ PoolData,
6
+ PoolKey,
7
+ } from '@sodax/sdk';
8
+ import { useMemo } from 'react';
9
+
10
+ export type UseCreateSupplyLiquidityParamsProps = {
11
+ poolData: PoolData;
12
+ poolKey: PoolKey;
13
+ minPrice: string;
14
+ maxPrice: string;
15
+ liquidityToken0Amount: string;
16
+ liquidityToken1Amount: string;
17
+ slippageTolerance: string | number;
18
+ positionId?: string | null;
19
+ isValidPosition?: boolean;
20
+ };
21
+
22
+ export type UseCreateSupplyLiquidityParamsResult = ConcentratedLiquiditySupplyParams &
23
+ Omit<ConcentratedLiquidityIncreaseLiquidityParams, 'tokenId'> & {
24
+ tokenId?: string | bigint;
25
+ positionId?: string | null;
26
+ isValidPosition?: boolean;
27
+ };
28
+
29
+ /**
30
+ * React hook to create the supply liquidity parameters for a given pool.
31
+ *
32
+ * Purpose:
33
+ * - Provides a hook which memoizes the supply liquidity parameters for a given pool.
34
+ *
35
+ * Usage:
36
+ * - Call the function with the pool data, pool key, minimum price, maximum price, liquidity token0 amount, liquidity token1 amount, slippage tolerance, position id, and validity of the position to create the supply liquidity parameters.
37
+ *
38
+ * Params:
39
+ * @param poolData - The pool data of the pool to supply liquidity to.
40
+ * @param poolKey - The pool key of the pool to supply liquidity to.
41
+ * @param minPrice - The minimum price of the liquidity to supply.
42
+ * @param maxPrice - The maximum price of the liquidity to supply.
43
+ * @param liquidityToken0Amount - The amount of the token0 to supply.
44
+ * @param liquidityToken1Amount - The amount of the token1 to supply.
45
+ * @param slippageTolerance - The slippage tolerance to use for the supply.
46
+ * @param positionId - The position id of the position to supply liquidity to.
47
+ * @param isValidPosition - Whether the position is valid.
48
+ * @returns The supply liquidity parameters.
49
+ */
50
+ export function useCreateSupplyLiquidityParams({
51
+ poolData,
52
+ poolKey,
53
+ minPrice,
54
+ maxPrice,
55
+ liquidityToken0Amount,
56
+ liquidityToken1Amount,
57
+ slippageTolerance,
58
+ positionId,
59
+ isValidPosition,
60
+ }: UseCreateSupplyLiquidityParamsProps): UseCreateSupplyLiquidityParamsResult {
61
+ return useMemo<UseCreateSupplyLiquidityParamsResult>(() => {
62
+ return createSupplyLiquidityParamsProps({
63
+ poolData,
64
+ poolKey,
65
+ minPrice,
66
+ maxPrice,
67
+ liquidityToken0Amount,
68
+ liquidityToken1Amount,
69
+ slippageTolerance,
70
+ positionId,
71
+ isValidPosition,
72
+ });
73
+ }, [
74
+ minPrice,
75
+ maxPrice,
76
+ liquidityToken0Amount,
77
+ liquidityToken1Amount,
78
+ slippageTolerance,
79
+ poolData,
80
+ poolKey,
81
+ positionId,
82
+ isValidPosition,
83
+ ]);
84
+ }
@@ -0,0 +1,44 @@
1
+ import type { CreateAssetWithdrawParams, DestinationParamsType, PoolData, PoolSpokeAssets } from '@sodax/sdk';
2
+ import { useMemo } from 'react';
3
+ import { createWithdrawParamsProps } from '@/utils/dex-utils';
4
+
5
+ export type UseCreateWithdrawParamsProps = {
6
+ tokenIndex: 0 | 1;
7
+ amount: string | number;
8
+ poolData: PoolData;
9
+ poolSpokeAssets: PoolSpokeAssets;
10
+ dst?: DestinationParamsType;
11
+ };
12
+
13
+ /**
14
+ * React hook to create the withdrawal parameters for a given pool and token.
15
+ *
16
+ * Purpose:
17
+ * - Provides a hook which memoizes the withdrawal parameters for a given pool and token.
18
+ *
19
+ * Usage:
20
+ * - Call the function with the token index, amount, pool data, pool spoke assets, and destination parameters to create the withdrawal parameters.
21
+ *
22
+ * Params:
23
+ * @param tokenIndex - The index of the token to withdraw.
24
+ * @param amount - The amount of the token to withdraw.
25
+ * @param poolData - The pool data of the pool to withdraw from.
26
+ * @param poolSpokeAssets - The pool spoke assets of the pool to withdraw from.
27
+ * @param dst - The destination parameters for the withdrawal.
28
+ * @returns The withdrawal parameters or undefined if the amount is not set.
29
+ */
30
+ export function useCreateWithdrawParams({
31
+ tokenIndex,
32
+ amount,
33
+ poolData,
34
+ poolSpokeAssets,
35
+ dst,
36
+ }: UseCreateWithdrawParamsProps): CreateAssetWithdrawParams | undefined {
37
+ return useMemo<CreateAssetWithdrawParams | undefined>(() => {
38
+ if (!amount || Number.parseFloat(String(amount)) <= 0) {
39
+ return undefined;
40
+ }
41
+
42
+ return createWithdrawParamsProps({ tokenIndex, amount, poolData, poolSpokeAssets, dst });
43
+ }, [tokenIndex, amount, poolData, poolSpokeAssets, dst]);
44
+ }