@sodax/dapp-kit 0.0.1-rc.8 → 1.0.0-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 (137) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +157 -60
  3. package/dist/index.d.mts +1558 -0
  4. package/dist/index.d.ts +1558 -4
  5. package/dist/index.js +1030 -135
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +988 -134
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +7 -8
  10. package/src/contexts/index.ts +3 -2
  11. package/src/hooks/backend/README.md +135 -0
  12. package/src/hooks/backend/index.ts +23 -0
  13. package/src/hooks/backend/useBackendAllMoneyMarketAssets.ts +49 -0
  14. package/src/hooks/backend/useBackendAllMoneyMarketBorrowers.ts +61 -0
  15. package/src/hooks/backend/useBackendIntentByHash.ts +53 -0
  16. package/src/hooks/backend/useBackendIntentByTxHash.ts +57 -0
  17. package/src/hooks/backend/useBackendMoneyMarketAsset.ts +57 -0
  18. package/src/hooks/backend/useBackendMoneyMarketAssetBorrowers.ts +67 -0
  19. package/src/hooks/backend/useBackendMoneyMarketAssetSuppliers.ts +67 -0
  20. package/src/hooks/backend/useBackendMoneyMarketPosition.ts +56 -0
  21. package/src/hooks/backend/useBackendOrderbook.ts +63 -0
  22. package/src/hooks/bridge/index.ts +5 -0
  23. package/src/hooks/bridge/useBridge.ts +57 -0
  24. package/src/hooks/bridge/useBridgeAllowance.ts +49 -0
  25. package/src/hooks/bridge/useBridgeApprove.ts +68 -0
  26. package/src/hooks/bridge/useGetBridgeableAmount.ts +50 -0
  27. package/src/hooks/bridge/useGetBridgeableTokens.ts +62 -0
  28. package/src/hooks/index.ts +4 -0
  29. package/src/hooks/migrate/index.ts +4 -0
  30. package/src/hooks/migrate/types.ts +15 -0
  31. package/src/hooks/migrate/useMigrate.tsx +110 -0
  32. package/src/hooks/migrate/useMigrationAllowance.tsx +79 -0
  33. package/src/hooks/migrate/useMigrationApprove.tsx +129 -0
  34. package/src/hooks/mm/index.ts +2 -1
  35. package/src/hooks/mm/useAToken.ts +47 -0
  36. package/src/hooks/mm/useBorrow.ts +2 -2
  37. package/src/hooks/mm/useMMAllowance.ts +2 -1
  38. package/src/hooks/mm/useMMApprove.ts +2 -1
  39. package/src/hooks/mm/useRepay.ts +2 -2
  40. package/src/hooks/mm/useReservesData.ts +1 -8
  41. package/src/hooks/mm/useReservesHumanized.ts +30 -0
  42. package/src/hooks/mm/useReservesList.ts +29 -0
  43. package/src/hooks/mm/useReservesUsdFormat.ts +38 -0
  44. package/src/hooks/mm/useSupply.ts +2 -2
  45. package/src/hooks/mm/useUserFormattedSummary.ts +54 -0
  46. package/src/hooks/mm/useUserReservesData.ts +30 -37
  47. package/src/hooks/mm/useWithdraw.ts +2 -2
  48. package/src/hooks/provider/useHubProvider.ts +3 -3
  49. package/src/hooks/provider/useSpokeProvider.ts +50 -18
  50. package/src/hooks/shared/index.ts +4 -0
  51. package/src/hooks/shared/useDeriveUserWalletAddress.ts +44 -0
  52. package/src/hooks/shared/useEstimateGas.ts +18 -0
  53. package/src/hooks/shared/useRequestTrustline.ts +103 -0
  54. package/src/hooks/shared/useStellarTrustlineCheck.ts +71 -0
  55. package/src/hooks/staking/index.ts +19 -0
  56. package/src/hooks/staking/useCancelUnstake.ts +52 -0
  57. package/src/hooks/staking/useClaim.ts +46 -0
  58. package/src/hooks/staking/useConvertedAssets.ts +47 -0
  59. package/src/hooks/staking/useInstantUnstake.ts +50 -0
  60. package/src/hooks/staking/useInstantUnstakeAllowance.ts +59 -0
  61. package/src/hooks/staking/useInstantUnstakeApprove.ts +52 -0
  62. package/src/hooks/staking/useInstantUnstakeRatio.ts +54 -0
  63. package/src/hooks/staking/useStake.ts +47 -0
  64. package/src/hooks/staking/useStakeAllowance.ts +57 -0
  65. package/src/hooks/staking/useStakeApprove.ts +50 -0
  66. package/src/hooks/staking/useStakeRatio.ts +53 -0
  67. package/src/hooks/staking/useStakingConfig.ts +40 -0
  68. package/src/hooks/staking/useStakingInfo.ts +50 -0
  69. package/src/hooks/staking/useUnstake.ts +54 -0
  70. package/src/hooks/staking/useUnstakeAllowance.ts +58 -0
  71. package/src/hooks/staking/useUnstakeApprove.ts +52 -0
  72. package/src/hooks/staking/useUnstakingInfo.ts +53 -0
  73. package/src/hooks/staking/useUnstakingInfoWithPenalty.ts +59 -0
  74. package/src/hooks/swap/index.ts +2 -1
  75. package/src/hooks/swap/useCancelSwap.ts +44 -0
  76. package/src/hooks/swap/useQuote.ts +21 -7
  77. package/src/hooks/swap/useStatus.ts +4 -4
  78. package/src/hooks/swap/{useCreateIntentOrder.ts → useSwap.ts} +19 -14
  79. package/src/hooks/swap/useSwapAllowance.ts +5 -1
  80. package/src/hooks/swap/useSwapApprove.ts +14 -14
  81. package/src/index.ts +0 -1
  82. package/src/providers/SodaxProvider.tsx +8 -20
  83. package/dist/contexts/index.d.ts +0 -8
  84. package/dist/contexts/index.d.ts.map +0 -1
  85. package/dist/core/index.d.ts +0 -4
  86. package/dist/core/index.d.ts.map +0 -1
  87. package/dist/hooks/index.d.ts +0 -5
  88. package/dist/hooks/index.d.ts.map +0 -1
  89. package/dist/hooks/mm/index.d.ts +0 -10
  90. package/dist/hooks/mm/index.d.ts.map +0 -1
  91. package/dist/hooks/mm/useBorrow.d.ts +0 -35
  92. package/dist/hooks/mm/useBorrow.d.ts.map +0 -1
  93. package/dist/hooks/mm/useHubWalletAddress.d.ts +0 -24
  94. package/dist/hooks/mm/useHubWalletAddress.d.ts.map +0 -1
  95. package/dist/hooks/mm/useMMAllowance.d.ts +0 -26
  96. package/dist/hooks/mm/useMMAllowance.d.ts.map +0 -1
  97. package/dist/hooks/mm/useMMApprove.d.ts +0 -27
  98. package/dist/hooks/mm/useMMApprove.d.ts.map +0 -1
  99. package/dist/hooks/mm/useRepay.d.ts +0 -35
  100. package/dist/hooks/mm/useRepay.d.ts.map +0 -1
  101. package/dist/hooks/mm/useReservesData.d.ts +0 -19
  102. package/dist/hooks/mm/useReservesData.d.ts.map +0 -1
  103. package/dist/hooks/mm/useSupply.d.ts +0 -34
  104. package/dist/hooks/mm/useSupply.d.ts.map +0 -1
  105. package/dist/hooks/mm/useUserReservesData.d.ts +0 -9
  106. package/dist/hooks/mm/useUserReservesData.d.ts.map +0 -1
  107. package/dist/hooks/mm/useWithdraw.d.ts +0 -33
  108. package/dist/hooks/mm/useWithdraw.d.ts.map +0 -1
  109. package/dist/hooks/provider/index.d.ts +0 -3
  110. package/dist/hooks/provider/index.d.ts.map +0 -1
  111. package/dist/hooks/provider/useHubProvider.d.ts +0 -3
  112. package/dist/hooks/provider/useHubProvider.d.ts.map +0 -1
  113. package/dist/hooks/provider/useSpokeProvider.d.ts +0 -18
  114. package/dist/hooks/provider/useSpokeProvider.d.ts.map +0 -1
  115. package/dist/hooks/shared/index.d.ts +0 -2
  116. package/dist/hooks/shared/index.d.ts.map +0 -1
  117. package/dist/hooks/shared/useSodaxContext.d.ts +0 -8
  118. package/dist/hooks/shared/useSodaxContext.d.ts.map +0 -1
  119. package/dist/hooks/swap/index.d.ts +0 -6
  120. package/dist/hooks/swap/index.d.ts.map +0 -1
  121. package/dist/hooks/swap/useCreateIntentOrder.d.ts +0 -33
  122. package/dist/hooks/swap/useCreateIntentOrder.d.ts.map +0 -1
  123. package/dist/hooks/swap/useQuote.d.ts +0 -39
  124. package/dist/hooks/swap/useQuote.d.ts.map +0 -1
  125. package/dist/hooks/swap/useStatus.d.ts +0 -31
  126. package/dist/hooks/swap/useStatus.d.ts.map +0 -1
  127. package/dist/hooks/swap/useSwapAllowance.d.ts +0 -23
  128. package/dist/hooks/swap/useSwapAllowance.d.ts.map +0 -1
  129. package/dist/hooks/swap/useSwapApprove.d.ts +0 -26
  130. package/dist/hooks/swap/useSwapApprove.d.ts.map +0 -1
  131. package/dist/index.d.ts.map +0 -1
  132. package/dist/providers/SodaxProvider.d.ts +0 -10
  133. package/dist/providers/SodaxProvider.d.ts.map +0 -1
  134. package/dist/providers/index.d.ts +0 -2
  135. package/dist/providers/index.d.ts.map +0 -1
  136. package/src/core/index.ts +0 -35
  137. package/src/hooks/mm/useHubWalletAddress.ts +0 -49
