@sodax/dapp-kit 0.0.1-rc.3 → 0.0.1-rc.31
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/LICENSE +21 -0
- package/README.md +152 -53
- package/dist/index.d.mts +1514 -0
- package/dist/index.d.ts +1514 -4
- package/dist/index.js +1141 -189
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1096 -187
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -8
- package/src/contexts/index.ts +2 -0
- package/src/core/index.ts +5 -33
- package/src/hooks/backend/README.md +135 -0
- package/src/hooks/backend/index.ts +23 -0
- package/src/hooks/backend/useBackendAllMoneyMarketAssets.ts +49 -0
- package/src/hooks/backend/useBackendAllMoneyMarketBorrowers.ts +61 -0
- package/src/hooks/backend/useBackendIntentByHash.ts +53 -0
- package/src/hooks/backend/useBackendIntentByTxHash.ts +52 -0
- package/src/hooks/backend/useBackendMoneyMarketAsset.ts +57 -0
- package/src/hooks/backend/useBackendMoneyMarketAssetBorrowers.ts +67 -0
- package/src/hooks/backend/useBackendMoneyMarketAssetSuppliers.ts +67 -0
- package/src/hooks/backend/useBackendMoneyMarketPosition.ts +56 -0
- package/src/hooks/backend/useBackendOrderbook.ts +63 -0
- package/src/hooks/bridge/index.ts +5 -0
- package/src/hooks/bridge/useBridge.ts +57 -0
- package/src/hooks/bridge/useBridgeAllowance.ts +49 -0
- package/src/hooks/bridge/useBridgeApprove.ts +68 -0
- package/src/hooks/bridge/useGetBridgeableAmount.ts +50 -0
- package/src/hooks/bridge/useGetBridgeableTokens.ts +62 -0
- package/src/hooks/index.ts +4 -0
- package/src/hooks/migrate/index.ts +4 -0
- package/src/hooks/migrate/types.ts +15 -0
- package/src/hooks/migrate/useMigrate.tsx +110 -0
- package/src/hooks/migrate/useMigrationAllowance.tsx +79 -0
- package/src/hooks/migrate/useMigrationApprove.tsx +129 -0
- package/src/hooks/mm/index.ts +3 -1
- package/src/hooks/mm/useBorrow.ts +20 -10
- package/src/hooks/mm/useMMAllowance.ts +56 -0
- package/src/hooks/mm/useMMApprove.ts +68 -0
- package/src/hooks/mm/useRepay.ts +20 -10
- package/src/hooks/mm/useReservesData.ts +30 -0
- package/src/hooks/mm/useReservesHumanized.ts +30 -0
- package/src/hooks/mm/useReservesList.ts +29 -0
- package/src/hooks/mm/useReservesUsdFormat.ts +38 -0
- package/src/hooks/mm/useSupply.ts +9 -6
- package/src/hooks/mm/useUserFormattedSummary.ts +54 -0
- package/src/hooks/mm/useUserReservesData.ts +30 -48
- package/src/hooks/mm/useWithdraw.ts +17 -11
- package/src/hooks/provider/useHubProvider.ts +3 -21
- package/src/hooks/provider/useSpokeProvider.ts +97 -6
- package/src/hooks/shared/index.ts +4 -2
- package/src/hooks/shared/useDeriveUserWalletAddress.ts +44 -0
- package/src/hooks/shared/useEstimateGas.ts +18 -0
- package/src/hooks/shared/useRequestTrustline.ts +103 -0
- package/src/hooks/shared/useStellarTrustlineCheck.ts +71 -0
- package/src/hooks/staking/index.ts +19 -0
- package/src/hooks/staking/useCancelUnstake.ts +52 -0
- package/src/hooks/staking/useClaim.ts +46 -0
- package/src/hooks/staking/useConvertedAssets.ts +47 -0
- package/src/hooks/staking/useInstantUnstake.ts +50 -0
- package/src/hooks/staking/useInstantUnstakeAllowance.ts +59 -0
- package/src/hooks/staking/useInstantUnstakeApprove.ts +52 -0
- package/src/hooks/staking/useInstantUnstakeRatio.ts +54 -0
- package/src/hooks/staking/useStake.ts +47 -0
- package/src/hooks/staking/useStakeAllowance.ts +57 -0
- package/src/hooks/staking/useStakeApprove.ts +50 -0
- package/src/hooks/staking/useStakeRatio.ts +53 -0
- package/src/hooks/staking/useStakingConfig.ts +40 -0
- package/src/hooks/staking/useStakingInfo.ts +50 -0
- package/src/hooks/staking/useUnstake.ts +54 -0
- package/src/hooks/staking/useUnstakeAllowance.ts +58 -0
- package/src/hooks/staking/useUnstakeApprove.ts +52 -0
- package/src/hooks/staking/useUnstakingInfo.ts +53 -0
- package/src/hooks/staking/useUnstakingInfoWithPenalty.ts +59 -0
- package/src/hooks/swap/index.ts +4 -1
- package/src/hooks/swap/useCancelSwap.ts +44 -0
- package/src/hooks/swap/useQuote.ts +20 -6
- package/src/hooks/swap/useStatus.ts +3 -3
- package/src/hooks/swap/{useCreateIntentOrder.ts → useSwap.ts} +22 -19
- package/src/hooks/swap/useSwapAllowance.ts +48 -0
- package/src/hooks/swap/useSwapApprove.ts +68 -0
- package/src/providers/SodaxProvider.tsx +7 -4
- package/dist/contexts/index.d.ts +0 -7
- package/dist/contexts/index.d.ts.map +0 -1
- package/dist/core/index.d.ts +0 -4
- package/dist/core/index.d.ts.map +0 -1
- package/dist/hooks/index.d.ts +0 -5
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/mm/index.d.ts +0 -7
- package/dist/hooks/mm/index.d.ts.map +0 -1
- package/dist/hooks/mm/useBorrow.d.ts +0 -26
- package/dist/hooks/mm/useBorrow.d.ts.map +0 -1
- package/dist/hooks/mm/useHubWalletAddress.d.ts +0 -24
- package/dist/hooks/mm/useHubWalletAddress.d.ts.map +0 -1
- package/dist/hooks/mm/useRepay.d.ts +0 -26
- package/dist/hooks/mm/useRepay.d.ts.map +0 -1
- package/dist/hooks/mm/useSupply.d.ts +0 -32
- package/dist/hooks/mm/useSupply.d.ts.map +0 -1
- package/dist/hooks/mm/useUserReservesData.d.ts +0 -9
- package/dist/hooks/mm/useUserReservesData.d.ts.map +0 -1
- package/dist/hooks/mm/useWithdraw.d.ts +0 -26
- package/dist/hooks/mm/useWithdraw.d.ts.map +0 -1
- package/dist/hooks/provider/index.d.ts +0 -3
- package/dist/hooks/provider/index.d.ts.map +0 -1
- package/dist/hooks/provider/useHubProvider.d.ts +0 -3
- package/dist/hooks/provider/useHubProvider.d.ts.map +0 -1
- package/dist/hooks/provider/useSpokeProvider.d.ts +0 -4
- package/dist/hooks/provider/useSpokeProvider.d.ts.map +0 -1
- package/dist/hooks/shared/index.d.ts +0 -4
- package/dist/hooks/shared/index.d.ts.map +0 -1
- package/dist/hooks/shared/useAllowance.d.ts +0 -3
- package/dist/hooks/shared/useAllowance.d.ts.map +0 -1
- package/dist/hooks/shared/useApprove.d.ts +0 -10
- package/dist/hooks/shared/useApprove.d.ts.map +0 -1
- package/dist/hooks/shared/useSodaxContext.d.ts +0 -8
- package/dist/hooks/shared/useSodaxContext.d.ts.map +0 -1
- package/dist/hooks/swap/index.d.ts +0 -4
- package/dist/hooks/swap/index.d.ts.map +0 -1
- package/dist/hooks/swap/useCreateIntentOrder.d.ts +0 -33
- package/dist/hooks/swap/useCreateIntentOrder.d.ts.map +0 -1
- package/dist/hooks/swap/useQuote.d.ts +0 -39
- package/dist/hooks/swap/useQuote.d.ts.map +0 -1
- package/dist/hooks/swap/useStatus.d.ts +0 -31
- package/dist/hooks/swap/useStatus.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/providers/SodaxProvider.d.ts +0 -10
- package/dist/providers/SodaxProvider.d.ts.map +0 -1
- package/dist/providers/index.d.ts +0 -2
- package/dist/providers/index.d.ts.map +0 -1
- package/src/hooks/mm/useHubWalletAddress.ts +0 -49
- package/src/hooks/shared/useAllowance.ts +0 -31
- package/src/hooks/shared/useApprove.ts +0 -53
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { parseUnits } from 'viem';
|
|
2
|
+
import { useCallback, useState, useRef, useEffect } from 'react';
|
|
3
|
+
import type {
|
|
4
|
+
IcxCreateRevertMigrationParams,
|
|
5
|
+
UnifiedBnUSDMigrateParams,
|
|
6
|
+
SpokeProvider,
|
|
7
|
+
Result,
|
|
8
|
+
ChainId,
|
|
9
|
+
} from '@sodax/sdk';
|
|
10
|
+
import { useSodaxContext } from '../shared/useSodaxContext';
|
|
11
|
+
import { MIGRATION_MODE_BNUSD, MIGRATION_MODE_ICX_SODA, type MigrationIntentParams } from './types';
|
|
12
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
13
|
+
|
|
14
|
+
interface UseApproveReturn {
|
|
15
|
+
approve: ({ params }: { params: MigrationIntentParams }) => Promise<boolean>;
|
|
16
|
+
isLoading: boolean;
|
|
17
|
+
error: Error | null;
|
|
18
|
+
resetError: () => void;
|
|
19
|
+
isApproved: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Hook for approving token spending for migration actions
|
|
24
|
+
* @param params The parameters for the migration approval
|
|
25
|
+
* @param spokeProvider The spoke provider instance for the chain
|
|
26
|
+
* @returns Object containing approve function, loading state, error state and reset function
|
|
27
|
+
* @example
|
|
28
|
+
* ```tsx
|
|
29
|
+
* const { approve, isLoading, error } = useMigrationApprove(params, spokeProvider);
|
|
30
|
+
*
|
|
31
|
+
* // Approve tokens for migration
|
|
32
|
+
* await approve({ params });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
export function useMigrationApprove(
|
|
37
|
+
params: MigrationIntentParams | undefined,
|
|
38
|
+
spokeProvider: SpokeProvider | undefined,
|
|
39
|
+
): UseApproveReturn {
|
|
40
|
+
const { sodax } = useSodaxContext();
|
|
41
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
42
|
+
const [error, setError] = useState<Error | null>(null);
|
|
43
|
+
const [isApproved, setIsApproved] = useState(false);
|
|
44
|
+
const queryClient = useQueryClient();
|
|
45
|
+
|
|
46
|
+
// Track previous values to reset approval state when needed
|
|
47
|
+
const prevTokenAddress = useRef<string | undefined>(undefined);
|
|
48
|
+
const prevAmount = useRef<string | undefined>(undefined);
|
|
49
|
+
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (prevTokenAddress.current !== params?.token?.address || prevAmount.current !== params?.amount) {
|
|
52
|
+
setIsApproved(false);
|
|
53
|
+
prevTokenAddress.current = params?.token?.address;
|
|
54
|
+
prevAmount.current = params?.amount;
|
|
55
|
+
}
|
|
56
|
+
}, [params?.token?.address, params?.amount]);
|
|
57
|
+
|
|
58
|
+
const approve = useCallback(
|
|
59
|
+
async ({ params: approveParams }: { params: MigrationIntentParams }) => {
|
|
60
|
+
try {
|
|
61
|
+
setIsLoading(true);
|
|
62
|
+
setError(null);
|
|
63
|
+
|
|
64
|
+
if (!spokeProvider) {
|
|
65
|
+
throw new Error('Spoke provider not found');
|
|
66
|
+
}
|
|
67
|
+
if (!approveParams) {
|
|
68
|
+
throw new Error('Migration intent not found');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const { token, amount, migrationMode = MIGRATION_MODE_ICX_SODA, toToken, destinationAddress } = approveParams;
|
|
72
|
+
const amountToMigrate = parseUnits(amount ?? '0', token?.decimals ?? 0);
|
|
73
|
+
|
|
74
|
+
let result: Result<string, unknown>;
|
|
75
|
+
if (migrationMode === MIGRATION_MODE_ICX_SODA) {
|
|
76
|
+
// ICX/SODA migration approval
|
|
77
|
+
const revertParams = {
|
|
78
|
+
amount: amountToMigrate,
|
|
79
|
+
to: destinationAddress as `hx${string}`,
|
|
80
|
+
} satisfies IcxCreateRevertMigrationParams;
|
|
81
|
+
|
|
82
|
+
result = await sodax.migration.approve(revertParams, 'revert', spokeProvider, false);
|
|
83
|
+
} else if (migrationMode === MIGRATION_MODE_BNUSD) {
|
|
84
|
+
// bnUSD migration approval
|
|
85
|
+
if (!toToken) throw new Error('Destination token is required for bnUSD migration');
|
|
86
|
+
|
|
87
|
+
const migrationParams = {
|
|
88
|
+
srcChainId: token?.xChainId as ChainId,
|
|
89
|
+
dstChainId: toToken?.xChainId as ChainId,
|
|
90
|
+
srcbnUSD: token?.address as string,
|
|
91
|
+
dstbnUSD: toToken?.address as string,
|
|
92
|
+
amount: amountToMigrate,
|
|
93
|
+
to: destinationAddress as `hx${string}` | `0x${string}`,
|
|
94
|
+
} satisfies UnifiedBnUSDMigrateParams;
|
|
95
|
+
|
|
96
|
+
result = await sodax.migration.approve(migrationParams, 'revert', spokeProvider, false);
|
|
97
|
+
} else {
|
|
98
|
+
throw new Error('Invalid migration mode');
|
|
99
|
+
}
|
|
100
|
+
if (!result.ok) {
|
|
101
|
+
throw new Error('Failed to approve tokens');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
setIsApproved(true);
|
|
105
|
+
queryClient.invalidateQueries({ queryKey: ['migration-allowance', params] });
|
|
106
|
+
return result.ok;
|
|
107
|
+
} catch (err) {
|
|
108
|
+
const error = err instanceof Error ? err : new Error('An unknown error occurred');
|
|
109
|
+
setError(error);
|
|
110
|
+
throw error;
|
|
111
|
+
} finally {
|
|
112
|
+
setIsLoading(false);
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
[spokeProvider, sodax, queryClient, params],
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
const resetError = useCallback(() => {
|
|
119
|
+
setError(null);
|
|
120
|
+
}, []);
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
approve,
|
|
124
|
+
isLoading,
|
|
125
|
+
error,
|
|
126
|
+
resetError,
|
|
127
|
+
isApproved,
|
|
128
|
+
};
|
|
129
|
+
}
|
package/src/hooks/mm/index.ts
CHANGED
|
@@ -3,4 +3,6 @@ export * from './useRepay';
|
|
|
3
3
|
export * from './useSupply';
|
|
4
4
|
export * from './useWithdraw';
|
|
5
5
|
export * from './useUserReservesData';
|
|
6
|
-
export * from './
|
|
6
|
+
export * from './useReservesData';
|
|
7
|
+
export * from './useMMAllowance';
|
|
8
|
+
export * from './useMMApprove';
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { XToken } from '@sodax/types';
|
|
2
2
|
import { useMutation, type UseMutationResult } from '@tanstack/react-query';
|
|
3
3
|
import { parseUnits } from 'viem';
|
|
4
|
-
import { useSpokeProvider } from '../provider/useSpokeProvider';
|
|
5
4
|
import { useSodaxContext } from '../shared/useSodaxContext';
|
|
6
|
-
import type {
|
|
5
|
+
import type { SpokeProvider } from '@sodax/sdk';
|
|
7
6
|
interface BorrowResponse {
|
|
8
7
|
ok: true;
|
|
9
|
-
value: [
|
|
8
|
+
value: [string, string];
|
|
10
9
|
}
|
|
11
10
|
|
|
12
11
|
/**
|
|
@@ -16,9 +15,17 @@ interface BorrowResponse {
|
|
|
16
15
|
* handling the entire borrow process including transaction creation, submission,
|
|
17
16
|
* and cross-chain communication.
|
|
18
17
|
*
|
|
18
|
+
* @param {XToken} spokeToken - The token to borrow from the spoke chain. Must be an XToken with valid address and chain information.
|
|
19
|
+
* @param {SpokeProvider} spokeProvider - The spoke provider to use for the borrow transaction. Must be a valid SpokeProvider instance.
|
|
20
|
+
*
|
|
21
|
+
* @returns {UseMutationResult<BorrowResponse, Error, string>} A mutation result object with the following properties:
|
|
22
|
+
* - mutateAsync: Function to execute the borrow transaction
|
|
23
|
+
* - isPending: Boolean indicating if a transaction is in progress
|
|
24
|
+
* - error: Error object if the last transaction failed, null otherwise
|
|
25
|
+
*
|
|
19
26
|
* @example
|
|
20
27
|
* ```typescript
|
|
21
|
-
* const { mutateAsync: borrow, isPending, error } = useBorrow(
|
|
28
|
+
* const { mutateAsync: borrow, isPending, error } = useBorrow(spokeToken);
|
|
22
29
|
* await borrow('100');
|
|
23
30
|
* ```
|
|
24
31
|
*
|
|
@@ -26,9 +33,11 @@ interface BorrowResponse {
|
|
|
26
33
|
* - spokeProvider is not available
|
|
27
34
|
* - Transaction execution fails
|
|
28
35
|
*/
|
|
29
|
-
export function useBorrow(
|
|
36
|
+
export function useBorrow(
|
|
37
|
+
spokeToken: XToken,
|
|
38
|
+
spokeProvider: SpokeProvider | undefined,
|
|
39
|
+
): UseMutationResult<BorrowResponse, Error, string> {
|
|
30
40
|
const { sodax } = useSodaxContext();
|
|
31
|
-
const spokeProvider = useSpokeProvider(spokeChainId as SpokeChainId);
|
|
32
41
|
|
|
33
42
|
return useMutation<BorrowResponse, Error, string>({
|
|
34
43
|
mutationFn: async (amount: string) => {
|
|
@@ -36,10 +45,11 @@ export function useBorrow(hubToken: XToken, spokeChainId: ChainId): UseMutationR
|
|
|
36
45
|
throw new Error('spokeProvider is not found');
|
|
37
46
|
}
|
|
38
47
|
|
|
39
|
-
const response = await sodax.moneyMarket.
|
|
48
|
+
const response = await sodax.moneyMarket.borrow(
|
|
40
49
|
{
|
|
41
|
-
token:
|
|
42
|
-
amount: parseUnits(amount,
|
|
50
|
+
token: spokeToken.address,
|
|
51
|
+
amount: parseUnits(amount, 18),
|
|
52
|
+
action: 'borrow',
|
|
43
53
|
},
|
|
44
54
|
spokeProvider,
|
|
45
55
|
);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { XToken } from '@sodax/types';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext';
|
|
4
|
+
import { parseUnits } from 'viem';
|
|
5
|
+
import type { MoneyMarketAction, SpokeProvider } from '@sodax/sdk';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Hook for checking token allowance for money market operations.
|
|
9
|
+
*
|
|
10
|
+
* This hook verifies if the user has approved enough tokens for a specific money market action
|
|
11
|
+
* (borrow/repay). It automatically queries and tracks the allowance status.
|
|
12
|
+
*
|
|
13
|
+
* @param {XToken} token - The token to check allowance for. Must be an XToken with valid address and chain information.
|
|
14
|
+
* @param {string} amount - The amount to check allowance for, as a decimal string
|
|
15
|
+
* @param {MoneyMarketAction} action - The money market action to check allowance for ('borrow' or 'repay')
|
|
16
|
+
* @param {SpokeProvider} spokeProvider - The spoke provider to use for allowance checks
|
|
17
|
+
*
|
|
18
|
+
* @returns {UseQueryResult<boolean, Error>} A React Query result containing:
|
|
19
|
+
* - data: Boolean indicating if allowance is sufficient
|
|
20
|
+
* - isLoading: Loading state indicator
|
|
21
|
+
* - error: Any error that occurred during the check
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const { data: hasAllowed, isLoading } = useMMAllowance(token, "100", "repay", provider);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export function useMMAllowance(
|
|
29
|
+
token: XToken,
|
|
30
|
+
amount: string,
|
|
31
|
+
action: MoneyMarketAction,
|
|
32
|
+
spokeProvider: SpokeProvider | undefined,
|
|
33
|
+
): UseQueryResult<boolean, Error> {
|
|
34
|
+
const { sodax } = useSodaxContext();
|
|
35
|
+
|
|
36
|
+
return useQuery({
|
|
37
|
+
queryKey: ['allowance', token.address, amount, action],
|
|
38
|
+
queryFn: async () => {
|
|
39
|
+
if (!spokeProvider) throw new Error('Spoke provider is required');
|
|
40
|
+
const actionBasedDecimals = action === 'withdraw' || action === 'borrow' ? 18 : token.decimals; // withdraw and borrow actions are in aToken decimals
|
|
41
|
+
const allowance = await sodax.moneyMarket.isAllowanceValid(
|
|
42
|
+
{
|
|
43
|
+
token: token.address,
|
|
44
|
+
amount: parseUnits(amount, actionBasedDecimals),
|
|
45
|
+
action,
|
|
46
|
+
},
|
|
47
|
+
spokeProvider,
|
|
48
|
+
);
|
|
49
|
+
if (allowance.ok) {
|
|
50
|
+
return allowance.value;
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
},
|
|
54
|
+
enabled: !!spokeProvider,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { useSodaxContext } from '../shared/useSodaxContext';
|
|
2
|
+
import type { XToken } from '@sodax/types';
|
|
3
|
+
import { parseUnits } from 'viem';
|
|
4
|
+
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
5
|
+
import type { MoneyMarketAction, SpokeProvider } from '@sodax/sdk';
|
|
6
|
+
|
|
7
|
+
interface UseApproveReturn {
|
|
8
|
+
approve: ({ amount, action }: { amount: string; action: MoneyMarketAction }) => Promise<boolean>;
|
|
9
|
+
isLoading: boolean;
|
|
10
|
+
error: Error | null;
|
|
11
|
+
resetError: () => void;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Hook for approving token spending for money market actions
|
|
16
|
+
* @param token The token to approve spending for
|
|
17
|
+
* @param spokeProvider The spoke provider instance for the chain
|
|
18
|
+
* @returns Object containing approve function, loading state, error state and reset function
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* const { approve, isLoading, error } = useMMApprove(token, spokeProvider);
|
|
22
|
+
*
|
|
23
|
+
* // Approve tokens for supply action
|
|
24
|
+
* await approve({ amount: "100", action: "supply" });
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
export function useMMApprove(token: XToken, spokeProvider: SpokeProvider | undefined): UseApproveReturn {
|
|
29
|
+
const { sodax } = useSodaxContext();
|
|
30
|
+
const queryClient = useQueryClient();
|
|
31
|
+
|
|
32
|
+
const {
|
|
33
|
+
mutateAsync: approve,
|
|
34
|
+
isPending,
|
|
35
|
+
error,
|
|
36
|
+
reset: resetError,
|
|
37
|
+
} = useMutation({
|
|
38
|
+
mutationFn: async ({ amount, action }: { amount: string; action: MoneyMarketAction }) => {
|
|
39
|
+
if (!spokeProvider) {
|
|
40
|
+
throw new Error('Spoke provider not found');
|
|
41
|
+
}
|
|
42
|
+
const actionBasedDecimals = action === 'withdraw' || action === 'borrow' ? 18 : token.decimals; // withdraw and borrow actions are in aToken decimals
|
|
43
|
+
const allowance = await sodax.moneyMarket.approve(
|
|
44
|
+
{
|
|
45
|
+
token: token.address,
|
|
46
|
+
amount: parseUnits(amount, actionBasedDecimals),
|
|
47
|
+
action,
|
|
48
|
+
},
|
|
49
|
+
spokeProvider,
|
|
50
|
+
);
|
|
51
|
+
if (!allowance.ok) {
|
|
52
|
+
throw new Error('Failed to approve tokens');
|
|
53
|
+
}
|
|
54
|
+
return allowance.ok;
|
|
55
|
+
},
|
|
56
|
+
onSuccess: () => {
|
|
57
|
+
// Invalidate allowance query to refetch the new allowance
|
|
58
|
+
queryClient.invalidateQueries({ queryKey: ['allowance', token.address] });
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
approve,
|
|
64
|
+
isLoading: isPending,
|
|
65
|
+
error: error,
|
|
66
|
+
resetError,
|
|
67
|
+
};
|
|
68
|
+
}
|
package/src/hooks/mm/useRepay.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { SpokeProvider } from '@sodax/sdk';
|
|
2
|
+
import type { XToken } from '@sodax/types';
|
|
3
3
|
import { useMutation, type UseMutationResult } from '@tanstack/react-query';
|
|
4
4
|
import { parseUnits } from 'viem';
|
|
5
|
-
import { useSpokeProvider } from '../provider/useSpokeProvider';
|
|
6
5
|
import { useSodaxContext } from '../shared/useSodaxContext';
|
|
7
6
|
|
|
8
7
|
interface RepayResponse {
|
|
9
8
|
ok: true;
|
|
10
|
-
value: [
|
|
9
|
+
value: [string, string];
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
/**
|
|
@@ -17,9 +16,17 @@ interface RepayResponse {
|
|
|
17
16
|
* handling the entire repayment process including transaction creation, submission,
|
|
18
17
|
* and cross-chain communication.
|
|
19
18
|
*
|
|
19
|
+
* @param {XToken} spokeToken - The token to repay on the spoke chain. Must be an XToken with valid address and chain information.
|
|
20
|
+
* @param {SpokeProvider} spokeProvider - The spoke provider to use for the repay transaction. Must be a valid SpokeProvider instance.
|
|
21
|
+
*
|
|
22
|
+
* @returns {UseMutationResult<RepayResponse, Error, string>} A mutation result object with the following properties:
|
|
23
|
+
* - mutateAsync: Function to execute the repay transaction
|
|
24
|
+
* - isPending: Boolean indicating if a transaction is in progress
|
|
25
|
+
* - error: Error object if the last transaction failed, null otherwise
|
|
26
|
+
*
|
|
20
27
|
* @example
|
|
21
28
|
* ```typescript
|
|
22
|
-
* const { mutateAsync: repay, isPending, error } = useRepay(
|
|
29
|
+
* const { mutateAsync: repay, isPending, error } = useRepay(spokeToken);
|
|
23
30
|
* await repay('100');
|
|
24
31
|
* ```
|
|
25
32
|
*
|
|
@@ -27,9 +34,11 @@ interface RepayResponse {
|
|
|
27
34
|
* - spokeProvider is not available
|
|
28
35
|
* - Transaction execution fails
|
|
29
36
|
*/
|
|
30
|
-
export function useRepay(
|
|
37
|
+
export function useRepay(
|
|
38
|
+
spokeToken: XToken,
|
|
39
|
+
spokeProvider: SpokeProvider | undefined,
|
|
40
|
+
): UseMutationResult<RepayResponse, Error, string> {
|
|
31
41
|
const { sodax } = useSodaxContext();
|
|
32
|
-
const spokeProvider = useSpokeProvider(spokeChainId as SpokeChainId);
|
|
33
42
|
|
|
34
43
|
return useMutation<RepayResponse, Error, string>({
|
|
35
44
|
mutationFn: async (amount: string) => {
|
|
@@ -37,10 +46,11 @@ export function useRepay(hubToken: XToken, spokeChainId: ChainId): UseMutationRe
|
|
|
37
46
|
throw new Error('spokeProvider is not found');
|
|
38
47
|
}
|
|
39
48
|
|
|
40
|
-
const response = await sodax.moneyMarket.
|
|
49
|
+
const response = await sodax.moneyMarket.repay(
|
|
41
50
|
{
|
|
42
|
-
token:
|
|
43
|
-
amount: parseUnits(amount,
|
|
51
|
+
token: spokeToken.address,
|
|
52
|
+
amount: parseUnits(amount, spokeToken.decimals),
|
|
53
|
+
action: 'repay',
|
|
44
54
|
},
|
|
45
55
|
spokeProvider,
|
|
46
56
|
);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { useQuery } from '@tanstack/react-query';
|
|
2
|
+
import { useSodaxContext } from '../shared/useSodaxContext';
|
|
3
|
+
/**
|
|
4
|
+
* Hook for fetching reserves data from the Sodax money market.
|
|
5
|
+
*
|
|
6
|
+
* This hook provides access to the current state of all reserves in the money market protocol,
|
|
7
|
+
* including liquidity, interest rates, and other key metrics. The data is automatically
|
|
8
|
+
* fetched and cached using React Query.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const { data: reservesData, isLoading, error } = useReservesData();
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* @returns A React Query result object containing:
|
|
16
|
+
* - data: The reserves data when available
|
|
17
|
+
* - isLoading: Loading state indicator
|
|
18
|
+
* - error: Any error that occurred during data fetching
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
export function useReservesData() {
|
|
22
|
+
const { sodax } = useSodaxContext();
|
|
23
|
+
|
|
24
|
+
return useQuery({
|
|
25
|
+
queryKey: ['reservesData'],
|
|
26
|
+
queryFn: async () => {
|
|
27
|
+
return await sodax.moneyMarket.data.getReservesData();
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ReservesDataHumanized } from '@sodax/sdk';
|
|
2
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext';
|
|
4
|
+
/**
|
|
5
|
+
* Hook for fetching humanized reserves data from the Sodax money market.
|
|
6
|
+
*
|
|
7
|
+
* This hook provides access to the current state of all reserves (humanized format) in the money market protocol,
|
|
8
|
+
* including liquidity, interest rates, and other key metrics. The data is automatically
|
|
9
|
+
* fetched and cached using React Query.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const { data: reservesHumanized, isLoading, error } = useReservesHumanized();
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @returns A React Query result object containing:
|
|
17
|
+
* - data: The reserves humanized data when available
|
|
18
|
+
* - isLoading: Loading state indicator
|
|
19
|
+
* - error: Any error that occurred during data fetching
|
|
20
|
+
*/
|
|
21
|
+
export function useReservesHumanized(): UseQueryResult<ReservesDataHumanized, Error> {
|
|
22
|
+
const { sodax } = useSodaxContext();
|
|
23
|
+
|
|
24
|
+
return useQuery({
|
|
25
|
+
queryKey: ['reservesHumanized'],
|
|
26
|
+
queryFn: async () => {
|
|
27
|
+
return await sodax.moneyMarket.data.getReservesHumanized();
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { useQuery } from '@tanstack/react-query';
|
|
2
|
+
import { useSodaxContext } from '../shared/useSodaxContext';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Hook for fetching list of reserves from the Sodax money market.
|
|
6
|
+
*
|
|
7
|
+
* This hook provides access to the list of addresses of all reserves in the money market protocol.
|
|
8
|
+
* The data is automatically fetched and cached using React Query.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const { data: reservesList, isLoading, error } = useReservesList();
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* @returns A React Query result object containing:
|
|
16
|
+
* - data: The reserves list when available
|
|
17
|
+
* - isLoading: Loading state indicator
|
|
18
|
+
* - error: Any error that occurred during data fetching
|
|
19
|
+
*/
|
|
20
|
+
export function useReservesList() {
|
|
21
|
+
const { sodax } = useSodaxContext();
|
|
22
|
+
|
|
23
|
+
return useQuery({
|
|
24
|
+
queryKey: ['reservesList'],
|
|
25
|
+
queryFn: async () => {
|
|
26
|
+
return await sodax.moneyMarket.data.getReservesList();
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { FormatReserveUSDResponse, ReserveData } from '@sodax/sdk';
|
|
2
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Hook for fetching formatted summary of Sodax user portfolio (holdings, total liquidity,
|
|
7
|
+
* collateral, borrows, liquidation threshold, health factor, available borrowing power, etc..).
|
|
8
|
+
*
|
|
9
|
+
* This hook provides access to the current state of user portfolio in the money market protocol.
|
|
10
|
+
* The data is automatically fetched and cached using React Query.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const { data: userFormattedSummary, isLoading, error } = useUserFormattedSummary();
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @returns A React Query result object containing:
|
|
18
|
+
* - data: The formatted summary of Sodax user portfolio when available
|
|
19
|
+
* - isLoading: Loading state indicator
|
|
20
|
+
* - error: Any error that occurred during data fetching
|
|
21
|
+
*/
|
|
22
|
+
export function useReservesUsdFormat(): UseQueryResult<
|
|
23
|
+
(ReserveData & { priceInMarketReferenceCurrency: string } & FormatReserveUSDResponse)[],
|
|
24
|
+
Error
|
|
25
|
+
> {
|
|
26
|
+
const { sodax } = useSodaxContext();
|
|
27
|
+
|
|
28
|
+
return useQuery({
|
|
29
|
+
queryKey: ['reservesUsdFormat'],
|
|
30
|
+
queryFn: async () => {
|
|
31
|
+
// fetch reserves and hub wallet address
|
|
32
|
+
const reserves = await sodax.moneyMarket.data.getReservesHumanized();
|
|
33
|
+
|
|
34
|
+
// format reserves
|
|
35
|
+
return sodax.moneyMarket.data.formatReservesUSD(sodax.moneyMarket.data.buildReserveDataWithPrice(reserves));
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SpokeProvider } from '@sodax/sdk';
|
|
2
2
|
import type { XToken } from '@sodax/types';
|
|
3
3
|
import { useMutation, type UseMutationResult } from '@tanstack/react-query';
|
|
4
4
|
import { parseUnits } from 'viem';
|
|
5
|
-
import { useSpokeProvider } from '../provider/useSpokeProvider';
|
|
6
5
|
import { useSodaxContext } from '../shared/useSodaxContext';
|
|
7
6
|
|
|
8
7
|
interface SupplyResponse {
|
|
9
8
|
ok: true;
|
|
10
|
-
value: [
|
|
9
|
+
value: [string, string];
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
/**
|
|
@@ -18,6 +17,7 @@ interface SupplyResponse {
|
|
|
18
17
|
* and cross-chain communication.
|
|
19
18
|
*
|
|
20
19
|
* @param {XToken} spokeToken - The token to supply on the spoke chain. Must be an XToken with valid address and chain information.
|
|
20
|
+
* @param {SpokeProvider} spokeProvider - The spoke provider to use for the supply transaction. Must be a valid SpokeProvider instance.
|
|
21
21
|
*
|
|
22
22
|
* @returns {UseMutationResult<SupplyResponse, Error, string>} A mutation result object with the following properties:
|
|
23
23
|
* - mutateAsync: Function to execute the supply transaction
|
|
@@ -33,9 +33,11 @@ interface SupplyResponse {
|
|
|
33
33
|
* @throws {Error} When:
|
|
34
34
|
* - spokeProvider is not available
|
|
35
35
|
*/
|
|
36
|
-
export function useSupply(
|
|
36
|
+
export function useSupply(
|
|
37
|
+
spokeToken: XToken,
|
|
38
|
+
spokeProvider: SpokeProvider | undefined,
|
|
39
|
+
): UseMutationResult<SupplyResponse, Error, string> {
|
|
37
40
|
const { sodax } = useSodaxContext();
|
|
38
|
-
const spokeProvider = useSpokeProvider(spokeToken.xChainId as SpokeChainId);
|
|
39
41
|
|
|
40
42
|
return useMutation<SupplyResponse, Error, string>({
|
|
41
43
|
mutationFn: async (amount: string) => {
|
|
@@ -43,10 +45,11 @@ export function useSupply(spokeToken: XToken): UseMutationResult<SupplyResponse,
|
|
|
43
45
|
throw new Error('spokeProvider is not found');
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
const response = await sodax.moneyMarket.
|
|
48
|
+
const response = await sodax.moneyMarket.supply(
|
|
47
49
|
{
|
|
48
50
|
token: spokeToken.address,
|
|
49
51
|
amount: parseUnits(amount, spokeToken.decimals),
|
|
52
|
+
action: 'supply',
|
|
50
53
|
},
|
|
51
54
|
spokeProvider,
|
|
52
55
|
);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { FormatUserSummaryResponse, FormatReserveUSDResponse, SpokeProvider } from '@sodax/sdk';
|
|
2
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Hook for fetching formatted summary of Sodax user portfolio (holdings, total liquidity,
|
|
7
|
+
* collateral, borrows, liquidation threshold, health factor, available borrowing power, etc..).
|
|
8
|
+
*
|
|
9
|
+
* This hook provides access to the current state of user portfolio in the money market protocol.
|
|
10
|
+
* The data is automatically fetched and cached using React Query.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const { data: userFormattedSummary, isLoading, error } = useUserFormattedSummary(spokeProvider, address);
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @returns A React Query result object containing:
|
|
18
|
+
* - data: The formatted summary of Sodax user portfolio when available
|
|
19
|
+
* - isLoading: Loading state indicator
|
|
20
|
+
* - error: Any error that occurred during data fetching
|
|
21
|
+
*/
|
|
22
|
+
export function useUserFormattedSummary(
|
|
23
|
+
spokeProvider: SpokeProvider | undefined,
|
|
24
|
+
address: string | undefined,
|
|
25
|
+
): UseQueryResult<FormatUserSummaryResponse<FormatReserveUSDResponse>, Error> {
|
|
26
|
+
const { sodax } = useSodaxContext();
|
|
27
|
+
|
|
28
|
+
return useQuery({
|
|
29
|
+
queryKey: ['userFormattedSummary', spokeProvider?.chainConfig.chain.id, address],
|
|
30
|
+
queryFn: async () => {
|
|
31
|
+
if (!spokeProvider || !address) {
|
|
32
|
+
throw new Error('Spoke provider or address is not defined');
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// fetch reserves and hub wallet address
|
|
36
|
+
const reserves = await sodax.moneyMarket.data.getReservesHumanized();
|
|
37
|
+
|
|
38
|
+
// format reserves
|
|
39
|
+
const formattedReserves = sodax.moneyMarket.data.formatReservesUSD(
|
|
40
|
+
sodax.moneyMarket.data.buildReserveDataWithPrice(reserves),
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// fetch user reserves
|
|
44
|
+
const userReserves = await sodax.moneyMarket.data.getUserReservesHumanized(spokeProvider);
|
|
45
|
+
|
|
46
|
+
// format user summary
|
|
47
|
+
return sodax.moneyMarket.data.formatUserSummary(
|
|
48
|
+
sodax.moneyMarket.data.buildUserSummaryRequest(reserves, formattedReserves, userReserves),
|
|
49
|
+
);
|
|
50
|
+
},
|
|
51
|
+
enabled: !!spokeProvider && !!address,
|
|
52
|
+
refetchInterval: 5000,
|
|
53
|
+
});
|
|
54
|
+
}
|