@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,82 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { useSodaxContext } from '../shared/useSodaxContext';
|
|
5
|
-
import type {
|
|
6
|
-
import { HubService } from '@sodax/sdk';
|
|
1
|
+
import type { SpokeChainKey } from '@sodax/sdk';
|
|
2
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
3
|
+
import { type Address, isAddress } from 'viem';
|
|
4
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
7
6
|
|
|
8
|
-
export type UseATokensBalancesParams =
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
export type UseATokensBalancesParams = ReadHookParams<
|
|
8
|
+
Map<Address, bigint>,
|
|
9
|
+
{
|
|
10
|
+
aTokens: readonly Address[];
|
|
11
|
+
spokeChainKey: SpokeChainKey | undefined;
|
|
12
|
+
userAddress: string | undefined;
|
|
13
|
+
}
|
|
14
|
+
>;
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
|
-
* React hook to fetch
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* hub wallet address and then fetches balanceOf for each aToken in a single multicall. Returns a Map
|
|
20
|
-
* of aToken address to balance, with querying/caching powered by React Query. This hook uses viem's
|
|
21
|
-
* multicall to batch all requests into a single RPC call for better performance.
|
|
22
|
-
*
|
|
23
|
-
* @param {UseATokensBalancesParams} params - Required params object:
|
|
24
|
-
* @property {readonly Address[]} aTokens - Array of aToken contract addresses to query balances for.
|
|
25
|
-
* @property {SpokeProvider} spokeProvider - The spoke provider to derive hub wallet address from.
|
|
26
|
-
* @property {string} userAddress - User's wallet address on the spoke chain.
|
|
27
|
-
* @property {UseQueryOptions<Map<Address, bigint>, Error>} queryOptions - React Query options to control query (e.g., staleTime, refetch, etc.).
|
|
28
|
-
*
|
|
29
|
-
* @returns {UseQueryResult<Map<Address, bigint>, Error>} React Query result object:
|
|
30
|
-
* - data: Map of aToken address to balance, if available
|
|
31
|
-
* - isLoading: Boolean loading state
|
|
32
|
-
* - error: Error, if API call fails
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* const { data: aTokenBalances, isLoading, error } = useATokensBalances({
|
|
36
|
-
* aTokens: [aToken1, aToken2, aToken3],
|
|
37
|
-
* spokeProvider,
|
|
38
|
-
* userAddress: '0x...',
|
|
39
|
-
* queryOptions: {}
|
|
40
|
-
* });
|
|
41
|
-
* const aToken1Balance = aTokenBalances?.get(aToken1);
|
|
17
|
+
* React hook to fetch aToken balances for a list of addresses in a single multicall.
|
|
18
|
+
* Derives the user's hub wallet via `EvmHubProvider.getUserHubWalletAddress` from the
|
|
19
|
+
* spoke `chainKey` + spoke wallet `userAddress`.
|
|
42
20
|
*/
|
|
43
21
|
export function useATokensBalances({
|
|
44
|
-
|
|
45
|
-
spokeProvider,
|
|
46
|
-
userAddress,
|
|
22
|
+
params,
|
|
47
23
|
queryOptions,
|
|
48
|
-
}: UseATokensBalancesParams): UseQueryResult<Map<Address, bigint>, Error> {
|
|
24
|
+
}: UseATokensBalancesParams = {}): UseQueryResult<Map<Address, bigint>, Error> {
|
|
49
25
|
const { sodax } = useSodaxContext();
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
};
|
|
54
|
-
queryOptions = {
|
|
55
|
-
...defaultQueryOptions,
|
|
56
|
-
...queryOptions, // override default query options if provided
|
|
57
|
-
};
|
|
26
|
+
const aTokens = params?.aTokens ?? [];
|
|
27
|
+
const spokeChainKey = params?.spokeChainKey;
|
|
28
|
+
const userAddress = params?.userAddress;
|
|
58
29
|
|
|
59
30
|
return useQuery({
|
|
60
|
-
|
|
31
|
+
queryKey: ['mm', 'aTokensBalances', aTokens, spokeChainKey, userAddress],
|
|
61
32
|
queryFn: async () => {
|
|
62
33
|
if (aTokens.length === 0) {
|
|
63
|
-
return new Map();
|
|
34
|
+
return new Map<Address, bigint>();
|
|
64
35
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
throw new Error('Spoke provider and user address are required');
|
|
36
|
+
if (!spokeChainKey || !userAddress) {
|
|
37
|
+
throw new Error('spokeChainKey and userAddress are required');
|
|
68
38
|
}
|
|
69
|
-
|
|
70
|
-
// Validate all addresses
|
|
71
39
|
for (const aToken of aTokens) {
|
|
72
40
|
if (!isAddress(aToken)) {
|
|
73
41
|
throw new Error(`Invalid aToken address: ${aToken}`);
|
|
74
42
|
}
|
|
75
43
|
}
|
|
76
44
|
|
|
77
|
-
const hubWalletAddress = await
|
|
78
|
-
|
|
79
|
-
return await sodax.moneyMarket.data.getATokensBalances(aTokens, hubWalletAddress);
|
|
45
|
+
const hubWalletAddress = await sodax.hubProvider.getUserHubWalletAddress(userAddress, spokeChainKey);
|
|
46
|
+
return sodax.moneyMarket.data.getATokensBalances(aTokens, hubWalletAddress);
|
|
80
47
|
},
|
|
48
|
+
enabled: aTokens.length > 0 && !!spokeChainKey && !!userAddress,
|
|
49
|
+
...queryOptions,
|
|
81
50
|
});
|
|
82
51
|
}
|
|
@@ -1,67 +1,49 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
1
|
+
// packages/dapp-kit/src/hooks/mm/useBorrow.ts
|
|
2
|
+
import type { MoneyMarketBorrowActionParams, SpokeChainKey, TxHashPair } from '@sodax/sdk';
|
|
3
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
4
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
5
|
+
import type { MutationHookParams } from '../shared/types.js';
|
|
6
|
+
import { useSafeMutation, type SafeUseMutationResult } from '../shared/useSafeMutation.js';
|
|
7
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export type
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Mutation variables for {@link useBorrow}. Generic over `K extends SpokeChainKey` (defaults to
|
|
11
|
+
* the full union). Sophisticated callers can lock K at the hook call site to narrow the
|
|
12
|
+
* `walletProvider` and `params.srcChainKey` types.
|
|
13
|
+
*/
|
|
14
|
+
export type UseBorrowVars<K extends SpokeChainKey = SpokeChainKey> = Omit<
|
|
15
|
+
MoneyMarketBorrowActionParams<K, false>,
|
|
16
|
+
'raw'
|
|
17
|
+
>;
|
|
14
18
|
|
|
15
19
|
/**
|
|
16
|
-
* React hook for borrowing tokens
|
|
17
|
-
*
|
|
18
|
-
* Encapsulates the async process to initiate a borrow transaction via the money market,
|
|
19
|
-
* handling transaction creation, submission, and cross-chain logic.
|
|
20
|
-
*
|
|
21
|
-
* @returns {UseMutationResult<
|
|
22
|
-
* BorrowResponse,
|
|
23
|
-
* MoneyMarketError<'CREATE_BORROW_INTENT_FAILED' | 'BORROW_UNKNOWN_ERROR' | RelayErrorCode>,
|
|
24
|
-
* UseBorrowParams
|
|
25
|
-
* >} A React Query mutation result object containing:
|
|
26
|
-
* - mutateAsync: (params: UseBorrowParams) => Promise<BorrowResponse>
|
|
27
|
-
* Triggers the borrow action. Expects an object with valid borrow params and a `SpokeProvider`.
|
|
28
|
-
* - isPending: `boolean` if a borrow transaction is in progress.
|
|
29
|
-
* - error: `MoneyMarketError` if the transaction fails, or `null`.
|
|
20
|
+
* React hook for borrowing tokens from the Sodax money market protocol.
|
|
30
21
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* const { mutateAsync: borrow, isPending, error } = useBorrow();
|
|
34
|
-
* await borrow({ params: borrowParams, spokeProvider });
|
|
35
|
-
* ```
|
|
36
|
-
*
|
|
37
|
-
* @throws {Error} When:
|
|
38
|
-
* - `spokeProvider` is missing or invalid.
|
|
39
|
-
* - The underlying borrow transaction fails.
|
|
22
|
+
* Throws on SDK failure so React Query's native error model engages (`isError`, `error`,
|
|
23
|
+
* `onError`, `retry`). Returns the unwrapped `TxHashPair` on success.
|
|
40
24
|
*/
|
|
41
|
-
export function useBorrow(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
UseBorrowParams
|
|
45
|
-
> {
|
|
25
|
+
export function useBorrow<K extends SpokeChainKey = SpokeChainKey>({
|
|
26
|
+
mutationOptions,
|
|
27
|
+
}: MutationHookParams<TxHashPair, UseBorrowVars<K>> = {}): SafeUseMutationResult<TxHashPair, Error, UseBorrowVars<K>> {
|
|
46
28
|
const { sodax } = useSodaxContext();
|
|
29
|
+
const queryClient = useQueryClient();
|
|
47
30
|
|
|
48
|
-
return
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
31
|
+
return useSafeMutation<TxHashPair, Error, UseBorrowVars<K>>({
|
|
32
|
+
mutationKey: ['mm', 'borrow'],
|
|
33
|
+
...mutationOptions,
|
|
34
|
+
mutationFn: async vars => unwrapResult(await sodax.moneyMarket.borrow({ ...vars, raw: false })),
|
|
35
|
+
onSuccess: async (data, vars, ctx) => {
|
|
36
|
+
const { params } = vars;
|
|
37
|
+
queryClient.invalidateQueries({ queryKey: ['mm', 'userReservesData', params.srcChainKey, params.srcAddress] });
|
|
38
|
+
queryClient.invalidateQueries({
|
|
39
|
+
queryKey: ['mm', 'userFormattedSummary', params.srcChainKey, params.srcAddress],
|
|
40
|
+
});
|
|
41
|
+
queryClient.invalidateQueries({ queryKey: ['mm', 'aTokensBalances'] });
|
|
42
|
+
const balanceChains = new Set([params.srcChainKey, params.dstChainKey ?? params.srcChainKey]);
|
|
43
|
+
for (const chainKey of balanceChains) {
|
|
44
|
+
queryClient.invalidateQueries({ queryKey: ['shared', 'xBalances', chainKey] });
|
|
56
45
|
}
|
|
57
|
-
|
|
58
|
-
const response = await sodax.moneyMarket.borrow(params, spokeProvider);
|
|
59
|
-
|
|
60
|
-
if (!response.ok) {
|
|
61
|
-
throw response.error;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return response;
|
|
46
|
+
await mutationOptions?.onSuccess?.(data, vars, ctx);
|
|
65
47
|
},
|
|
66
48
|
});
|
|
67
49
|
}
|
|
@@ -1,93 +1,57 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import type { MoneyMarketParams } from '@sodax/sdk';
|
|
2
|
+
import type { SpokeChainKey } from '@sodax/sdk';
|
|
3
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
4
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
6
|
+
|
|
7
|
+
export type UseMMAllowanceParams<K extends SpokeChainKey> = ReadHookParams<
|
|
8
|
+
boolean,
|
|
9
|
+
{
|
|
10
|
+
payload: MoneyMarketParams<K> | undefined;
|
|
11
|
+
}
|
|
12
|
+
>;
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
|
-
* Hook for checking token allowance for money market operations.
|
|
13
|
-
*
|
|
14
|
-
* This hook verifies if the user has approved enough tokens for a specific money market action
|
|
15
|
-
* (borrow/repay). It automatically queries and tracks the allowance status.
|
|
15
|
+
* Hook for checking token allowance / trustline sufficiency for money market operations.
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* @param {SpokeProvider} spokeProvider - The spoke provider to use for allowance checks
|
|
17
|
+
* Skips the on-chain check entirely for `borrow` and `withdraw` actions — those don't require
|
|
18
|
+
* approval, and the SDK already short-circuits to `true` for them. The early `enabled: false`
|
|
19
|
+
* here additionally avoids a render flash with `isLoading: true`.
|
|
21
20
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* - isLoading: Loading state indicator
|
|
25
|
-
* - error: Any error that occurred during the check
|
|
21
|
+
* The query key matches the invalidation keys emitted by `useMMApprove` and the four mutation
|
|
22
|
+
* hooks: `['mm', 'allowance', srcChainKey, token, action]`.
|
|
26
23
|
*
|
|
27
24
|
* @example
|
|
28
|
-
* ```
|
|
29
|
-
* const { data:
|
|
25
|
+
* ```tsx
|
|
26
|
+
* const { data: hasAllowance } = useMMAllowance({ params: { payload: supplyParams } });
|
|
30
27
|
* ```
|
|
31
28
|
*/
|
|
32
|
-
export function useMMAllowance({
|
|
29
|
+
export function useMMAllowance<K extends SpokeChainKey>({
|
|
33
30
|
params,
|
|
34
|
-
spokeProvider,
|
|
35
31
|
queryOptions,
|
|
36
|
-
}: UseMMAllowanceParams): UseQueryResult<boolean, Error> {
|
|
32
|
+
}: UseMMAllowanceParams<K> = {}): UseQueryResult<boolean, Error> {
|
|
37
33
|
const { sodax } = useSodaxContext();
|
|
34
|
+
const payload = params?.payload;
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
queryKey: ['mm', 'allowance',
|
|
41
|
-
/**
|
|
42
|
-
* IMPORTANT: Skip allowance checks for 'borrow' and 'withdraw' actions.
|
|
43
|
-
*
|
|
44
|
-
* Reason: According to the SDK's MoneyMarketService.isAllowanceValid() implementation,
|
|
45
|
-
* borrow and withdraw actions do NOT require ERC-20 token approval. The SDK's
|
|
46
|
-
* isAllowanceValid() method always returns `true` for these actions without making
|
|
47
|
-
* any on-chain allowance checks.
|
|
48
|
-
*
|
|
49
|
-
* This optimization prevents unnecessary RPC calls and avoids showing confusing states for actions that don't actually need approval.
|
|
50
|
-
*
|
|
51
|
-
* Only 'supply' and 'repay' actions require token approval and should trigger allowance checks.
|
|
52
|
-
*/
|
|
53
|
-
enabled: !!spokeProvider && !!params && params.action !== 'borrow' && params.action !== 'withdraw',
|
|
54
|
-
refetchInterval: 5000,
|
|
55
|
-
gcTime: 0, // Don't cache failed queries
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
queryOptions = {
|
|
59
|
-
...defaultQueryOptions,
|
|
60
|
-
...queryOptions, // override default query options if provided
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
return useQuery({
|
|
64
|
-
...queryOptions,
|
|
36
|
+
return useQuery<boolean, Error>({
|
|
37
|
+
queryKey: ['mm', 'allowance', payload?.srcChainKey, payload?.token, payload?.action],
|
|
65
38
|
queryFn: async () => {
|
|
66
|
-
if (!
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Early return for borrow/withdraw actions: these actions do NOT require ERC-20 token approval.
|
|
71
|
-
*
|
|
72
|
-
* The SDK's MoneyMarketService.isAllowanceValid() always returns `true` for borrow/withdraw
|
|
73
|
-
* without checking on-chain allowance. This is because:
|
|
74
|
-
* - Borrow: User receives tokens (no approval needed)
|
|
75
|
-
* - Withdraw: User withdraws their own supplied tokens (no approval needed)
|
|
76
|
-
*
|
|
77
|
-
* By returning `true` here, we avoid unnecessary RPC calls and ensure consistent behavior
|
|
78
|
-
* with the SDK's implementation.
|
|
79
|
-
*/
|
|
80
|
-
if (params.action === 'borrow' || params.action === 'withdraw') {
|
|
81
|
-
return true;
|
|
39
|
+
if (!payload) {
|
|
40
|
+
throw new Error('Params are required');
|
|
82
41
|
}
|
|
83
42
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
throw allowance.error;
|
|
43
|
+
// Borrow and withdraw don't require approval; SDK returns true instantly anyway.
|
|
44
|
+
if (payload.action === 'borrow' || payload.action === 'withdraw') {
|
|
45
|
+
return true;
|
|
88
46
|
}
|
|
89
47
|
|
|
90
|
-
|
|
48
|
+
const result = await sodax.moneyMarket.isAllowanceValid({ params: payload });
|
|
49
|
+
if (!result.ok) throw result.error;
|
|
50
|
+
return result.value;
|
|
91
51
|
},
|
|
52
|
+
enabled: !!payload && payload.action !== 'borrow' && payload.action !== 'withdraw',
|
|
53
|
+
refetchInterval: 5000,
|
|
54
|
+
gcTime: 0,
|
|
55
|
+
...queryOptions,
|
|
92
56
|
});
|
|
93
57
|
}
|
|
@@ -1,56 +1,49 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
1
|
+
// packages/dapp-kit/src/hooks/mm/useMMApprove.ts
|
|
2
|
+
import type { MoneyMarketApproveActionParams, SpokeChainKey, TxReturnType } from '@sodax/sdk';
|
|
3
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
4
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
5
|
+
import type { MutationHookParams } from '../shared/types.js';
|
|
6
|
+
import { useSafeMutation, type SafeUseMutationResult } from '../shared/useSafeMutation.js';
|
|
7
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Mutation variables for {@link useMMApprove}. Generic over `K extends SpokeChainKey` (defaults
|
|
11
|
+
* to the full union). Sophisticated callers can lock K at the hook call site to narrow the
|
|
12
|
+
* `walletProvider` and `params.srcChainKey` types.
|
|
13
|
+
*/
|
|
14
|
+
export type UseMMApproveVars<K extends SpokeChainKey = SpokeChainKey> = Omit<
|
|
15
|
+
MoneyMarketApproveActionParams<K, false>,
|
|
16
|
+
'raw'
|
|
17
|
+
>;
|
|
9
18
|
|
|
10
19
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* This hook manages the approval transaction, allowing the user
|
|
14
|
-
* to grant the protocol permission to spend their tokens for specific money market actions
|
|
15
|
-
* (such as supply, borrow, or repay). Upon successful approval, it also invalidates and
|
|
16
|
-
* refetches the associated allowance status so the UI remains up-to-date.
|
|
17
|
-
*
|
|
18
|
-
* @returns {UseMutationResult<string, Error, UseMMApproveParams>} A React Query mutation result containing:
|
|
19
|
-
* - mutateAsync: Function to trigger the approval (see below)
|
|
20
|
-
* - isPending: Boolean indicating if approval transaction is in progress
|
|
21
|
-
* - error: Error object if the last approval failed, null otherwise
|
|
20
|
+
* React hook for approving ERC-20 token spending (or trustline establishment) for a Sodax money
|
|
21
|
+
* market action.
|
|
22
22
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* await approve({ params: { token, amount: "100", action: "supply", ... }, spokeProvider });
|
|
27
|
-
* ```
|
|
28
|
-
*
|
|
29
|
-
* @throws {Error} When:
|
|
30
|
-
* - spokeProvider is undefined or invalid
|
|
31
|
-
* - Approval transaction fails for any reason
|
|
23
|
+
* Throws on SDK failure so React Query's native error model engages (`isError`, `error`,
|
|
24
|
+
* `onError`, `retry`). Returns the unwrapped tx return value on success. Invalidates the matching
|
|
25
|
+
* `['mm', 'allowance', srcChainKey, token, action]` query on confirmed success.
|
|
32
26
|
*/
|
|
33
|
-
export function useMMApprove
|
|
27
|
+
export function useMMApprove<K extends SpokeChainKey = SpokeChainKey>({
|
|
28
|
+
mutationOptions,
|
|
29
|
+
}: MutationHookParams<TxReturnType<K, false>, UseMMApproveVars<K>> = {}): SafeUseMutationResult<
|
|
30
|
+
TxReturnType<K, false>,
|
|
31
|
+
Error,
|
|
32
|
+
UseMMApproveVars<K>
|
|
33
|
+
> {
|
|
34
34
|
const { sodax } = useSodaxContext();
|
|
35
35
|
const queryClient = useQueryClient();
|
|
36
36
|
|
|
37
|
-
return
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
if (!allowance.ok) {
|
|
44
|
-
throw allowance.error;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return allowance.value;
|
|
48
|
-
},
|
|
49
|
-
onSuccess: (_, { params, spokeProvider }: UseMMApproveParams) => {
|
|
50
|
-
// Invalidate allowance query to refetch updated approval status
|
|
37
|
+
return useSafeMutation<TxReturnType<K, false>, Error, UseMMApproveVars<K>>({
|
|
38
|
+
mutationKey: ['mm', 'approve'],
|
|
39
|
+
...mutationOptions,
|
|
40
|
+
mutationFn: async vars => unwrapResult(await sodax.moneyMarket.approve({ ...vars, raw: false })),
|
|
41
|
+
onSuccess: async (data, vars, ctx) => {
|
|
42
|
+
const { params } = vars;
|
|
51
43
|
queryClient.invalidateQueries({
|
|
52
|
-
queryKey: ['mm', 'allowance',
|
|
44
|
+
queryKey: ['mm', 'allowance', params.srcChainKey, params.token, params.action],
|
|
53
45
|
});
|
|
46
|
+
await mutationOptions?.onSuccess?.(data, vars, ctx);
|
|
54
47
|
},
|
|
55
48
|
});
|
|
56
49
|
}
|
package/src/hooks/mm/useRepay.ts
CHANGED
|
@@ -1,64 +1,44 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
// packages/dapp-kit/src/hooks/mm/useRepay.ts
|
|
2
|
+
import type { MoneyMarketRepayActionParams, SpokeChainKey, TxHashPair } from '@sodax/sdk';
|
|
3
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
4
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
5
|
+
import type { MutationHookParams } from '../shared/types.js';
|
|
6
|
+
import { useSafeMutation, type SafeUseMutationResult } from '../shared/useSafeMutation.js';
|
|
7
|
+
import { unwrapResult } from '../shared/unwrapResult.js';
|
|
4
8
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export type
|
|
11
|
-
params: MoneyMarketRepayParams;
|
|
12
|
-
spokeProvider: SpokeProvider;
|
|
13
|
-
};
|
|
9
|
+
/**
|
|
10
|
+
* Mutation variables for {@link useRepay}. Generic over `K extends SpokeChainKey` (defaults to
|
|
11
|
+
* the full union). Sophisticated callers can lock K at the hook call site to narrow the
|
|
12
|
+
* `walletProvider` and `params.srcChainKey` types.
|
|
13
|
+
*/
|
|
14
|
+
export type UseRepayVars<K extends SpokeChainKey = SpokeChainKey> = Omit<MoneyMarketRepayActionParams<K, false>, 'raw'>;
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* React hook for repaying a borrow in the Sodax money market protocol.
|
|
17
18
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* and error handling.
|
|
21
|
-
*
|
|
22
|
-
* @returns {UseMutationResult<RepayResponse, MoneyMarketError<'CREATE_REPAY_INTENT_FAILED' | 'REPAY_UNKNOWN_ERROR' | RelayErrorCode>, UseRepayParams>} React Query mutation result object containing:
|
|
23
|
-
* - mutateAsync: (params: UseRepayParams) => Promise<RepayResponse>
|
|
24
|
-
* Initiates a repay transaction using the given MoneyMarketRepayParams and SpokeProvider.
|
|
25
|
-
* - isPending: boolean indicating if a transaction is in progress.
|
|
26
|
-
* - error: MoneyMarketError if an error occurred while repaying, otherwise undefined.
|
|
27
|
-
*
|
|
28
|
-
* @example
|
|
29
|
-
* ```typescript
|
|
30
|
-
* const { mutateAsync: repay, isPending, error } = useRepay();
|
|
31
|
-
* await repay({ params: repayParams, spokeProvider });
|
|
32
|
-
* ```
|
|
33
|
-
*
|
|
34
|
-
* @throws {Error} When:
|
|
35
|
-
* - `spokeProvider` is missing or invalid.
|
|
36
|
-
* - The underlying repay transaction fails.
|
|
19
|
+
* Throws on SDK failure so React Query's native error model engages (`isError`, `error`,
|
|
20
|
+
* `onError`, `retry`). Returns the unwrapped `TxHashPair` on success.
|
|
37
21
|
*/
|
|
38
|
-
export function useRepay(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
UseRepayParams
|
|
42
|
-
> {
|
|
22
|
+
export function useRepay<K extends SpokeChainKey = SpokeChainKey>({
|
|
23
|
+
mutationOptions,
|
|
24
|
+
}: MutationHookParams<TxHashPair, UseRepayVars<K>> = {}): SafeUseMutationResult<TxHashPair, Error, UseRepayVars<K>> {
|
|
43
25
|
const { sodax } = useSodaxContext();
|
|
26
|
+
const queryClient = useQueryClient();
|
|
44
27
|
|
|
45
|
-
return
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return response;
|
|
28
|
+
return useSafeMutation<TxHashPair, Error, UseRepayVars<K>>({
|
|
29
|
+
mutationKey: ['mm', 'repay'],
|
|
30
|
+
...mutationOptions,
|
|
31
|
+
mutationFn: async vars => unwrapResult(await sodax.moneyMarket.repay({ ...vars, raw: false })),
|
|
32
|
+
onSuccess: async (data, vars, ctx) => {
|
|
33
|
+
const { params } = vars;
|
|
34
|
+
queryClient.invalidateQueries({ queryKey: ['mm', 'userReservesData', params.srcChainKey, params.srcAddress] });
|
|
35
|
+
queryClient.invalidateQueries({
|
|
36
|
+
queryKey: ['mm', 'userFormattedSummary', params.srcChainKey, params.srcAddress],
|
|
37
|
+
});
|
|
38
|
+
queryClient.invalidateQueries({ queryKey: ['mm', 'aTokensBalances'] });
|
|
39
|
+
queryClient.invalidateQueries({ queryKey: ['mm', 'allowance', params.srcChainKey, params.token, params.action] });
|
|
40
|
+
queryClient.invalidateQueries({ queryKey: ['shared', 'xBalances', params.srcChainKey] });
|
|
41
|
+
await mutationOptions?.onSuccess?.(data, vars, ctx);
|
|
62
42
|
},
|
|
63
43
|
});
|
|
64
44
|
}
|
|
@@ -1,49 +1,23 @@
|
|
|
1
|
-
import { useQuery, type UseQueryResult, type UseQueryOptions } from '@tanstack/react-query';
|
|
2
|
-
import { useSodaxContext } from '../shared/useSodaxContext';
|
|
3
1
|
import type { AggregatedReserveData, BaseCurrencyInfo } from '@sodax/sdk';
|
|
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 UseReservesDataParams =
|
|
6
|
-
queryOptions?: UseQueryOptions<readonly [readonly AggregatedReserveData[], BaseCurrencyInfo], Error>;
|
|
7
|
-
};
|
|
6
|
+
export type UseReservesDataParams = ReadHookParams<readonly [readonly AggregatedReserveData[], BaseCurrencyInfo]>;
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
|
-
* React hook for fetching the latest reserves data
|
|
11
|
-
*
|
|
12
|
-
* Provides the full set of aggregated reserves and base currency information.
|
|
13
|
-
* Optionally accepts React Query options for customizing the query key, cache time, and related behaviors.
|
|
14
|
-
*
|
|
15
|
-
* @param params (optional) - Object including:
|
|
16
|
-
* - queryOptions: Custom React Query options
|
|
17
|
-
*
|
|
18
|
-
* @returns {UseQueryResult<readonly [readonly AggregatedReserveData[], BaseCurrencyInfo], Error>}
|
|
19
|
-
* React Query result object containing:
|
|
20
|
-
* - data: [aggregated reserves[], base currency info], or undefined if not loaded
|
|
21
|
-
* - isLoading: True if the request is loading
|
|
22
|
-
* - isError: True if the request failed
|
|
23
|
-
* - error: Error object, if present
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* const { data, isLoading, error } = useReservesData();
|
|
27
|
-
* const { data } = useReservesData({ queryOptions: { queryKey: ['custom', 'reservesData'] } });
|
|
9
|
+
* React hook for fetching the latest aggregated reserves data and base-currency info from the
|
|
10
|
+
* Sodax money market.
|
|
28
11
|
*/
|
|
29
|
-
export function useReservesData(
|
|
30
|
-
|
|
31
|
-
): UseQueryResult<readonly [readonly AggregatedReserveData[], BaseCurrencyInfo], Error> {
|
|
32
|
-
const defaultQueryOptions = {
|
|
33
|
-
queryKey: ['mm', 'reservesData'],
|
|
34
|
-
refetchInterval: 5000,
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const queryOptions = {
|
|
38
|
-
...defaultQueryOptions,
|
|
39
|
-
...params?.queryOptions, // override default query options if provided
|
|
40
|
-
}
|
|
12
|
+
export function useReservesData({
|
|
13
|
+
queryOptions,
|
|
14
|
+
}: UseReservesDataParams = {}): UseQueryResult<readonly [readonly AggregatedReserveData[], BaseCurrencyInfo], Error> {
|
|
41
15
|
const { sodax } = useSodaxContext();
|
|
42
16
|
|
|
43
17
|
return useQuery({
|
|
18
|
+
queryKey: ['mm', 'reservesData'],
|
|
19
|
+
queryFn: async () => sodax.moneyMarket.data.getReservesData(),
|
|
20
|
+
refetchInterval: 5000,
|
|
44
21
|
...queryOptions,
|
|
45
|
-
queryFn: async (): Promise<readonly [readonly AggregatedReserveData[], BaseCurrencyInfo]> => {
|
|
46
|
-
return await sodax.moneyMarket.data.getReservesData();
|
|
47
|
-
},
|
|
48
22
|
});
|
|
49
23
|
}
|