@@ -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
+ }
@@ -3,7 +3,8 @@ export * from './useRepay';
3
3
  export * from './useSupply';
4
4
  export * from './useWithdraw';
5
5
  export * from './useUserReservesData';
6
- export * from './useHubWalletAddress';
7
6
  export * from './useReservesData';
8
7
  export * from './useMMAllowance';
9
8
  export * from './useMMApprove';
9
+ export * from './useAToken';
10
+ export * from './useReservesUsdFormat';
@@ -0,0 +1,47 @@
1
+ import type { Address, XToken } from '@sodax/sdk';
2
+ import { useQuery, type UseQueryResult } from '@tanstack/react-query';
3
+ import { useSodaxContext } from '../shared/useSodaxContext';
4
+
5
+ /**
6
+ * React hook for fetching an AToken's ERC20 metadata from the Sodax money market.
7
+ *
8
+ * Fetches and caches the metadata (name, symbol, decimals, address) for a given aToken address and chain using React Query.
9
+ * This metadata is typically required for rendering balances and labels in UI components.
10
+ *
11
+ * @param {Address | undefined} aToken - The aToken contract address to look up. Should be an EVM address.
12
+ * @param {ChainId | undefined} chainId - The EVM chain ID for the aToken.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const { data: aToken, isLoading, error } = useAToken(aTokenAddress, chainId);
17
+ * if (aToken) {
18
+ * console.log(aToken.symbol); // 'aETH'
19
+ * }
20
+ * ```
21
+ *
22
+ * @returns {UseQueryResult<Erc20Token, Error>} A React Query result object containing:
23
+ * - data: The aToken ERC20 metadata when available.
24
+ * - isLoading: Loading state indicator.
25
+ * - error: Any error that occurred during data fetching.
26
+ */
27
+ export function useAToken(
28
+ aToken: Address | undefined,
29
+ ): UseQueryResult<XToken, Error> {
30
+ const { sodax } = useSodaxContext();
31
+
32
+ return useQuery({
33
+ queryKey: ['aToken', sodax.hubProvider.chainConfig.chain.id, aToken],
34
+ queryFn: async () => {
35
+ if (!aToken) {
36
+ throw new Error('aToken address or hub provider is not defined');
37
+ }
38
+
39
+ const aTokenData = await sodax.moneyMarket.data.getATokenData(aToken);
40
+ return {
41
+ ...aTokenData,
42
+ xChainId: sodax.hubProvider.chainConfig.chain.id,
43
+ };
44
+ },
45
+ enabled: !!aToken,
46
+ });
47
+ }
@@ -5,7 +5,7 @@ import { useSodaxContext } from '../shared/useSodaxContext';
5
5
  import type { SpokeProvider } from '@sodax/sdk';
