@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,79 +1,59 @@
|
|
|
1
|
-
import { useQuery, type
|
|
2
|
-
import type { SubmitSwapTxStatusResponse } from '@sodax/
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
1
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { RequestOverrideConfig, SubmitSwapTxStatusResponse } from '@sodax/sdk';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
4
|
+
import { unwrapResult } from './unwrapResult.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
5
6
|
|
|
6
|
-
export type UseBackendSubmitSwapTxStatusParams =
|
|
7
|
-
|
|
7
|
+
export type UseBackendSubmitSwapTxStatusParams = ReadHookParams<
|
|
8
|
+
SubmitSwapTxStatusResponse | undefined,
|
|
9
|
+
{
|
|
8
10
|
txHash: string | undefined;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
};
|
|
11
|
+
srcChainKey?: string;
|
|
12
|
+
apiConfig?: RequestOverrideConfig;
|
|
13
|
+
}
|
|
14
|
+
>;
|
|
14
15
|
|
|
15
16
|
/**
|
|
16
17
|
* React hook for polling the processing status of a submitted swap transaction.
|
|
17
18
|
*
|
|
18
|
-
* @param {UseBackendSubmitSwapTxStatusParams | undefined} params - Parameters for the query:
|
|
19
|
-
* - `params.txHash`: The transaction hash of the submitted swap; query is disabled if undefined or empty.
|
|
20
|
-
* - `params.srcChainId`: Optional source chain ID to narrow the status lookup.
|
|
21
|
-
* - `queryOptions`: Optional React Query options to override default behavior (e.g., refetchInterval, retry).
|
|
22
|
-
*
|
|
23
|
-
* @returns {UseQueryResult<SubmitSwapTxStatusResponse | undefined, Error>} React Query result object:
|
|
24
|
-
* - `data`: The status response or undefined if unavailable.
|
|
25
|
-
* - `isLoading`: Loading state.
|
|
26
|
-
* - `error`: Error instance if the query failed.
|
|
27
|
-
* - `refetch`: Function to re-trigger the query.
|
|
28
|
-
*
|
|
29
19
|
* @example
|
|
30
|
-
* const { data: status
|
|
31
|
-
* params: { txHash: '0x123...',
|
|
20
|
+
* const { data: status } = useBackendSubmitSwapTxStatus({
|
|
21
|
+
* params: { txHash: '0x123...', srcChainKey: 'sonic' },
|
|
32
22
|
* });
|
|
33
23
|
*
|
|
34
|
-
* if (status?.data.status === 'executed') {
|
|
35
|
-
* console.log('Swap completed!', status.data.result);
|
|
36
|
-
* }
|
|
37
|
-
*
|
|
38
24
|
* @remarks
|
|
39
|
-
* -
|
|
40
|
-
* - Default refetch interval is 1 second for real-time status polling.
|
|
41
|
-
* - Uses React Query for state management, caching, and retries.
|
|
25
|
+
* - Default refetch interval is 1 second; stops on 'executed' or 'failed' status.
|
|
42
26
|
*/
|
|
43
|
-
export const useBackendSubmitSwapTxStatus = (
|
|
44
|
-
params
|
|
45
|
-
|
|
27
|
+
export const useBackendSubmitSwapTxStatus = ({
|
|
28
|
+
params,
|
|
29
|
+
queryOptions,
|
|
30
|
+
}: UseBackendSubmitSwapTxStatusParams = {}): UseQueryResult<SubmitSwapTxStatusResponse | undefined, Error> => {
|
|
46
31
|
const { sodax } = useSodaxContext();
|
|
32
|
+
const txHash = params?.txHash;
|
|
33
|
+
const srcChainKey = params?.srcChainKey;
|
|
34
|
+
const apiConfig = params?.apiConfig;
|
|
47
35
|
|
|
48
|
-
|
|
49
|
-
queryKey: ['
|
|
50
|
-
|
|
36
|
+
return useQuery({
|
|
37
|
+
queryKey: ['backend', 'submitSwapTx', 'status', txHash, srcChainKey],
|
|
38
|
+
queryFn: async (): Promise<SubmitSwapTxStatusResponse | undefined> => {
|
|
39
|
+
if (!txHash) return undefined;
|
|
40
|
+
return unwrapResult(
|
|
41
|
+
await sodax.backendApi.getSubmitSwapTxStatus(
|
|
42
|
+
{
|
|
43
|
+
txHash,
|
|
44
|
+
srcChainKey,
|
|
45
|
+
},
|
|
46
|
+
apiConfig,
|
|
47
|
+
),
|
|
48
|
+
);
|
|
49
|
+
},
|
|
50
|
+
enabled: !!txHash && txHash.length > 0,
|
|
51
51
|
retry: 3,
|
|
52
|
-
refetchInterval:
|
|
52
|
+
refetchInterval: query => {
|
|
53
53
|
const status = query.state.data?.data?.status;
|
|
54
54
|
if (status === 'executed' || status === 'failed') return false;
|
|
55
55
|
return 1000;
|
|
56
56
|
},
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const queryOptions = {
|
|
60
|
-
...defaultQueryOptions,
|
|
61
|
-
...params?.queryOptions,
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
return useQuery({
|
|
65
57
|
...queryOptions,
|
|
66
|
-
queryFn: async (): Promise<SubmitSwapTxStatusResponse | undefined> => {
|
|
67
|
-
if (!params?.params?.txHash) {
|
|
68
|
-
return undefined;
|
|
69
|
-
}
|
|
70
|
-
return sodax.backendApi.getSubmitSwapTxStatus(
|
|
71
|
-
{
|
|
72
|
-
txHash: params.params.txHash,
|
|
73
|
-
srcChainId: params.params.srcChainId,
|
|
74
|
-
},
|
|
75
|
-
params.apiConfig,
|
|
76
|
-
);
|
|
77
|
-
},
|
|
78
58
|
});
|
|
79
59
|
};
|
|
@@ -1,81 +1,43 @@
|
|
|
1
1
|
import type { UserIntentsResponse, Address } from '@sodax/sdk';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import type {
|
|
2
|
+
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
4
|
+
import { unwrapResult } from './unwrapResult.js';
|
|
5
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
6
6
|
|
|
7
|
-
export type
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
queryOptions?: UseQueryOptions<UserIntentsResponse | undefined, Error>;
|
|
16
|
-
pagination?: BackendPaginationParams;
|
|
17
|
-
};
|
|
7
|
+
export type UseBackendUserIntentsParams = ReadHookParams<
|
|
8
|
+
UserIntentsResponse | undefined,
|
|
9
|
+
{
|
|
10
|
+
userAddress: Address | undefined;
|
|
11
|
+
startDate?: number;
|
|
12
|
+
endDate?: number;
|
|
13
|
+
}
|
|
14
|
+
>;
|
|
18
15
|
|
|
19
16
|
/**
|
|
20
|
-
* React hook for fetching user-created intents from the backend API for a given user address
|
|
21
|
-
* with optional support for a date filtering range.
|
|
22
|
-
*
|
|
23
|
-
* @param {UseBackendUserIntentsParams} args - Query configuration.
|
|
24
|
-
* @param {GetUserIntentsParams | undefined} args.params - User intent filter parameters.
|
|
25
|
-
* @param {Address} args.params.userAddress - The wallet address of the user (required).
|
|
26
|
-
* @param {number} [args.params.startDate] - Include intents created after this timestamp (ms).
|
|
27
|
-
* @param {number} [args.params.endDate] - Include intents created before this timestamp (ms).
|
|
28
|
-
* @param {UseQueryOptions<UserIntentsResponse | undefined, Error>} [args.queryOptions] - Optional React Query options.
|
|
29
|
-
* @param {BackendPaginationParams} [args.pagination] - (currently ignored) Pagination options.
|
|
30
|
-
*
|
|
31
|
-
* @returns {UseQueryResult<UserIntentsResponse | undefined, Error>} React Query result:
|
|
32
|
-
* - `data`: The user intent response, or undefined if unavailable.
|
|
33
|
-
* - `isLoading`: `true` if loading.
|
|
34
|
-
* - `error`: An Error instance if any occurred.
|
|
35
|
-
* - `refetch`: Function to refetch data.
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* const { data: userIntents, isLoading, error } = useBackendUserIntents({
|
|
39
|
-
* params: { userAddress: "0x123..." }
|
|
40
|
-
* });
|
|
17
|
+
* React hook for fetching user-created intents from the backend API for a given user address.
|
|
41
18
|
*
|
|
42
19
|
* @example
|
|
43
|
-
* const { data } = useBackendUserIntents({
|
|
44
|
-
* params: {
|
|
45
|
-
* userAddress: "0xabc...",
|
|
46
|
-
* startDate: Date.now() - 1_000_000,
|
|
47
|
-
* endDate: Date.now(),
|
|
48
|
-
* },
|
|
20
|
+
* const { data: userIntents } = useBackendUserIntents({
|
|
21
|
+
* params: { userAddress: '0x123...' },
|
|
49
22
|
* });
|
|
50
|
-
*
|
|
51
|
-
* @remarks
|
|
52
|
-
* The query is disabled if `params` or `params.userAddress` is missing or empty. Uses React Query for
|
|
53
|
-
* cache/state management and auto-retries failed requests three times by default.
|
|
54
23
|
*/
|
|
55
24
|
export const useBackendUserIntents = ({
|
|
56
25
|
params,
|
|
57
26
|
queryOptions,
|
|
58
|
-
}: UseBackendUserIntentsParams): UseQueryResult<UserIntentsResponse | undefined, Error> => {
|
|
27
|
+
}: UseBackendUserIntentsParams = {}): UseQueryResult<UserIntentsResponse | undefined, Error> => {
|
|
59
28
|
const { sodax } = useSodaxContext();
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
retry: 3,
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
queryOptions = {
|
|
67
|
-
...defaultQueryOptions,
|
|
68
|
-
...queryOptions, // override default query options if provided
|
|
69
|
-
};
|
|
29
|
+
const userAddress = params?.userAddress;
|
|
30
|
+
const startDate = params?.startDate;
|
|
31
|
+
const endDate = params?.endDate;
|
|
70
32
|
|
|
71
33
|
return useQuery({
|
|
72
|
-
|
|
34
|
+
queryKey: ['backend', 'intent', 'user', userAddress, startDate, endDate],
|
|
73
35
|
queryFn: async (): Promise<UserIntentsResponse | undefined> => {
|
|
74
|
-
if (!
|
|
75
|
-
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return sodax.backendApi.getUserIntents(params);
|
|
36
|
+
if (!userAddress) return undefined;
|
|
37
|
+
return unwrapResult(await sodax.backendApi.getUserIntents({ userAddress, startDate, endDate }));
|
|
79
38
|
},
|
|
39
|
+
enabled: !!userAddress && userAddress.length > 0,
|
|
40
|
+
retry: 3,
|
|
41
|
+
...queryOptions,
|
|
80
42
|
});
|
|
81
43
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export * from './useRadfiAuth';
|
|
2
|
-
export * from './useRadfiSession';
|
|
3
|
-
export * from './useFundTradingWallet';
|
|
4
|
-
export * from './useBitcoinBalance';
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './
|
|
1
|
+
export * from './useRadfiAuth.js';
|
|
2
|
+
export * from './useRadfiSession.js';
|
|
3
|
+
export * from './useFundTradingWallet.js';
|
|
4
|
+
export * from './useBitcoinBalance.js';
|
|
5
|
+
export * from './useTradingWallet.js';
|
|
6
|
+
export * from './useTradingWalletBalance.js';
|
|
7
|
+
export * from './useExpiredUtxos.js';
|
|
8
|
+
export * from './useRenewUtxos.js';
|
|
9
|
+
export * from './useRadfiWithdraw.js';
|
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
3
|
+
|
|
4
|
+
export type UseBitcoinBalanceParams = ReadHookParams<
|
|
5
|
+
bigint,
|
|
6
|
+
{
|
|
7
|
+
address: string | undefined;
|
|
8
|
+
rpcUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
>;
|
|
11
|
+
|
|
12
|
+
const DEFAULT_RPC_URL = 'https://mempool.space/api';
|
|
2
13
|
|
|
3
14
|
/**
|
|
4
15
|
* Hook to fetch BTC balance for any Bitcoin address.
|
|
@@ -7,12 +18,15 @@ import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
|
7
18
|
* The UTXO set already excludes spent outputs (even from unconfirmed txs),
|
|
8
19
|
* so the total is always the correct spendable balance.
|
|
9
20
|
*/
|
|
10
|
-
export function useBitcoinBalance(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
): UseQueryResult<bigint, Error> {
|
|
21
|
+
export function useBitcoinBalance({
|
|
22
|
+
params,
|
|
23
|
+
queryOptions,
|
|
24
|
+
}: UseBitcoinBalanceParams = {}): UseQueryResult<bigint, Error> {
|
|
25
|
+
const address = params?.address;
|
|
26
|
+
const rpcUrl = params?.rpcUrl ?? DEFAULT_RPC_URL;
|
|
27
|
+
|
|
14
28
|
return useQuery<bigint, Error>({
|
|
15
|
-
queryKey: ['
|
|
29
|
+
queryKey: ['bitcoin', 'balance', address],
|
|
16
30
|
queryFn: async () => {
|
|
17
31
|
if (!address) return 0n;
|
|
18
32
|
|
|
@@ -23,5 +37,6 @@ export function useBitcoinBalance(
|
|
|
23
37
|
return BigInt(utxos.reduce((sum, utxo) => sum + utxo.value, 0));
|
|
24
38
|
},
|
|
25
39
|
enabled: !!address,
|
|
40
|
+
...queryOptions,
|
|
26
41
|
});
|
|
27
42
|
}
|
|
@@ -1,25 +1,35 @@
|
|
|
1
1
|
import { useQuery, type UseQueryResult } from '@tanstack/react-query';
|
|
2
|
-
import type {
|
|
2
|
+
import type { RadfiUtxo, IBitcoinWalletProvider } from '@sodax/sdk';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
4
|
+
import type { ReadHookParams } from '../shared/types.js';
|
|
5
|
+
|
|
6
|
+
export type UseExpiredUtxosParams = ReadHookParams<
|
|
7
|
+
RadfiUtxo[],
|
|
8
|
+
{
|
|
9
|
+
walletProvider: IBitcoinWalletProvider | undefined;
|
|
10
|
+
tradingAddress: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
export function useExpiredUtxos({
|
|
15
|
+
params,
|
|
16
|
+
queryOptions,
|
|
17
|
+
}: UseExpiredUtxosParams = {}): UseQueryResult<RadfiUtxo[], Error> {
|
|
18
|
+
const { sodax } = useSodaxContext();
|
|
19
|
+
const walletProvider = params?.walletProvider;
|
|
20
|
+
const tradingAddress = params?.tradingAddress;
|
|
3
21
|
|
|
4
|
-
/**
|
|
5
|
-
* Hook to fetch expired UTXOs for a trading wallet address.
|
|
6
|
-
* UTXOs that are expired or within 2 weeks of expiry are considered invalid for trading
|
|
7
|
-
* and need to be renewed via the Radfi renew-utxo flow.
|
|
8
|
-
*/
|
|
9
|
-
export function useExpiredUtxos(
|
|
10
|
-
spokeProvider: BitcoinSpokeProvider | undefined,
|
|
11
|
-
tradingAddress: string | undefined,
|
|
12
|
-
): UseQueryResult<RadfiUtxo[], Error> {
|
|
13
22
|
return useQuery<RadfiUtxo[], Error>({
|
|
14
|
-
queryKey: ['
|
|
23
|
+
queryKey: ['bitcoin', 'expiredUtxos', tradingAddress],
|
|
15
24
|
queryFn: async () => {
|
|
16
|
-
if (!
|
|
17
|
-
throw new Error('
|
|
25
|
+
if (!walletProvider || !tradingAddress) {
|
|
26
|
+
throw new Error('walletProvider and tradingAddress are required');
|
|
18
27
|
}
|
|
19
|
-
const result = await
|
|
28
|
+
const result = await sodax.spoke.bitcoin.radfi.getExpiredUtxos(tradingAddress);
|
|
20
29
|
return result.data;
|
|
21
30
|
},
|
|
22
|
-
enabled: !!
|
|
23
|
-
refetchInterval: 60_000,
|
|
31
|
+
enabled: !!walletProvider && !!tradingAddress,
|
|
32
|
+
refetchInterval: 60_000,
|
|
33
|
+
...queryOptions,
|
|
24
34
|
});
|
|
25
35
|
}
|
|
@@ -1,39 +1,42 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
// packages/dapp-kit/src/hooks/bitcoin/useFundTradingWallet.ts
|
|
2
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
3
|
+
import { ChainKeys, type IBitcoinWalletProvider } from '@sodax/sdk';
|
|
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
|
+
|
|
8
|
+
export type UseFundTradingWalletVars = {
|
|
9
|
+
amount: bigint;
|
|
10
|
+
walletProvider: IBitcoinWalletProvider;
|
|
11
|
+
};
|
|
3
12
|
|
|
4
13
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* @returns {UseMutationResult} Mutation result — input is amount in satoshis, output is transaction ID
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```tsx
|
|
12
|
-
* const { mutateAsync: fundWallet, isPending } = useFundTradingWallet(spokeProvider);
|
|
13
|
-
*
|
|
14
|
-
* const handleFund = async () => {
|
|
15
|
-
* const txId = await fundWallet(100_000n); // fund 100,000 satoshis
|
|
16
|
-
* console.log('Funded:', txId);
|
|
17
|
-
* };
|
|
18
|
-
* ```
|
|
14
|
+
* React hook for funding the user's Radfi trading wallet from their personal Bitcoin wallet.
|
|
15
|
+
* Pure mutation: pass `{ amount, walletProvider }` to `mutate({...})`. Returns the broadcast tx
|
|
16
|
+
* id on success.
|
|
19
17
|
*/
|
|
20
|
-
export function useFundTradingWallet(
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
export function useFundTradingWallet({
|
|
19
|
+
mutationOptions,
|
|
20
|
+
}: MutationHookParams<string, UseFundTradingWalletVars> = {}): SafeUseMutationResult<
|
|
21
|
+
string,
|
|
22
|
+
Error,
|
|
23
|
+
UseFundTradingWalletVars
|
|
24
|
+
> {
|
|
25
|
+
const { sodax } = useSodaxContext();
|
|
23
26
|
const queryClient = useQueryClient();
|
|
24
27
|
|
|
25
|
-
return
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
return BitcoinSpokeService.fundTradingWallet(amount, spokeProvider);
|
|
28
|
+
return useSafeMutation<string, Error, UseFundTradingWalletVars>({
|
|
29
|
+
mutationKey: ['bitcoin', 'fundTradingWallet'],
|
|
30
|
+
...mutationOptions,
|
|
31
|
+
mutationFn: async ({ amount, walletProvider }) => {
|
|
32
|
+
const walletAddress = await walletProvider.getWalletAddress();
|
|
33
|
+
return sodax.spoke.bitcoin.fundTradingWallet(amount, walletAddress, walletProvider);
|
|
32
34
|
},
|
|
33
|
-
onSuccess: () => {
|
|
34
|
-
|
|
35
|
-
queryClient.invalidateQueries({ queryKey: ['
|
|
36
|
-
queryClient.invalidateQueries({ queryKey: ['xBalances'] });
|
|
35
|
+
onSuccess: async (data, vars, ctx) => {
|
|
36
|
+
queryClient.invalidateQueries({ queryKey: ['bitcoin', 'balance'] });
|
|
37
|
+
queryClient.invalidateQueries({ queryKey: ['bitcoin', 'tradingWalletBalance'] });
|
|
38
|
+
queryClient.invalidateQueries({ queryKey: ['shared', 'xBalances', ChainKeys.BITCOIN_MAINNET] });
|
|
39
|
+
await mutationOptions?.onSuccess?.(data, vars, ctx);
|
|
37
40
|
},
|
|
38
41
|
});
|
|
39
42
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
1
|
+
// packages/dapp-kit/src/hooks/bitcoin/useRadfiAuth.ts
|
|
2
|
+
import { RadfiApiError, type IBitcoinWalletProvider } from '@sodax/sdk';
|
|
3
|
+
import { useSodaxContext } from '../shared/useSodaxContext.js';
|
|
4
|
+
import type { MutationHookParams } from '../shared/types.js';
|
|
5
|
+
import { useSafeMutation, type SafeUseMutationResult } from '../shared/useSafeMutation.js';
|
|
3
6
|
|
|
4
7
|
export type RadfiSession = {
|
|
5
8
|
accessToken: string;
|
|
@@ -8,17 +11,20 @@ export type RadfiSession = {
|
|
|
8
11
|
publicKey: string;
|
|
9
12
|
};
|
|
10
13
|
|
|
14
|
+
export type UseRadfiAuthVars = {
|
|
15
|
+
walletProvider: IBitcoinWalletProvider;
|
|
16
|
+
};
|
|
17
|
+
|
|
11
18
|
type RadfiAuthResult = {
|
|
12
19
|
accessToken: string;
|
|
13
20
|
refreshToken: string;
|
|
14
21
|
tradingAddress: string;
|
|
15
22
|
};
|
|
16
23
|
|
|
17
|
-
const SESSION_KEY = (address: string) => `radfi_session_${address}`;
|
|
24
|
+
const SESSION_KEY = (address: string): string => `radfi_session_${address}`;
|
|
18
25
|
|
|
19
26
|
export function saveRadfiSession(address: string, session: RadfiSession): void {
|
|
20
27
|
try {
|
|
21
|
-
// Radfi tokens are only used for API rate-limiting / anti-spam, not for accessing user assets.
|
|
22
28
|
localStorage.setItem(SESSION_KEY(address), JSON.stringify(session));
|
|
23
29
|
} catch {}
|
|
24
30
|
}
|
|
@@ -39,62 +45,59 @@ export function clearRadfiSession(address: string): void {
|
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
48
|
+
* React hook for authenticating with Radfi via BIP322-signed message. Pure mutation: pass
|
|
49
|
+
* `{ walletProvider }` to `mutate({...})`. The hook itself takes no arguments other than the
|
|
50
|
+
* structural `mutationOptions` slot.
|
|
44
51
|
*/
|
|
45
|
-
export function useRadfiAuth(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
export function useRadfiAuth({
|
|
53
|
+
mutationOptions,
|
|
54
|
+
}: MutationHookParams<RadfiAuthResult, UseRadfiAuthVars> = {}): SafeUseMutationResult<
|
|
55
|
+
RadfiAuthResult,
|
|
56
|
+
Error,
|
|
57
|
+
UseRadfiAuthVars
|
|
58
|
+
> {
|
|
59
|
+
const { sodax } = useSodaxContext();
|
|
60
|
+
return useSafeMutation<RadfiAuthResult, Error, UseRadfiAuthVars>({
|
|
61
|
+
mutationKey: ['bitcoin', 'radfiAuth'],
|
|
62
|
+
...mutationOptions,
|
|
63
|
+
mutationFn: async ({ walletProvider }) => {
|
|
64
|
+
const radfi = sodax.spoke.bitcoin.radfi;
|
|
65
|
+
const walletAddress = await walletProvider.getWalletAddress();
|
|
55
66
|
const existingSession = loadRadfiSession(walletAddress);
|
|
56
67
|
const cachedPublicKey = existingSession?.publicKey;
|
|
57
68
|
|
|
58
69
|
try {
|
|
59
|
-
const { accessToken, refreshToken, tradingAddress, publicKey } = await
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
tradingAddress,
|
|
65
|
-
publicKey,
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
saveRadfiSession(walletAddress, session);
|
|
69
|
-
|
|
70
|
+
const { accessToken, refreshToken, tradingAddress, publicKey } = await radfi.authenticateWithWallet(
|
|
71
|
+
walletProvider,
|
|
72
|
+
cachedPublicKey,
|
|
73
|
+
);
|
|
74
|
+
saveRadfiSession(walletAddress, { accessToken, refreshToken, tradingAddress, publicKey });
|
|
70
75
|
return { accessToken, refreshToken, tradingAddress };
|
|
71
76
|
} catch (err: unknown) {
|
|
72
|
-
|
|
73
|
-
// Try to refresh with existing session if available.
|
|
74
|
-
const isAlreadyRegistered =
|
|
75
|
-
err instanceof Error &&
|
|
76
|
-
(err.message.includes('duplicatedPubKey') || err.message.includes('4008'));
|
|
77
|
+
const isAlreadyRegistered = err instanceof RadfiApiError && err.code === '4008';
|
|
77
78
|
|
|
78
79
|
if (isAlreadyRegistered && existingSession?.refreshToken) {
|
|
79
80
|
try {
|
|
80
|
-
const refreshed = await
|
|
81
|
-
|
|
81
|
+
const refreshed = await radfi.refreshAccessToken(existingSession.refreshToken);
|
|
82
|
+
radfi.setRadfiAccessToken(refreshed.accessToken, refreshed.refreshToken);
|
|
83
|
+
saveRadfiSession(walletAddress, {
|
|
82
84
|
...existingSession,
|
|
83
85
|
accessToken: refreshed.accessToken,
|
|
84
86
|
refreshToken: refreshed.refreshToken,
|
|
87
|
+
});
|
|
88
|
+
return {
|
|
89
|
+
accessToken: refreshed.accessToken,
|
|
90
|
+
refreshToken: refreshed.refreshToken,
|
|
91
|
+
tradingAddress: existingSession.tradingAddress,
|
|
85
92
|
};
|
|
86
|
-
spokeProvider.setRadfiAccessToken(refreshed.accessToken, refreshed.refreshToken);
|
|
87
|
-
saveRadfiSession(walletAddress, session);
|
|
88
|
-
return { accessToken: refreshed.accessToken, refreshToken: refreshed.refreshToken, tradingAddress: existingSession.tradingAddress };
|
|
89
93
|
} catch {
|
|
90
|
-
// Refresh also failed — clear stale session and guide user
|
|
91
94
|
clearRadfiSession(walletAddress);
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
throw new Error(
|
|
95
98
|
'This wallet is already registered with Radfi from another session. ' +
|
|
96
|
-
|
|
97
|
-
|
|
99
|
+
'Please clear your browser storage for this site and try again, ' +
|
|
100
|
+
'or wait for the previous session to expire.',
|
|
98
101
|
);
|
|
99
102
|
}
|
|
100
103
|
|