@sodax/dapp-kit 1.5.7-beta → 2.0.0-rc.2
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 +190 -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 +1581 -1531
- package/dist/index.mjs.map +1 -1
- package/package.json +21 -11
- 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 +13 -82
- 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 -2574
- package/dist/index.js.map +0 -1
- package/src/hooks/migrate/types.ts +0 -15
- package/src/hooks/migrate/useMigrate.tsx +0 -110
- package/src/hooks/migrate/useMigrationAllowance.tsx +0 -79
- package/src/hooks/migrate/useMigrationApprove.tsx +0 -129
- package/src/hooks/provider/useSpokeProvider.ts +0 -172
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { SpokeChainKey } from '@sodax/sdk';
|
|
2
2
|
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
3
|
-
import { useSodaxContext } from './useSodaxContext';
|
|
3
|
+
import { useSodaxContext } from './useSodaxContext.js';
|
|
4
4
|
import type { Address } from 'viem';
|
|
5
|
+
import type { ReadHookParams } from './types.js';
|
|
6
|
+
|
|
7
|
+
export type UseGetUserHubWalletAddressParams = ReadHookParams<
|
|
8
|
+
Address,
|
|
9
|
+
{
|
|
10
|
+
spokeChainId?: SpokeChainKey;
|
|
11
|
+
spokeAddress?: string;
|
|
12
|
+
}
|
|
13
|
+
>;
|
|
5
14
|
|
|
6
15
|
/**
|
|
7
16
|
* Hook for deriving user wallet address for hub abstraction.
|
|
@@ -14,41 +23,31 @@ import type { Address } from 'viem';
|
|
|
14
23
|
* The query is automatically enabled when both `spokeChainId` and `spokeAddress` are provided.
|
|
15
24
|
* This is a deterministic operation, so the result is cached and not refetched automatically.
|
|
16
25
|
*
|
|
17
|
-
* @param spokeChainId - Optional spoke chain ID. If not provided, the query will be disabled.
|
|
18
|
-
* @param spokeAddress - Optional user wallet address on the spoke chain. If not provided, the query will be disabled.
|
|
19
|
-
* @returns A React Query result object containing:
|
|
20
|
-
* - data: The derived user wallet address (Address) when available
|
|
21
|
-
* - isLoading: Loading state indicator
|
|
22
|
-
* - error: Any error that occurred during derivation (Error)
|
|
23
|
-
*
|
|
24
26
|
* @example
|
|
25
27
|
* ```typescript
|
|
26
|
-
* const { data: derivedAddress, isLoading, error } =
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* if (error) return <div>Error: {error.message}</div>;
|
|
30
|
-
* if (derivedAddress) return <div>Derived Address: {derivedAddress}</div>;
|
|
28
|
+
* const { data: derivedAddress, isLoading, error } = useGetUserHubWalletAddress({
|
|
29
|
+
* params: { spokeChainId, spokeAddress: userAddress },
|
|
30
|
+
* });
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
33
|
-
export function useGetUserHubWalletAddress(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
): UseQueryResult<Address, Error> {
|
|
33
|
+
export function useGetUserHubWalletAddress({
|
|
34
|
+
params,
|
|
35
|
+
queryOptions,
|
|
36
|
+
}: UseGetUserHubWalletAddressParams = {}): UseQueryResult<Address, Error> {
|
|
37
37
|
const { sodax } = useSodaxContext();
|
|
38
|
+
const spokeChainId = params?.spokeChainId;
|
|
39
|
+
const spokeAddress = params?.spokeAddress;
|
|
38
40
|
|
|
39
|
-
return useQuery({
|
|
40
|
-
queryKey: ['
|
|
41
|
+
return useQuery<Address, Error>({
|
|
42
|
+
queryKey: ['shared', 'userHubWalletAddress', spokeChainId, spokeAddress],
|
|
41
43
|
queryFn: async (): Promise<Address> => {
|
|
42
44
|
if (!spokeChainId || !spokeAddress) {
|
|
43
45
|
throw new Error('Spoke chain id and address are required');
|
|
44
46
|
}
|
|
45
|
-
|
|
46
|
-
// Determine if spokeChainId is a SpokeProvider object or SpokeChainId value
|
|
47
|
-
spokeChainId = typeof spokeChainId === 'object' ? spokeChainId.chainConfig.chain.id : spokeChainId;
|
|
48
|
-
|
|
49
|
-
return await HubService.getUserHubWalletAddress(spokeAddress, spokeChainId, sodax.hubProvider);
|
|
47
|
+
return await sodax.hubProvider.getUserHubWalletAddress(spokeAddress, spokeChainId);
|
|
50
48
|
},
|
|
51
49
|
enabled: !!spokeChainId && !!spokeAddress,
|
|
52
|
-
refetchInterval: false,
|
|
50
|
+
refetchInterval: false,
|
|
51
|
+
...queryOptions,
|
|
53
52
|
});
|
|
54
53
|
}
|
|
@@ -1,86 +1,59 @@
|
|
|
1
|
-
import { type SpokeProvider, StellarSpokeProvider, StellarSpokeService, type TxReturnType } from '@sodax/sdk';
|
|
2
1
|
import { useQueryClient } from '@tanstack/react-query';
|
|
3
2
|
import { useCallback, useState } from 'react';
|
|
3
|
+
import type { IStellarWalletProvider, StellarChainKey } from '@sodax/sdk';
|
|
4
|
+
import { useSodaxContext } from './useSodaxContext.js';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
* React hook to request a Stellar trustline for a given token and amount.
|
|
7
|
-
*
|
|
8
|
-
* This hook provides a callback function for requesting a trustline on the Stellar network
|
|
9
|
-
* using the provided SpokeProvider. It is intended for use with StellarSpokeProvider
|
|
10
|
-
* and will throw if used with a non-Stellar provider. Upon success, it invalidates
|
|
11
|
-
* the trustline check query to ensure UI reflects the updated trustline state.
|
|
12
|
-
*
|
|
13
|
-
* @template T - The type of SpokeProvider, defaults to SpokeProvider.
|
|
14
|
-
* @param {string | undefined} token - The Stellar asset code or token address for which to request a trustline.
|
|
15
|
-
* @returns {Object} An object containing:
|
|
16
|
-
* - `requestTrustline`: Function to trigger the trustline request.
|
|
17
|
-
* - `isLoading`: Whether the request is in progress.
|
|
18
|
-
* - `isRequested`: Whether a trustline has been successfully requested.
|
|
19
|
-
* - `error`: Any error encountered during the request.
|
|
20
|
-
* - `data`: The transaction result if successful.
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* ```tsx
|
|
24
|
-
* import { useRequestTrustline } from '@sodax/dapp-kit';
|
|
25
|
-
*
|
|
26
|
-
* const { requestTrustline, isLoading, isRequested, error, data } = useRequestTrustline('USDC-G...TOKEN');
|
|
27
|
-
*
|
|
28
|
-
* // To request a trustline:
|
|
29
|
-
* await requestTrustline({
|
|
30
|
-
* token: 'USDC-G...TOKEN',
|
|
31
|
-
* amount: 10000000n,
|
|
32
|
-
* spokeProvider: stellarProvider,
|
|
33
|
-
* });
|
|
34
|
-
*
|
|
35
|
-
* if (isLoading) return <span>Requesting trustline...</span>;
|
|
36
|
-
* if (error) return <span>Error: {error.message}</span>;
|
|
37
|
-
* if (isRequested) return <span>Trustline requested! Tx: {data?.txHash}</span>;
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
|
|
41
|
-
export function useRequestTrustline<T extends SpokeProvider = SpokeProvider>(
|
|
42
|
-
token: string | undefined,
|
|
43
|
-
): {
|
|
6
|
+
export function useRequestTrustline(token: string | undefined): {
|
|
44
7
|
requestTrustline: (params: {
|
|
45
8
|
token: string;
|
|
46
9
|
amount: bigint;
|
|
47
|
-
|
|
48
|
-
|
|
10
|
+
srcChainKey: StellarChainKey;
|
|
11
|
+
walletProvider: IStellarWalletProvider;
|
|
12
|
+
}) => Promise<string>;
|
|
49
13
|
isLoading: boolean;
|
|
50
14
|
isRequested: boolean;
|
|
51
15
|
error: Error | null;
|
|
52
|
-
data:
|
|
16
|
+
data: string | null;
|
|
53
17
|
} {
|
|
18
|
+
const { sodax } = useSodaxContext();
|
|
54
19
|
const queryClient = useQueryClient();
|
|
55
20
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
56
21
|
const [isRequested, setIsRequested] = useState<boolean>(false);
|
|
57
22
|
const [error, setError] = useState<Error | null>(null);
|
|
58
|
-
const [data, setData] = useState<
|
|
23
|
+
const [data, setData] = useState<string | null>(null);
|
|
59
24
|
|
|
60
25
|
const requestTrustline = useCallback(
|
|
61
26
|
async ({
|
|
62
27
|
token,
|
|
63
28
|
amount,
|
|
64
|
-
|
|
29
|
+
srcChainKey,
|
|
30
|
+
walletProvider,
|
|
65
31
|
}: {
|
|
66
32
|
token: string;
|
|
67
33
|
amount: bigint;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
34
|
+
srcChainKey: StellarChainKey;
|
|
35
|
+
walletProvider: IStellarWalletProvider;
|
|
36
|
+
}): Promise<string> => {
|
|
37
|
+
if (!token || !amount) {
|
|
38
|
+
const error = new Error('Token and amount are required');
|
|
72
39
|
setError(error);
|
|
73
40
|
throw error;
|
|
74
41
|
}
|
|
75
|
-
|
|
76
42
|
setIsLoading(true);
|
|
77
43
|
setError(null);
|
|
78
|
-
|
|
79
44
|
try {
|
|
80
|
-
const
|
|
45
|
+
const srcAddress = await walletProvider.getWalletAddress();
|
|
46
|
+
const result = await sodax.spoke.stellar.requestTrustline<false>({
|
|
47
|
+
raw: false,
|
|
48
|
+
srcChainKey,
|
|
49
|
+
srcAddress,
|
|
50
|
+
token,
|
|
51
|
+
amount,
|
|
52
|
+
walletProvider,
|
|
53
|
+
});
|
|
81
54
|
setData(result);
|
|
82
55
|
setIsRequested(true);
|
|
83
|
-
queryClient.invalidateQueries({ queryKey: ['
|
|
56
|
+
queryClient.invalidateQueries({ queryKey: ['shared', 'stellarTrustlineCheck', token] });
|
|
84
57
|
return result;
|
|
85
58
|
} catch (err) {
|
|
86
59
|
const error = err instanceof Error ? err : new Error('Unknown error occurred');
|
|
@@ -90,14 +63,8 @@ export function useRequestTrustline<T extends SpokeProvider = SpokeProvider>(
|
|
|
90
63
|
setIsLoading(false);
|
|
91
64
|
}
|
|
92
65
|
},
|
|
93
|
-
[queryClient],
|
|
66
|
+
[queryClient, sodax],
|
|
94
67
|
);
|
|
95
68
|
|
|
96
|
-
return {
|
|
97
|
-
requestTrustline,
|
|
98
|
-
isLoading,
|
|
99
|
-
isRequested,
|
|
100
|
-
error,
|
|
101
|
-
data,
|
|
102
|
-
};
|
|
69
|
+
return { requestTrustline, isLoading, isRequested, error, data };
|
|
103
70
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { toResult } from './useSafeMutation.js';
|
|
3
|
+
|
|
4
|
+
describe('toResult', () => {
|
|
5
|
+
it('packs a resolved promise into { ok: true, value }', async () => {
|
|
6
|
+
const r = await toResult(Promise.resolve(42));
|
|
7
|
+
expect(r).toEqual({ ok: true, value: 42 });
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it('packs a rejected promise into { ok: false, error } — never rejects', async () => {
|
|
11
|
+
const err = new Error('user rejected');
|
|
12
|
+
const r = await toResult(Promise.reject(err));
|
|
13
|
+
expect(r).toEqual({ ok: false, error: err });
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it('preserves non-Error throwables', async () => {
|
|
17
|
+
const r = await toResult(Promise.reject('boom'));
|
|
18
|
+
expect(r.ok).toBe(false);
|
|
19
|
+
if (!r.ok) expect(r.error).toBe('boom');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('forwards the resolved value verbatim (no copy/transform)', async () => {
|
|
23
|
+
const value = { spokeTxHash: '0xaaa', hubTxHash: '0xbbb' };
|
|
24
|
+
const r = await toResult(Promise.resolve(value));
|
|
25
|
+
if (r.ok) expect(r.value).toBe(value); // same reference
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('does not catch synchronous throws above the await — caller must produce a Promise', async () => {
|
|
29
|
+
// Documents the contract: toResult only neutralizes Promise rejections, not sync throws
|
|
30
|
+
// before the Promise is constructed. Hooks always pass `mutateAsync(vars)` which is async.
|
|
31
|
+
const wrapped = (): Promise<Result<number>> =>
|
|
32
|
+
toResult(
|
|
33
|
+
(async () => {
|
|
34
|
+
throw new Error('async throw');
|
|
35
|
+
})(),
|
|
36
|
+
);
|
|
37
|
+
const r = await wrapped();
|
|
38
|
+
expect(r.ok).toBe(false);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Local type alias to keep the file self-contained — mirrors @sodax/sdk's Result<T>.
|
|
43
|
+
type Result<T> = { ok: true; value: T } | { ok: false; error: unknown };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
// packages/dapp-kit/src/hooks/shared/useSafeMutation.ts
|
|
2
|
+
import type { Result } from '@sodax/sdk';
|
|
3
|
+
import {
|
|
4
|
+
useMutation,
|
|
5
|
+
type MutateOptions,
|
|
6
|
+
type UseMutationOptions,
|
|
7
|
+
type UseMutationResult,
|
|
8
|
+
} from '@tanstack/react-query';
|
|
9
|
+
import { useCallback } from 'react';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Return shape of every dapp-kit mutation hook. Extends `UseMutationResult` with one extra
|
|
13
|
+
* method, `mutateAsyncSafe`, that never rejects — it returns the SDK's `Result<T>` shape so
|
|
14
|
+
* callers can branch on `.ok` without `try/catch`.
|
|
15
|
+
*
|
|
16
|
+
* The underlying `mutationFn` still throws on SDK failure, so React Query's native error model
|
|
17
|
+
* (`isError`, `error`, `onError`, `retry`, `throwOnError`, devtools) keeps working as documented.
|
|
18
|
+
*/
|
|
19
|
+
export type SafeUseMutationResult<TData, TError, TVars, TContext = unknown> = UseMutationResult<
|
|
20
|
+
TData,
|
|
21
|
+
TError,
|
|
22
|
+
TVars,
|
|
23
|
+
TContext
|
|
24
|
+
> & {
|
|
25
|
+
/**
|
|
26
|
+
* Like `mutateAsync` but never rejects. Returns `Result<TData>` so callers can branch
|
|
27
|
+
* on `.ok` without `try/catch`.
|
|
28
|
+
*
|
|
29
|
+
* Use this for imperative flows where rejection-style errors are awkward — e.g. sequential
|
|
30
|
+
* `if (!hasAllowance) await approve(...); await action(...)` chains where the user-reject
|
|
31
|
+
* case is the modal failure mode, not an exceptional one.
|
|
32
|
+
*/
|
|
33
|
+
mutateAsyncSafe: (
|
|
34
|
+
vars: TVars,
|
|
35
|
+
options?: MutateOptions<TData, TError, TVars, TContext>,
|
|
36
|
+
) => Promise<Result<TData>>;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Wraps a `Promise<T>` (typically `mutateAsync(vars)`) into a `Promise<Result<T>>` that never
|
|
41
|
+
* rejects. Pure, side-effect-free — extracted for unit testing.
|
|
42
|
+
*/
|
|
43
|
+
export async function toResult<T>(promise: Promise<T>): Promise<Result<T>> {
|
|
44
|
+
try {
|
|
45
|
+
const value = await promise;
|
|
46
|
+
return { ok: true, value };
|
|
47
|
+
} catch (error) {
|
|
48
|
+
return { ok: false, error };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Drop-in replacement for `useMutation` that augments the result with `mutateAsyncSafe`. Used
|
|
54
|
+
* by every dapp-kit mutation hook so consumers can pick rejection-style (`mutateAsync`) or
|
|
55
|
+
* Result-style (`mutateAsyncSafe`) ergonomics without the hook author having to think about it.
|
|
56
|
+
*/
|
|
57
|
+
export function useSafeMutation<TData, TError, TVars, TContext = unknown>(
|
|
58
|
+
options: UseMutationOptions<TData, TError, TVars, TContext>,
|
|
59
|
+
): SafeUseMutationResult<TData, TError, TVars, TContext> {
|
|
60
|
+
const mutation = useMutation<TData, TError, TVars, TContext>(options);
|
|
61
|
+
const { mutateAsync } = mutation;
|
|
62
|
+
const mutateAsyncSafe = useCallback(
|
|
63
|
+
(vars: TVars, opts?: MutateOptions<TData, TError, TVars, TContext>): Promise<Result<TData>> =>
|
|
64
|
+
toResult(mutateAsync(vars, opts)),
|
|
65
|
+
[mutateAsync],
|
|
66
|
+
);
|
|
67
|
+
return { ...mutation, mutateAsyncSafe };
|
|
68
|
+
}
|
|
@@ -1,71 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { SpokeChainId, SpokeProvider } from '@sodax/sdk';
|
|
1
|
+
import { ChainKeys, type IStellarWalletProvider, type SpokeChainKey } from '@sodax/sdk';
|
|
3
2
|
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
3
|
+
import { useSodaxContext } from './useSodaxContext.js';
|
|
4
|
+
import type { ReadHookParams } from './types.js';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
* @param {string | undefined} token - The Stellar asset code or token address to check the trustline for.
|
|
15
|
-
* @param {bigint | undefined} amount - The minimum amount required for the trustline.
|
|
16
|
-
* @param {T | undefined} spokeProvider - The provider instance for interacting with the Stellar network.
|
|
17
|
-
* @param {SpokeChainId | undefined} chainId - The chain ID to determine if the check should be performed (only on Stellar mainnet).
|
|
18
|
-
* @returns {UseQueryResult<boolean, Error>} A React Query result object containing:
|
|
19
|
-
* - `data`: `true` if the trustline exists and is sufficient, `false` otherwise.
|
|
20
|
-
* - `error`: Any error encountered during the check.
|
|
21
|
-
* - `isLoading`: Whether the query is in progress.
|
|
22
|
-
* - Other React Query state.
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* ```tsx
|
|
26
|
-
* import { useStellarTrustlineCheck } from '@sodax/dapp-kit';
|
|
27
|
-
*
|
|
28
|
-
* const { data: hasTrustline, isLoading, error } = useStellarTrustlineCheck(
|
|
29
|
-
* 'USDC-G...TOKEN',
|
|
30
|
-
* 10000000n,
|
|
31
|
-
* stellarProvider,
|
|
32
|
-
* 'stellar'
|
|
33
|
-
* );
|
|
34
|
-
*
|
|
35
|
-
* if (isLoading) return <span>Checking trustline...</span>;
|
|
36
|
-
* if (error) return <span>Error: {error.message}</span>;
|
|
37
|
-
* if (!hasTrustline) return <span>Trustline not established or insufficient.</span>;
|
|
38
|
-
* return <span>Trustline is sufficient!</span>;
|
|
39
|
-
* ```
|
|
40
|
-
*/
|
|
6
|
+
export type UseStellarTrustlineCheckParams = ReadHookParams<
|
|
7
|
+
boolean,
|
|
8
|
+
{
|
|
9
|
+
token: string | undefined;
|
|
10
|
+
amount: bigint | undefined;
|
|
11
|
+
chainId: SpokeChainKey | undefined;
|
|
12
|
+
walletProvider: IStellarWalletProvider | undefined;
|
|
13
|
+
}
|
|
14
|
+
>;
|
|
41
15
|
|
|
42
|
-
export function useStellarTrustlineCheck
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (chainId !== STELLAR_MAINNET_CHAIN_ID) {
|
|
52
|
-
return true;
|
|
53
|
-
}
|
|
54
|
-
if (!spokeProvider || !token || !amount || !(spokeProvider instanceof StellarSpokeProvider)) {
|
|
55
|
-
console.error(
|
|
56
|
-
'Spoke provider, token or amount not found. Details: spokeProvider:',
|
|
57
|
-
spokeProvider,
|
|
58
|
-
'token:',
|
|
59
|
-
token,
|
|
60
|
-
'amount:',
|
|
61
|
-
amount,
|
|
62
|
-
);
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
const response = await StellarSpokeService.hasSufficientTrustline(token, amount, spokeProvider);
|
|
16
|
+
export function useStellarTrustlineCheck({
|
|
17
|
+
params,
|
|
18
|
+
queryOptions,
|
|
19
|
+
}: UseStellarTrustlineCheckParams = {}): UseQueryResult<boolean, Error> {
|
|
20
|
+
const { sodax } = useSodaxContext();
|
|
21
|
+
const token = params?.token;
|
|
22
|
+
const amount = params?.amount;
|
|
23
|
+
const chainId = params?.chainId;
|
|
24
|
+
const walletProvider = params?.walletProvider;
|
|
66
25
|
|
|
67
|
-
|
|
26
|
+
return useQuery<boolean, Error>({
|
|
27
|
+
queryKey: ['shared', 'stellarTrustlineCheck', token],
|
|
28
|
+
queryFn: async () => {
|
|
29
|
+
if (chainId !== ChainKeys.STELLAR_MAINNET) return true;
|
|
30
|
+
if (!walletProvider || !token || !amount) return false;
|
|
31
|
+
const walletAddress = await walletProvider.getWalletAddress();
|
|
32
|
+
return sodax.spoke.stellar.hasSufficientTrustline(token, amount, walletAddress);
|
|
68
33
|
},
|
|
69
|
-
enabled: !!
|
|
34
|
+
enabled: !!walletProvider && !!token && !!amount,
|
|
35
|
+
...queryOptions,
|
|
70
36
|
});
|
|
71
37
|
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import type { IXServiceBase, XToken } from '@sodax/sdk';
|
|
3
|
+
import { getXBalancesQueryOptions } from './useXBalances.js';
|
|
4
|
+
|
|
5
|
+
const makeToken = (symbol: string, address: string): XToken =>
|
|
6
|
+
({
|
|
7
|
+
symbol,
|
|
8
|
+
name: symbol,
|
|
9
|
+
decimals: 18,
|
|
10
|
+
address,
|
|
11
|
+
chainKey: 'sonic',
|
|
12
|
+
hubAsset: '0x0000000000000000000000000000000000000000',
|
|
13
|
+
vault: '0x0000000000000000000000000000000000000000',
|
|
14
|
+
}) as XToken;
|
|
15
|
+
|
|
16
|
+
const makeXService = (balances: Record<string, bigint>): IXServiceBase => ({
|
|
17
|
+
xChainType: 'EVM',
|
|
18
|
+
getBalance: vi.fn(),
|
|
19
|
+
getBalances: vi.fn().mockResolvedValue(balances),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe('getXBalancesQueryOptions', () => {
|
|
23
|
+
const tokenA = makeToken('AAA', '0xaaa');
|
|
24
|
+
const tokenB = makeToken('BBB', '0xbbb');
|
|
25
|
+
|
|
26
|
+
it('builds a queryKey pairing each token symbol with its address', () => {
|
|
27
|
+
const opts = getXBalancesQueryOptions({
|
|
28
|
+
xService: makeXService({}),
|
|
29
|
+
xChainId: 'sonic',
|
|
30
|
+
xTokens: [tokenA, tokenB],
|
|
31
|
+
address: '0xuser',
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
expect(opts.queryKey).toEqual([
|
|
35
|
+
'shared',
|
|
36
|
+
'xBalances',
|
|
37
|
+
'sonic',
|
|
38
|
+
[
|
|
39
|
+
['AAA', '0xaaa'],
|
|
40
|
+
['BBB', '0xbbb'],
|
|
41
|
+
],
|
|
42
|
+
'0xuser',
|
|
43
|
+
]);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('is disabled when xService is missing', () => {
|
|
47
|
+
const opts = getXBalancesQueryOptions({
|
|
48
|
+
xService: undefined,
|
|
49
|
+
xChainId: 'sonic',
|
|
50
|
+
xTokens: [tokenA],
|
|
51
|
+
address: '0xuser',
|
|
52
|
+
});
|
|
53
|
+
expect(opts.enabled).toBe(false);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('is disabled when address is missing', () => {
|
|
57
|
+
const opts = getXBalancesQueryOptions({
|
|
58
|
+
xService: makeXService({}),
|
|
59
|
+
xChainId: 'sonic',
|
|
60
|
+
xTokens: [tokenA],
|
|
61
|
+
address: undefined,
|
|
62
|
+
});
|
|
63
|
+
expect(opts.enabled).toBe(false);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('is disabled when xTokens is empty', () => {
|
|
67
|
+
const opts = getXBalancesQueryOptions({
|
|
68
|
+
xService: makeXService({}),
|
|
69
|
+
xChainId: 'sonic',
|
|
70
|
+
xTokens: [],
|
|
71
|
+
address: '0xuser',
|
|
72
|
+
});
|
|
73
|
+
expect(opts.enabled).toBe(false);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('is enabled when all inputs are present', () => {
|
|
77
|
+
const opts = getXBalancesQueryOptions({
|
|
78
|
+
xService: makeXService({}),
|
|
79
|
+
xChainId: 'sonic',
|
|
80
|
+
xTokens: [tokenA],
|
|
81
|
+
address: '0xuser',
|
|
82
|
+
});
|
|
83
|
+
expect(opts.enabled).toBe(true);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('queryFn delegates to xService.getBalances with address and tokens', async () => {
|
|
87
|
+
const expected = { '0xaaa': 42n };
|
|
88
|
+
const xService = makeXService(expected);
|
|
89
|
+
|
|
90
|
+
const opts = getXBalancesQueryOptions({
|
|
91
|
+
xService,
|
|
92
|
+
xChainId: 'sonic',
|
|
93
|
+
xTokens: [tokenA],
|
|
94
|
+
address: '0xuser',
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const result = await opts.queryFn();
|
|
98
|
+
expect(result).toEqual(expected);
|
|
99
|
+
expect(xService.getBalances).toHaveBeenCalledWith('0xuser', [tokenA]);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('queryFn returns {} when xService is undefined (defensive, enabled should prevent this)', async () => {
|
|
103
|
+
const opts = getXBalancesQueryOptions({
|
|
104
|
+
xService: undefined,
|
|
105
|
+
xChainId: 'sonic',
|
|
106
|
+
xTokens: [tokenA],
|
|
107
|
+
address: '0xuser',
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const result = await opts.queryFn();
|
|
111
|
+
expect(result).toEqual({});
|
|
112
|
+
});
|
|
113
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { type UseQueryResult, useQuery } from '@tanstack/react-query';
|
|
2
|
+
import type { SpokeChainKey, IXServiceBase, XToken } from '@sodax/sdk';
|
|
3
|
+
import type { ReadHookParams } from './types.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Domain inputs for {@link useXBalances}. `xChainId` is optional so the hook can be mounted
|
|
7
|
+
* before a chain is selected; `enabled` gates execution on every required field being present.
|
|
8
|
+
*/
|
|
9
|
+
export interface XBalancesInputs {
|
|
10
|
+
xService: IXServiceBase | undefined;
|
|
11
|
+
xChainId: SpokeChainKey | undefined;
|
|
12
|
+
xTokens: readonly XToken[];
|
|
13
|
+
address: string | undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type UseXBalancesParams = ReadHookParams<Record<string, bigint>, XBalancesInputs>;
|
|
17
|
+
|
|
18
|
+
const REFETCH_INTERVAL_MS = 5_000;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Pure builder for {@link useXBalances} query options. Exported for unit
|
|
22
|
+
* tests and for advanced callers that compose their own `useQuery` wrapper.
|
|
23
|
+
*/
|
|
24
|
+
export function getXBalancesQueryOptions({ xService, xChainId, xTokens, address }: XBalancesInputs) {
|
|
25
|
+
return {
|
|
26
|
+
// Pair symbol + address: readable in devtools, unique on-chain (symbol alone
|
|
27
|
+
// can collide — e.g. scam tokens copying legitimate ticker).
|
|
28
|
+
queryKey: ['shared', 'xBalances', xChainId, xTokens.map(x => [x.symbol, x.address] as const), address] as const,
|
|
29
|
+
queryFn: async (): Promise<Record<string, bigint>> => {
|
|
30
|
+
if (!xService) return {};
|
|
31
|
+
return xService.getBalances(address, xTokens);
|
|
32
|
+
},
|
|
33
|
+
enabled: !!xService && !!address && xTokens.length > 0,
|
|
34
|
+
refetchInterval: REFETCH_INTERVAL_MS,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Fetch token balances for multiple tokens on a specific chain. Returns an
|
|
40
|
+
* object mapping each token's address to its balance in smallest unit.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```tsx
|
|
44
|
+
* const xService = useXService({ xChainType: getXChainType(xChainId) });
|
|
45
|
+
* const { data: balances } = useXBalances({ params: { xService, xChainId, xTokens, address } });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export function useXBalances({
|
|
49
|
+
params,
|
|
50
|
+
queryOptions,
|
|
51
|
+
}: UseXBalancesParams = {}): UseQueryResult<Record<string, bigint>> {
|
|
52
|
+
return useQuery({
|
|
53
|
+
...getXBalancesQueryOptions({
|
|
54
|
+
xService: params?.xService,
|
|
55
|
+
xChainId: params?.xChainId,
|
|
56
|
+
xTokens: params?.xTokens ?? [],
|
|
57
|
+
address: params?.address,
|
|
58
|
+
}),
|
|
59
|
+
...queryOptions,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
// packages/dapp-kit/src/hooks/staking/index.ts
|
|
2
|
-
export { useStake } from './useStake';
|
|
3
|
-
export { useStakeApprove } from './useStakeApprove';
|
|
4
|
-
export { useStakeAllowance } from './useStakeAllowance';
|
|
5
|
-
export { useUnstake } from './useUnstake';
|
|
6
|
-
export { useClaim } from './useClaim';
|
|
7
|
-
export { useCancelUnstake } from './useCancelUnstake';
|
|
8
|
-
export { useStakingInfo } from './useStakingInfo';
|
|
9
|
-
export { useUnstakingInfoWithPenalty } from './useUnstakingInfoWithPenalty';
|
|
10
|
-
export { useStakingConfig } from './useStakingConfig';
|
|
11
|
-
export { useStakeRatio } from './useStakeRatio';
|
|
12
|
-
export { useInstantUnstakeRatio } from './useInstantUnstakeRatio';
|
|
13
|
-
export { useConvertedAssets } from './useConvertedAssets';
|
|
14
|
-
export { useInstantUnstake } from './useInstantUnstake';
|
|
15
|
-
export { useUnstakeAllowance } from './useUnstakeAllowance';
|
|
16
|
-
export { useUnstakeApprove } from './useUnstakeApprove';
|
|
17
|
-
export { useUnstakingInfo } from './useUnstakingInfo';
|
|
18
|
-
export { useInstantUnstakeApprove } from './useInstantUnstakeApprove';
|
|
19
|
-
export { useInstantUnstakeAllowance } from './useInstantUnstakeAllowance';
|
|
2
|
+
export { useStake } from './useStake.js';
|
|
3
|
+
export { useStakeApprove } from './useStakeApprove.js';
|
|
4
|
+
export { useStakeAllowance } from './useStakeAllowance.js';
|
|
5
|
+
export { useUnstake } from './useUnstake.js';
|
|
6
|
+
export { useClaim } from './useClaim.js';
|
|
7
|
+
export { useCancelUnstake } from './useCancelUnstake.js';
|
|
8
|
+
export { useStakingInfo } from './useStakingInfo.js';
|
|
9
|
+
export { useUnstakingInfoWithPenalty } from './useUnstakingInfoWithPenalty.js';
|
|
10
|
+
export { useStakingConfig } from './useStakingConfig.js';
|
|
11
|
+
export { useStakeRatio } from './useStakeRatio.js';
|
|
12
|
+
export { useInstantUnstakeRatio } from './useInstantUnstakeRatio.js';
|
|
13
|
+
export { useConvertedAssets } from './useConvertedAssets.js';
|
|
14
|
+
export { useInstantUnstake } from './useInstantUnstake.js';
|
|
15
|
+
export { useUnstakeAllowance } from './useUnstakeAllowance.js';
|
|
16
|
+
export { useUnstakeApprove } from './useUnstakeApprove.js';
|
|
17
|
+
export { useUnstakingInfo } from './useUnstakingInfo.js';
|
|
18
|
+
export { useInstantUnstakeApprove } from './useInstantUnstakeApprove.js';
|
|
19
|
+
export { useInstantUnstakeAllowance } from './useInstantUnstakeAllowance.js';
|