6
6
  interface BorrowResponse {
7
7
  ok: true;
8
- value: [`0x${string}`, `0x${string}`];
8
+ value: [string, string];
9
9
  }
10
10
 
11
11
  /**
@@ -45,7 +45,7 @@ export function useBorrow(
45
45
  throw new Error('spokeProvider is not found');
46
46
  }
47
47
 
48
- const response = await sodax.moneyMarket.borrowAndSubmit(
48
+ const response = await sodax.moneyMarket.borrow(
49
49
  {
50
50
  token: spokeToken.address,
51
51
  amount: parseUnits(amount, 18),
@@ -37,10 +37,11 @@ export function useMMAllowance(
37
37
  queryKey: ['allowance', token.address, amount, action],
38
38
  queryFn: async () => {
39
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
40
41
  const allowance = await sodax.moneyMarket.isAllowanceValid(
41
42
  {
42
43
  token: token.address,
43
- amount: parseUnits(amount, token.decimals),
44
+ amount: parseUnits(amount, actionBasedDecimals),
44
45
  action,
45
46
  },
46
47
  spokeProvider,
@@ -39,10 +39,11 @@ export function useMMApprove(token: XToken, spokeProvider: SpokeProvider | undef
39
39
  if (!spokeProvider) {
40
40
  throw new Error('Spoke provider not found');
41
41
  }
42
+ const actionBasedDecimals = action === 'withdraw' || action === 'borrow' ? 18 : token.decimals; // withdraw and borrow actions are in aToken decimals
42
43
  const allowance = await sodax.moneyMarket.approve(
43
44
  {
44
45
  token: token.address,
45
- amount: parseUnits(amount, token.decimals),
46
+ amount: parseUnits(amount, actionBasedDecimals),
46
47
  action,
47
48
  },
48
49
  spokeProvider,
@@ -6,7 +6,7 @@ import { useSodaxContext } from '../shared/useSodaxContext';
6
6
 
7
7
  interface RepayResponse {
8
8
  ok: true;
9
- value: [`0x${string}`, `0x${string}`];
9
+ value: [string, string];
10
10
  }
11
11
 
12
12
  /**
@@ -46,7 +46,7 @@ export function useRepay(
46
46
  throw new Error('spokeProvider is not found');
47
47
  }
48
48
 
49
- const response = await sodax.moneyMarket.repayAndSubmit(
49
+ const response = await sodax.moneyMarket.repay(
50
50
  {
51
51
  token: spokeToken.address,
52
52
  amount: parseUnits(amount, spokeToken.decimals),
@@ -1,5 +1,3 @@
1
- import { getMoneyMarketConfig } from '@sodax/sdk';
2
- import type { HubChainId } from '@sodax/types';
3
1
  import { useQuery } from '@tanstack/react-query';
4
2
  import { useSodaxContext } from '../shared/useSodaxContext';
5
3
  /**
@@ -22,16 +20,11 @@ import { useSodaxContext } from '../shared/useSodaxContext';
22
20
 
23
21
  export function useReservesData() {
24
22
  const { sodax } = useSodaxContext();
25
- const hubChainId = (sodax.config?.hubProviderConfig?.chainConfig.chain.id ?? 'sonic') as HubChainId;
26
23
 
27
24
  return useQuery({
28
25
  queryKey: ['reservesData'],
29
26
  queryFn: async () => {
30
- const moneyMarketConfig = getMoneyMarketConfig(hubChainId);
31
- return await sodax.moneyMarket.getReservesData(
32
- moneyMarketConfig.uiPoolDataProvider,
33
- moneyMarketConfig.poolAddressesProvider,
34
- );
27
+ return await sodax.moneyMarket.data.getReservesData();
35
28
  },
36
29
  });
37
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
+ }
@@ -6,7 +6,7 @@ import { useSodaxContext } from '../shared/useSodaxContext';
6
6
 
7
7
  interface SupplyResponse {
8
8
  ok: true;
9
- value: [`0x${string}`, `0x${string}`];
9
+ value: [string, string];
10
10
  }
11
11
 
12
12
  /**
@@ -45,7 +45,7 @@ export function useSupply(
45
45
  throw new Error('spokeProvider is not found');
46
46
  }
47
47
 
48
- const response = await sodax.moneyMarket.supplyAndSubmit(
48
+ const response = await sodax.moneyMarket.supply(
49
49
  {
50
50
  token: spokeToken.address,
51
51
  amount: parseUnits(amount, spokeToken.decimals),
@@ -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
+ }
@@ -1,47 +1,40 @@
1
- import { allXTokens } from '@/core';
2
- import { encodeAddress, EvmWalletAbstraction, getMoneyMarketConfig, type EvmHubProvider } from '@sodax/sdk';
3
- import type { HubChainId, SpokeChainId } from '@sodax/types';
4
- import type { ChainId } from '@sodax/types';
5
- import { useQuery } from '@tanstack/react-query';
6
- import { useHubProvider } from '../provider/useHubProvider';
1
+ import type { SpokeProvider, UserReserveData } from '@sodax/sdk';
2
+ import { useQuery, type UseQueryResult } from '@tanstack/react-query';
7
3
  import { useSodaxContext } from '../shared/useSodaxContext';
8
4
 
9
- export function useUserReservesData(spokeChainId: ChainId, address: string | undefined) {
5
+ /**
6
+ * Hook for fetching user reserves data from the Sodax money market.
7
+ *
8
+ * This hook provides access to the current state of user reserves in the money market protocol.
9
+ * The data is automatically fetched and cached using React Query.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const { data: userReservesData, isLoading, error } = useUserReservesData(spokeProvider, address);
14
+ * ```
15
+ *
16
+ * @returns A React Query result object containing:
17
+ * - data: The user reserves data when available
18
+ * - isLoading: Loading state indicator
19
+ * - error: Any error that occurred during data fetching
20
+ */
21
+ export function useUserReservesData(
22
+ spokeProvider: SpokeProvider | undefined,
23
+ address: string | undefined,
24
+ refetchInterval = 5000,
25
+ ): UseQueryResult<readonly [readonly UserReserveData[], number], Error> {
10
26
  const { sodax } = useSodaxContext();
11
- const hubChainId = (sodax.config?.hubProviderConfig?.chainConfig.chain.id ?? 'sonic') as HubChainId;
12
- const hubProvider = useHubProvider();
13
27
 
14
- const { data: userReserves } = useQuery({
15
- queryKey: ['userReserves', spokeChainId, address],
28
+ return useQuery({
29
+ queryKey: ['userReserves', spokeProvider?.chainConfig.chain.id, address],
16
30
  queryFn: async () => {
17
- if (!hubProvider || !address) {
18
- return;
31
+ if (!spokeProvider) {
32
+ throw new Error('Spoke provider or address is not defined');
19
33
  }
20
34
 
21
- const addressBytes = encodeAddress(spokeChainId, address);
22
- const hubWalletAddress = await EvmWalletAbstraction.getUserHubWalletAddress(
23
- spokeChainId as SpokeChainId,
24
- addressBytes,
25
- hubProvider as EvmHubProvider,
26
- );
27
-
28
- const moneyMarketConfig = getMoneyMarketConfig(hubChainId);
29
- const [res] = await sodax.moneyMarket.getUserReservesData(
30
- hubWalletAddress as `0x${string}`,
31
- moneyMarketConfig.uiPoolDataProvider,
32
- moneyMarketConfig.poolAddressesProvider,
33
- );
34
-
35
- return res?.map(r => {
36
- return {
37
- ...r,
38
- token: allXTokens.find(t => t.address === r.underlyingAsset),
39
- };
40
- });
35
+ return await sodax.moneyMarket.data.getUserReservesData(spokeProvider);
41
36
  },
42
- enabled: !!spokeChainId && !!hubProvider && !!address,
43
- refetchInterval: 5000,
37
+ enabled: !!spokeProvider && !!address,
38
+ refetchInterval,
44
39
  });
45
-
46
- return userReserves;
47
40
  }
@@ -6,7 +6,7 @@ import { useSodaxContext } from '../shared/useSodaxContext';
6
6
 
7
7
  interface WithdrawResponse {
8
8
  ok: true;
9
- value: [`0x${string}`, `0x${string}`];
9
+ value: [string, string];
10
10
  }
11
11
 
12
12
  /**
@@ -44,7 +44,7 @@ export function useWithdraw(
44
44
  throw new Error('spokeProvider is not found');
45
45
  }
46
46
 
47
- const response = await sodax.moneyMarket.withdrawAndSubmit(
47
+ const response = await sodax.moneyMarket.withdraw(
48
48
  {
49
49
  token: spokeToken.address,
50
50
  // vault token on hub chain decimals is 18
@@ -1,8 +1,8 @@
1
1
  import type { EvmHubProvider } from '@sodax/sdk';
2
2
  import { useSodaxContext } from '../shared/useSodaxContext';
3
3
 
4
- export function useHubProvider(): EvmHubProvider | undefined {
5
- const { hubProvider } = useSodaxContext();
4
+ export function useHubProvider(): EvmHubProvider {
5
+ const { sodax } = useSodaxContext();
6
6
 
7
- return hubProvider;
7
+ return sodax.hubProvider;
8
8
  }