@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.
Files changed (202) hide show
  1. package/README.md +300 -422
  2. package/ai-exported/AGENTS.md +134 -0
  3. package/ai-exported/integration/README.md +49 -0
  4. package/ai-exported/integration/ai-rules.md +79 -0
  5. package/ai-exported/integration/architecture.md +274 -0
  6. package/ai-exported/integration/features/README.md +29 -0
  7. package/ai-exported/integration/features/auxiliary-services.md +169 -0
  8. package/ai-exported/integration/features/bitcoin.md +87 -0
  9. package/ai-exported/integration/features/bridge.md +91 -0
  10. package/ai-exported/integration/features/dex.md +152 -0
  11. package/ai-exported/integration/features/migration.md +118 -0
  12. package/ai-exported/integration/features/money-market.md +116 -0
  13. package/ai-exported/integration/features/staking.md +123 -0
  14. package/ai-exported/integration/features/swap.md +101 -0
  15. package/ai-exported/integration/quickstart.md +187 -0
  16. package/ai-exported/integration/recipes/README.md +136 -0
  17. package/ai-exported/integration/recipes/backend-queries.md +157 -0
  18. package/ai-exported/integration/recipes/bitcoin.md +193 -0
  19. package/ai-exported/integration/recipes/bridge.md +174 -0
  20. package/ai-exported/integration/recipes/dex.md +204 -0
  21. package/ai-exported/integration/recipes/invalidations.md +115 -0
  22. package/ai-exported/integration/recipes/migration.md +212 -0
  23. package/ai-exported/integration/recipes/money-market.md +206 -0
  24. package/ai-exported/integration/recipes/mutation-error-handling.md +118 -0
  25. package/ai-exported/integration/recipes/observability.md +93 -0
  26. package/ai-exported/integration/recipes/setup.md +144 -0
  27. package/ai-exported/integration/recipes/staking.md +202 -0
  28. package/ai-exported/integration/recipes/swap.md +272 -0
  29. package/ai-exported/integration/recipes/wallet-connectivity.md +101 -0
  30. package/ai-exported/integration/reference/README.md +12 -0
  31. package/ai-exported/integration/reference/glossary.md +188 -0
  32. package/ai-exported/integration/reference/hooks-index.md +190 -0
  33. package/ai-exported/integration/reference/public-api.md +110 -0
  34. package/ai-exported/integration/reference/querykey-conventions.md +179 -0
  35. package/ai-exported/migration/README.md +60 -0
  36. package/ai-exported/migration/ai-rules.md +81 -0
  37. package/ai-exported/migration/breaking-changes/hook-signatures.md +233 -0
  38. package/ai-exported/migration/breaking-changes/querykey-conventions.md +108 -0
  39. package/ai-exported/migration/breaking-changes/result-handling.md +211 -0
  40. package/ai-exported/migration/breaking-changes/sdk-leakage.md +165 -0
  41. package/ai-exported/migration/checklist.md +89 -0
  42. package/ai-exported/migration/features/README.md +34 -0
  43. package/ai-exported/migration/features/auxiliary-services.md +114 -0
  44. package/ai-exported/migration/features/bitcoin.md +88 -0
  45. package/ai-exported/migration/features/bridge.md +123 -0
  46. package/ai-exported/migration/features/dex.md +101 -0
  47. package/ai-exported/migration/features/migration.md +120 -0
  48. package/ai-exported/migration/features/money-market.md +97 -0
  49. package/ai-exported/migration/features/staking.md +109 -0
  50. package/ai-exported/migration/features/swap.md +118 -0
  51. package/ai-exported/migration/recipes.md +188 -0
  52. package/ai-exported/migration/reference/README.md +15 -0
  53. package/ai-exported/migration/reference/deleted-hooks.md +110 -0
  54. package/ai-exported/migration/reference/error-shape-crosswalk.md +144 -0
  55. package/ai-exported/migration/reference/renamed-hooks.md +66 -0
  56. package/dist/index.cjs +2642 -0
  57. package/dist/index.cjs.map +1 -0
  58. package/dist/index.d.cts +1550 -0
  59. package/dist/index.d.ts +1020 -2051
  60. package/dist/index.mjs +1581 -1531
  61. package/dist/index.mjs.map +1 -1
  62. package/package.json +21 -11
  63. package/src/contexts/index.ts +0 -3
  64. package/src/hooks/_mutationContract.test.ts +99 -0
  65. package/src/hooks/backend/README.md +2 -2
  66. package/src/hooks/backend/index.ts +13 -13
  67. package/src/hooks/backend/unwrapResult.ts +1 -0
  68. package/src/hooks/backend/useBackendAllMoneyMarketAssets.ts +13 -45
  69. package/src/hooks/backend/useBackendAllMoneyMarketBorrowers.ts +29 -59
  70. package/src/hooks/backend/useBackendIntentByHash.ts +21 -47
  71. package/src/hooks/backend/useBackendIntentByTxHash.ts +23 -50
  72. package/src/hooks/backend/useBackendMoneyMarketAsset.ts +21 -54
  73. package/src/hooks/backend/useBackendMoneyMarketAssetBorrowers.ts +30 -57
  74. package/src/hooks/backend/useBackendMoneyMarketAssetSuppliers.ts +31 -58
  75. package/src/hooks/backend/useBackendMoneyMarketPosition.ts +22 -38
  76. package/src/hooks/backend/useBackendOrderbook.ts +27 -49
  77. package/src/hooks/backend/useBackendSubmitSwapTx.ts +30 -36
  78. package/src/hooks/backend/useBackendSubmitSwapTxStatus.ts +38 -58
  79. package/src/hooks/backend/useBackendUserIntents.ts +25 -63
  80. package/src/hooks/bitcoin/index.ts +9 -8
  81. package/src/hooks/bitcoin/useBitcoinBalance.ts +20 -5
  82. package/src/hooks/bitcoin/useExpiredUtxos.ts +26 -16
  83. package/src/hooks/bitcoin/useFundTradingWallet.ts +33 -30
  84. package/src/hooks/bitcoin/useRadfiAuth.ts +43 -40
  85. package/src/hooks/bitcoin/useRadfiSession.ts +53 -59
  86. package/src/hooks/bitcoin/useRadfiWithdraw.ts +35 -53
  87. package/src/hooks/bitcoin/useRenewUtxos.ts +30 -50
  88. package/src/hooks/bitcoin/useTradingWallet.ts +1 -1
  89. package/src/hooks/bitcoin/useTradingWalletBalance.ts +25 -14
  90. package/src/hooks/bridge/index.ts +5 -5
  91. package/src/hooks/bridge/useBridge.ts +29 -55
  92. package/src/hooks/bridge/useBridgeAllowance.ts +38 -38
  93. package/src/hooks/bridge/useBridgeApprove.ts +32 -57
  94. package/src/hooks/bridge/useGetBridgeableAmount.ts +23 -37
  95. package/src/hooks/bridge/useGetBridgeableTokens.ts +27 -50
  96. package/src/hooks/dex/index.ts +16 -16
  97. package/src/hooks/dex/useClaimRewards.ts +35 -54
  98. package/src/hooks/dex/useCreateDecreaseLiquidityParams.ts +7 -20
  99. package/src/hooks/dex/useCreateDepositParams.ts +7 -21
  100. package/src/hooks/dex/useCreateSupplyLiquidityParams.ts +13 -28
  101. package/src/hooks/dex/useCreateWithdrawParams.ts +7 -20
  102. package/src/hooks/dex/useDecreaseLiquidity.ts +40 -66
  103. package/src/hooks/dex/useDexAllowance.ts +29 -75
  104. package/src/hooks/dex/useDexApprove.ts +32 -43
  105. package/src/hooks/dex/useDexDeposit.ts +42 -49
  106. package/src/hooks/dex/useDexWithdraw.ts +32 -43
  107. package/src/hooks/dex/useLiquidityAmounts.ts +13 -82
  108. package/src/hooks/dex/usePoolBalances.ts +50 -72
  109. package/src/hooks/dex/usePoolData.ts +17 -43
  110. package/src/hooks/dex/usePools.ts +11 -38
  111. package/src/hooks/dex/usePositionInfo.ts +27 -62
  112. package/src/hooks/dex/useSupplyLiquidity.ts +80 -75
  113. package/src/hooks/index.ts +12 -10
  114. package/src/hooks/migrate/index.ts +13 -4
  115. package/src/hooks/migrate/useMigrateBaln.ts +42 -0
  116. package/src/hooks/migrate/useMigrateIcxToSoda.ts +44 -0
  117. package/src/hooks/migrate/useMigratebnUSD.ts +47 -0
  118. package/src/hooks/migrate/useMigrationAllowance.ts +76 -0
  119. package/src/hooks/migrate/useMigrationApprove.ts +66 -0
  120. package/src/hooks/migrate/useRevertMigrateSodaToIcx.ts +39 -0
  121. package/src/hooks/mm/index.ts +14 -12
  122. package/src/hooks/mm/useAToken.ts +25 -41
  123. package/src/hooks/mm/useATokensBalances.ts +29 -60
  124. package/src/hooks/mm/useBorrow.ts +38 -56
  125. package/src/hooks/mm/useMMAllowance.ts +37 -73
  126. package/src/hooks/mm/useMMApprove.ts +36 -43
  127. package/src/hooks/mm/useRepay.ts +33 -53
  128. package/src/hooks/mm/useReservesData.ts +12 -38
  129. package/src/hooks/mm/useReservesHumanized.ts +12 -31
  130. package/src/hooks/mm/useReservesList.ts +11 -31
  131. package/src/hooks/mm/useReservesUsdFormat.ts +15 -35
  132. package/src/hooks/mm/useSupply.ts +45 -51
  133. package/src/hooks/mm/useUserFormattedSummary.ts +32 -84
  134. package/src/hooks/mm/useUserReservesData.ts +27 -77
  135. package/src/hooks/mm/useWithdraw.ts +38 -54
  136. package/src/hooks/partner/index.ts +6 -0
  137. package/src/hooks/partner/useApproveToken.ts +42 -0
  138. package/src/hooks/partner/useFeeClaimSwap.ts +38 -0
  139. package/src/hooks/partner/useFetchAssetsBalances.ts +37 -0
  140. package/src/hooks/partner/useGetAutoSwapPreferences.ts +37 -0
  141. package/src/hooks/partner/useIsTokenApproved.ts +39 -0
  142. package/src/hooks/partner/useSetSwapPreference.ts +50 -0
  143. package/src/hooks/provider/index.ts +1 -2
  144. package/src/hooks/provider/useHubProvider.ts +1 -1
  145. package/src/hooks/recovery/index.ts +2 -0
  146. package/src/hooks/recovery/useHubAssetBalances.ts +43 -0
  147. package/src/hooks/recovery/useWithdrawHubAsset.ts +48 -0
  148. package/src/hooks/shared/index.ts +10 -6
  149. package/src/hooks/shared/types.ts +77 -0
  150. package/src/hooks/shared/unwrapResult.ts +19 -0
  151. package/src/hooks/shared/useDeriveUserWalletAddress.ts +22 -40
  152. package/src/hooks/shared/useEstimateGas.ts +18 -15
  153. package/src/hooks/shared/useGetUserHubWalletAddress.ts +25 -26
  154. package/src/hooks/shared/useRequestTrustline.ts +28 -61
  155. package/src/hooks/shared/useSafeMutation.test.ts +43 -0
  156. package/src/hooks/shared/useSafeMutation.ts +68 -0
  157. package/src/hooks/shared/useSodaxContext.ts +1 -1
  158. package/src/hooks/shared/useStellarTrustlineCheck.ts +30 -64
  159. package/src/hooks/shared/useXBalances.test.ts +113 -0
  160. package/src/hooks/shared/useXBalances.ts +61 -0
  161. package/src/hooks/staking/index.ts +18 -18
  162. package/src/hooks/staking/useCancelUnstake.ts +30 -41
  163. package/src/hooks/staking/useClaim.ts +27 -36
  164. package/src/hooks/staking/useConvertedAssets.ts +24 -34
  165. package/src/hooks/staking/useInstantUnstake.ts +33 -40
  166. package/src/hooks/staking/useInstantUnstakeAllowance.ts +37 -45
  167. package/src/hooks/staking/useInstantUnstakeApprove.ts +42 -42
  168. package/src/hooks/staking/useInstantUnstakeRatio.ts +24 -41
  169. package/src/hooks/staking/useStake.ts +32 -37
  170. package/src/hooks/staking/useStakeAllowance.ts +30 -43
  171. package/src/hooks/staking/useStakeApprove.ts +40 -40
  172. package/src/hooks/staking/useStakeRatio.ts +24 -40
  173. package/src/hooks/staking/useStakingConfig.ts +14 -27
  174. package/src/hooks/staking/useStakingInfo.ts +30 -38
  175. package/src/hooks/staking/useUnstake.ts +29 -43
  176. package/src/hooks/staking/useUnstakeAllowance.ts +37 -44
  177. package/src/hooks/staking/useUnstakeApprove.ts +40 -43
  178. package/src/hooks/staking/useUnstakingInfo.ts +29 -41
  179. package/src/hooks/staking/useUnstakingInfoWithPenalty.ts +31 -47
  180. package/src/hooks/swap/index.ts +8 -8
  181. package/src/hooks/swap/useCancelLimitOrder.ts +24 -41
  182. package/src/hooks/swap/useCancelSwap.ts +24 -33
  183. package/src/hooks/swap/useCreateLimitOrder.ts +29 -62
  184. package/src/hooks/swap/useQuote.ts +17 -43
  185. package/src/hooks/swap/useStatus.ts +22 -29
  186. package/src/hooks/swap/useSwap.ts +31 -49
  187. package/src/hooks/swap/useSwapAllowance.ts +38 -35
  188. package/src/hooks/swap/useSwapApprove.ts +48 -57
  189. package/src/index.ts +5 -3
  190. package/src/providers/SodaxProvider.tsx +17 -11
  191. package/src/providers/createSodaxQueryClient.ts +96 -0
  192. package/src/providers/index.ts +2 -1
  193. package/src/utils/dex-utils.ts +27 -5
  194. package/src/utils/index.ts +1 -1
  195. package/dist/index.d.mts +0 -2581
  196. package/dist/index.js +0 -2574
  197. package/dist/index.js.map +0 -1
  198. package/src/hooks/migrate/types.ts +0 -15
  199. package/src/hooks/migrate/useMigrate.tsx +0 -110
  200. package/src/hooks/migrate/useMigrationAllowance.tsx +0 -79
  201. package/src/hooks/migrate/useMigrationApprove.tsx +0 -129
  202. package/src/hooks/provider/useSpokeProvider.ts +0 -172
@@ -1,52 +1,41 @@
1
1
  // packages/dapp-kit/src/hooks/staking/useCancelUnstake.ts
2
- import { useMutation, useQueryClient, type UseMutationResult } from '@tanstack/react-query';
3
- import { useSodaxContext } from '../shared/useSodaxContext';
4
- import type { CancelUnstakeParams, SpokeProvider, SpokeTxHash, HubTxHash } from '@sodax/sdk';
2
+ import type { CancelUnstakeAction, 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';
8
+
9
+ export type UseCancelUnstakeVars<K extends SpokeChainKey = SpokeChainKey> = Omit<CancelUnstakeAction<K, false>, 'raw'>;
5
10
 
6
11
  /**
7
- * Hook for executing cancel unstake transactions to cancel pending unstake requests.
8
- * Uses React Query's useMutation for better state management and caching.
9
- *
10
- * @param {SpokeProvider | undefined} spokeProvider - The spoke provider to use for the cancel unstake
11
- * @returns {UseMutationResult<[SpokeTxHash, HubTxHash], Error, Omit<CancelUnstakeParams, 'action'>>} Mutation result object containing mutation function and state
12
- *
13
- * @example
14
- * ```typescript
15
- * const { mutateAsync: cancelUnstake, isPending } = useCancelUnstake(spokeProvider);
16
- *
17
- * const handleCancelUnstake = async () => {
18
- * const result = await cancelUnstake({
19
- * requestId: 1n
20
- * });
12
+ * React hook for cancelling a pending unstake request.
21
13
  *
22
- * console.log('Cancel unstake successful:', result);
23
- * };
24
- * ```
14
+ * Throws on SDK failure so React Query's native error model engages (`isError`, `error`,
15
+ * `onError`, `retry`). Returns the unwrapped `TxHashPair` on success.
25
16
  */
26
- export function useCancelUnstake(
27
- spokeProvider: SpokeProvider | undefined,
28
- ): UseMutationResult<[SpokeTxHash, HubTxHash], Error, Omit<CancelUnstakeParams, 'action'>> {
17
+ export function useCancelUnstake<K extends SpokeChainKey = SpokeChainKey>({
18
+ mutationOptions,
19
+ }: MutationHookParams<TxHashPair, UseCancelUnstakeVars<K>> = {}): SafeUseMutationResult<
20
+ TxHashPair,
21
+ Error,
22
+ UseCancelUnstakeVars<K>
23
+ > {
29
24
  const { sodax } = useSodaxContext();
30
25
  const queryClient = useQueryClient();
31
26
 
32
- return useMutation({
33
- mutationFn: async (params: Omit<CancelUnstakeParams, 'action'>) => {
34
- if (!spokeProvider) {
35
- throw new Error('Spoke provider not available');
36
- }
37
-
38
- const result = await sodax.staking.cancelUnstake({ ...params, action: 'cancelUnstake' }, spokeProvider);
39
- if (!result.ok) {
40
- throw new Error(`Cancel unstake failed: ${result.error.code}`);
41
- }
42
-
43
- return result.value;
44
- },
45
- onSuccess: () => {
46
- // Invalidate relevant queries to refresh data
47
- queryClient.invalidateQueries({ queryKey: ['stakingInfo'] });
48
- queryClient.invalidateQueries({ queryKey: ['unstakingInfo'] });
49
- queryClient.invalidateQueries({ queryKey: ['unstakingInfoWithPenalty'] });
27
+ return useSafeMutation<TxHashPair, Error, UseCancelUnstakeVars<K>>({
28
+ mutationKey: ['staking', 'cancelUnstake'],
29
+ ...mutationOptions,
30
+ mutationFn: async vars => unwrapResult(await sodax.staking.cancelUnstake({ ...vars, raw: false })),
31
+ onSuccess: async (data, vars, ctx) => {
32
+ const { params } = vars;
33
+ queryClient.invalidateQueries({ queryKey: ['staking', 'unstakingInfo', params.srcChainKey, params.srcAddress] });
34
+ queryClient.invalidateQueries({
35
+ queryKey: ['staking', 'unstakingInfoWithPenalty', params.srcChainKey, params.srcAddress],
36
+ });
37
+ queryClient.invalidateQueries({ queryKey: ['staking', 'info', params.srcChainKey, params.srcAddress] });
38
+ await mutationOptions?.onSuccess?.(data, vars, ctx);
50
39
  },
51
40
  });
52
41
  }
@@ -1,46 +1,37 @@
1
1
  // packages/dapp-kit/src/hooks/staking/useClaim.ts
2
- import { useSodaxContext } from '../shared/useSodaxContext';
3
- import type { ClaimParams, SpokeTxHash, HubTxHash, SpokeProvider } from '@sodax/sdk';
4
- import { useMutation, type UseMutationResult } from '@tanstack/react-query';
2
+ import type { ClaimAction, 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';
8
+
9
+ export type UseClaimVars<K extends SpokeChainKey = SpokeChainKey> = Omit<ClaimAction<K, false>, 'raw'>;
5
10
 
6
11
  /**
7
- * Hook for executing claim transactions to claim unstaked SODA tokens after the unstaking period.
8
- * Uses React Query's useMutation for better state management and caching.
9
- *
10
- * @param {SpokeProvider | undefined} spokeProvider - The spoke provider to use for the claim
11
- * @returns {UseMutationResult<[SpokeTxHash, HubTxHash], Error, Omit<ClaimParams, 'action'>>} Mutation result object containing mutation function and state
12
- *
13
- * @example
14
- * ```typescript
15
- * const { mutateAsync: claim, isPending } = useClaim(spokeProvider);
16
- *
17
- * const handleClaim = async () => {
18
- * const result = await claim({
19
- * requestId: 1n
20
- * });
12
+ * React hook for claiming an unstaked SODA request that has reached the end of its waiting period.
21
13
  *
22
- * console.log('Claim successful:', result);
23
- * };
24
- * ```
14
+ * Throws on SDK failure so React Query's native error model engages (`isError`, `error`,
15
+ * `onError`, `retry`). Returns the unwrapped `TxHashPair` on success.
25
16
  */
26
- export function useClaim(
27
- spokeProvider: SpokeProvider | undefined,
28
- ): UseMutationResult<[SpokeTxHash, HubTxHash], Error, Omit<ClaimParams, 'action'>> {
17
+ export function useClaim<K extends SpokeChainKey = SpokeChainKey>({
18
+ mutationOptions,
19
+ }: MutationHookParams<TxHashPair, UseClaimVars<K>> = {}): SafeUseMutationResult<TxHashPair, Error, UseClaimVars<K>> {
29
20
  const { sodax } = useSodaxContext();
21
+ const queryClient = useQueryClient();
30
22
 
31
- return useMutation<[SpokeTxHash, HubTxHash], Error, Omit<ClaimParams, 'action'>>({
32
- mutationFn: async (params: Omit<ClaimParams, 'action'>) => {
33
- if (!spokeProvider) {
34
- throw new Error('Spoke provider not found');
35
- }
36
-
37
- const result = await sodax.staking.claim({ ...params, action: 'claim' }, spokeProvider);
38
-
39
- if (!result.ok) {
40
- throw new Error(`Claim failed: ${result.error.code}`);
41
- }
42
-
43
- return result.value;
23
+ return useSafeMutation<TxHashPair, Error, UseClaimVars<K>>({
24
+ mutationKey: ['staking', 'claim'],
25
+ ...mutationOptions,
26
+ mutationFn: async vars => unwrapResult(await sodax.staking.claim({ ...vars, raw: false })),
27
+ onSuccess: async (data, vars, ctx) => {
28
+ const { params } = vars;
29
+ queryClient.invalidateQueries({ queryKey: ['staking', 'unstakingInfo', params.srcChainKey, params.srcAddress] });
30
+ queryClient.invalidateQueries({
31
+ queryKey: ['staking', 'unstakingInfoWithPenalty', params.srcChainKey, params.srcAddress],
32
+ });
33
+ queryClient.invalidateQueries({ queryKey: ['shared', 'xBalances', params.srcChainKey] });
34
+ await mutationOptions?.onSuccess?.(data, vars, ctx);
44
35
  },
45
36
  });
46
37
  }
@@ -1,47 +1,37 @@
1
- // packages/dapp-kit/src/hooks/staking/useConvertedAssets.ts
2
- import { useSodaxContext } from '../shared/useSodaxContext';
3
1
  import { useQuery, type UseQueryResult } from '@tanstack/react-query';
2
+ import { useSodaxContext } from '../shared/useSodaxContext.js';
3
+ import type { ReadHookParams } from '../shared/types.js';
4
+
5
+ export type UseConvertedAssetsParams = ReadHookParams<
6
+ bigint,
7
+ {
8
+ amount: bigint | undefined;
9
+ }
10
+ >;
4
11
 
5
12
  /**
6
- * Hook for fetching converted assets amount for xSODA shares.
7
- * Uses React Query for efficient caching and state management.
8
- *
9
- * @param {bigint | undefined} amount - The amount of xSODA shares to convert
10
- * @param {number} refetchInterval - The interval in milliseconds to refetch data (default: 10000)
11
- * @returns {UseQueryResult<bigint, Error>} Query result object containing converted assets amount and state
12
- *
13
- * @example
14
- * ```typescript
15
- * const { data: convertedAssets, isLoading, error } = useConvertedAssets(1000000000000000000n); // 1 xSODA
16
- *
17
- * if (isLoading) return <div>Loading converted assets...</div>;
18
- * if (convertedAssets) {
19
- * console.log('Converted assets:', convertedAssets);
20
- * }
21
- * ```
13
+ * React hook to convert an xSODA share amount to its underlying SODA value via the vault's
14
+ * exchange rate. Hub-only read. Throws on `!ok`.
22
15
  */
23
- export function useConvertedAssets(amount: bigint | undefined, refetchInterval = 10000): UseQueryResult<bigint, Error> {
16
+ export function useConvertedAssets({
17
+ params,
18
+ queryOptions,
19
+ }: UseConvertedAssetsParams = {}): UseQueryResult<bigint, Error> {
24
20
  const { sodax } = useSodaxContext();
21
+ const amount = params?.amount;
25
22
 
26
- // console.log('useConvertedAssets hook called with:', { amount: amount?.toString(), sodax: !!sodax });
27
-
28
- return useQuery({
29
- queryKey: ['soda', 'convertedAssets', amount?.toString()],
23
+ return useQuery<bigint, Error>({
24
+ queryKey: ['staking', 'convertedAssets', amount?.toString()],
30
25
  queryFn: async () => {
31
- // console.log('useConvertedAssets queryFn called with amount:', amount?.toString());
32
- if (!amount || amount <= 0n) {
33
- throw new Error('Amount must be greater than 0');
26
+ if (amount === undefined) {
27
+ throw new Error('amount is required');
34
28
  }
35
-
36
29
  const result = await sodax.staking.getConvertedAssets(amount);
37
-
38
- if (!result.ok) {
39
- throw new Error(`Failed to fetch converted assets: ${result.error.code}`);
40
- }
41
-
30
+ if (!result.ok) throw result.error;
42
31
  return result.value;
43
32
  },
44
- enabled: !!amount && amount > 0n && !!sodax?.staking,
45
- refetchInterval,
33
+ enabled: amount !== undefined,
34
+ refetchInterval: 10_000,
35
+ ...queryOptions,
46
36
  });
47
37
  }
@@ -1,50 +1,43 @@
1
1
  // packages/dapp-kit/src/hooks/staking/useInstantUnstake.ts
2
- import { useSodaxContext } from '../shared/useSodaxContext';
3
- import { useMutation, type UseMutationResult } from '@tanstack/react-query';
4
- import type { SpokeProvider, InstantUnstakeParams } from '@sodax/sdk';
2
+ import type { InstantUnstakeAction, 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';
8
+
9
+ export type UseInstantUnstakeVars<K extends SpokeChainKey = SpokeChainKey> = Omit<
10
+ InstantUnstakeAction<K, false>,
11
+ 'raw'
12
+ >;
5
13
 
6
14
  /**
7
- * Hook for executing instant unstake operations.
8
- * Uses React Query for efficient state management and error handling.
9
- *
10
- * @param {SpokeProvider | undefined} spokeProvider - The spoke provider for the transaction
11
- * @returns {UseMutationResult<[string, string], Error, Omit<InstantUnstakeParams, 'action'>>} Mutation result object containing instant unstake state and methods
15
+ * React hook for instant-unstaking SODA (bypassing the waiting period at a slippage cost).
12
16
  *
13
- * @example
14
- * ```typescript
15
- * const { mutateAsync: instantUnstake, isPending } = useInstantUnstake(spokeProvider);
16
- *
17
- * const handleInstantUnstake = async () => {
18
- * const result = await instantUnstake({
19
- * amount: 1000000000000000000n,
20
- * minAmount: 950000000000000000n,
21
- * account: '0x...'
22
- * });
23
- * console.log('Instant unstake successful:', result);
24
- * };
25
- * ```
17
+ * Throws on SDK failure so React Query's native error model engages (`isError`, `error`,
18
+ * `onError`, `retry`). Returns the unwrapped `TxHashPair` on success.
26
19
  */
27
- export function useInstantUnstake(
28
- spokeProvider: SpokeProvider | undefined,
29
- ): UseMutationResult<[string, string], Error, Omit<InstantUnstakeParams, 'action'>> {
20
+ export function useInstantUnstake<K extends SpokeChainKey = SpokeChainKey>({
21
+ mutationOptions,
22
+ }: MutationHookParams<TxHashPair, UseInstantUnstakeVars<K>> = {}): SafeUseMutationResult<
23
+ TxHashPair,
24
+ Error,
25
+ UseInstantUnstakeVars<K>
26
+ > {
30
27
  const { sodax } = useSodaxContext();
28
+ const queryClient = useQueryClient();
31
29
 
32
- return useMutation({
33
- mutationFn: async (params: Omit<InstantUnstakeParams, 'action'>) => {
34
- if (!spokeProvider) {
35
- throw new Error('spokeProvider is not found');
36
- }
37
-
38
- const result = await sodax.staking.instantUnstake({ ...params, action: 'instantUnstake' }, spokeProvider);
39
-
40
- if (!result.ok) {
41
- throw new Error(`Instant unstake failed: ${result.error.code}`);
42
- }
43
-
44
- return result.value;
45
- },
46
- onError: error => {
47
- console.error('Instant unstake error:', error);
30
+ return useSafeMutation<TxHashPair, Error, UseInstantUnstakeVars<K>>({
31
+ mutationKey: ['staking', 'instantUnstake'],
32
+ ...mutationOptions,
33
+ mutationFn: async vars => unwrapResult(await sodax.staking.instantUnstake({ ...vars, raw: false })),
34
+ onSuccess: async (data, vars, ctx) => {
35
+ const { params } = vars;
36
+ queryClient.invalidateQueries({ queryKey: ['staking', 'info', params.srcChainKey, params.srcAddress] });
37
+ queryClient.invalidateQueries({ queryKey: ['staking', 'instantUnstakeRatio'] });
38
+ queryClient.invalidateQueries({ queryKey: ['staking', 'allowance', params.srcChainKey, 'instantUnstake'] });
39
+ queryClient.invalidateQueries({ queryKey: ['shared', 'xBalances', params.srcChainKey] });
40
+ await mutationOptions?.onSuccess?.(data, vars, ctx);
48
41
  },
49
42
  });
50
43
  }
@@ -1,59 +1,51 @@
1
- // packages/dapp-kit/src/hooks/staking/useStakeAllowance.ts
2
- import { useSodaxContext } from '../shared/useSodaxContext';
3
- import type { SpokeProvider, InstantUnstakeParams } from '@sodax/sdk';
1
+ import type { InstantUnstakeParams } from '@sodax/sdk';
2
+ import type { SpokeChainKey } from '@sodax/sdk';
4
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 UseInstantUnstakeAllowanceParams<K extends SpokeChainKey = SpokeChainKey> = ReadHookParams<
8
+ boolean,
9
+ {
10
+ payload: Omit<InstantUnstakeParams<K>, 'action'> | undefined;
11
+ }
12
+ >;
5
13
 
6
14
  /**
7
- * Hook for checking xSODA token allowance for instant unstaking operations.
8
- * Uses React Query for efficient caching and state management.
9
- *
10
- * @param {Omit<InstantUnstakeParams, 'action'> | undefined} params - The instant unstaking parameters. If undefined, the query will be disabled.
11
- * @param {SpokeProvider | undefined} spokeProvider - The spoke provider to use for the allowance check
12
- * @returns {UseQueryResult<boolean, Error>} Query result object containing allowance data and state
13
- *
14
- * @example
15
- * ```typescript
16
- * const { data: hasAllowed, isLoading } = useInstantUnstakeAllowance(
17
- * {
18
- * amount: 1000000000000000000n, // 1 xSODA
19
- * minAmount: 950000000000000000n, // 0.95 SODA
20
- * account: '0x...'
21
- * },
22
- * spokeProvider
23
- * );
24
- *
25
- * if (isLoading) return <div>Checking allowance...</div>;
26
- * if (hasAllowed) {
27
- * console.log('Sufficient allowance for instant unstaking');
28
- * }
29
- * ```
15
+ * React hook to check whether the user has approved sufficient xSODA spending for the
16
+ * instant-unstake action. Read-only calls `staking.isAllowanceValid` with `raw: true` so no
17
+ * `walletProvider` is required.
30
18
  */
31
- export function useInstantUnstakeAllowance(
32
- params: Omit<InstantUnstakeParams, 'action'> | undefined,
33
- spokeProvider: SpokeProvider | undefined,
34
- ): UseQueryResult<boolean, Error> {
19
+ export function useInstantUnstakeAllowance<K extends SpokeChainKey = SpokeChainKey>({
20
+ params,
21
+ queryOptions,
22
+ }: UseInstantUnstakeAllowanceParams<K> = {}): UseQueryResult<boolean, Error> {
35
23
  const { sodax } = useSodaxContext();
24
+ const payload = params?.payload;
36
25
 
37
- return useQuery({
38
- queryKey: ['soda', 'instantUnstakeAllowance', params, spokeProvider?.chainConfig.chain.id],
26
+ return useQuery<boolean, Error>({
27
+ queryKey: [
28
+ 'staking',
29
+ 'allowance',
30
+ payload?.srcChainKey,
31
+ 'instantUnstake',
32
+ payload?.srcAddress,
33
+ payload?.amount?.toString(),
34
+ ],
39
35
  queryFn: async () => {
40
- if (!params || !spokeProvider) {
41
- return false;
36
+ if (!payload) {
37
+ throw new Error('Params are required');
42
38
  }
43
-
44
39
  const result = await sodax.staking.isAllowanceValid({
45
- params: { ...params, action: 'instantUnstake' },
46
- spokeProvider,
40
+ params: { ...payload, action: 'instantUnstake' },
41
+ raw: true,
47
42
  });
48
-
49
- if (!result.ok) {
50
- console.error(`Unstake allowance check failed: ${result.error.code}, error: ${result.error.error}`);
51
- throw new Error(`Unstake allowance check failed: ${result.error.code}`);
52
- }
53
-
43
+ if (!result.ok) throw result.error;
54
44
  return result.value;
55
45
  },
56
- enabled: !!params && !!spokeProvider,
57
- refetchInterval: 5000, // Refetch every 5 seconds
46
+ enabled: !!payload,
47
+ refetchInterval: 5_000,
48
+ gcTime: 0,
49
+ ...queryOptions,
58
50
  });
59
51
  }
@@ -1,52 +1,52 @@
1
- // packages/dapp-kit/src/hooks/staking/useStakeApprove.ts
2
- import { useSodaxContext } from '../shared/useSodaxContext';
3
- import type { InstantUnstakeParams, TxReturnType, SpokeProvider } from '@sodax/sdk';
4
- import { useMutation, type UseMutationResult } from '@tanstack/react-query';
1
+ // packages/dapp-kit/src/hooks/staking/useInstantUnstakeApprove.ts
2
+ import type { GetWalletProviderType, InstantUnstakeParams, 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';
5
8
 
6
9
  /**
7
- * Hook for approving xSODA token spending for instant unstaking operations.
8
- * Uses React Query's useMutation for better state management and caching.
9
- *
10
- * @param {SpokeProvider | undefined} spokeProvider - The spoke provider to use for the approval
11
- * @returns {UseMutationResult<TxReturnType<SpokeProvider, false>, Error, Omit<InstantUnstakeParams, 'action'>>} Mutation result object containing mutation function and state
12
- *
13
- * @example
14
- * ```typescript
15
- * const { mutateAsync: approve, isPending } = useInstantUnstakeApprove(spokeProvider);
16
- *
17
- * const handleApprove = async () => {
18
- * const result = await approve({
19
- * amount: 1000000000000000000n, // 1 xSODA
20
- * minAmount: 950000000000000000n, // 0.95 SODA
21
- * account: '0x...'
22
- * });
10
+ * Mutation variables for {@link useInstantUnstakeApprove}. The `action` literal is injected by
11
+ * the hook.
12
+ */
13
+ export type UseInstantUnstakeApproveVars<K extends SpokeChainKey = SpokeChainKey> = {
14
+ params: Omit<InstantUnstakeParams<K>, 'action'>;
15
+ walletProvider: GetWalletProviderType<K>;
16
+ };
17
+
18
+ /**
19
+ * React hook for approving xSODA spending on the instant-unstake action.
23
20
  *
24
- * console.log('Approval successful:', result);
25
- * };
26
- * ```
21
+ * Throws on SDK failure so React Query's native error model engages (`isError`, `error`,
22
+ * `onError`, `retry`). Returns the unwrapped tx return value on success.
27
23
  */
28
- export function useInstantUnstakeApprove(
29
- spokeProvider: SpokeProvider | undefined,
30
- ): UseMutationResult<TxReturnType<SpokeProvider, false>, Error, Omit<InstantUnstakeParams, 'action'>> {
24
+ export function useInstantUnstakeApprove<K extends SpokeChainKey = SpokeChainKey>({
25
+ mutationOptions,
26
+ }: MutationHookParams<TxReturnType<K, false>, UseInstantUnstakeApproveVars<K>> = {}): SafeUseMutationResult<
27
+ TxReturnType<K, false>,
28
+ Error,
29
+ UseInstantUnstakeApproveVars<K>
30
+ > {
31
31
  const { sodax } = useSodaxContext();
32
+ const queryClient = useQueryClient();
32
33
 
33
- return useMutation<TxReturnType<SpokeProvider, false>, Error, Omit<InstantUnstakeParams, 'action'>>({
34
- mutationFn: async (params: Omit<InstantUnstakeParams, 'action'>) => {
35
- console.log('useInstantUnstakeApprove called with params:', params);
36
- if (!spokeProvider) {
37
- throw new Error('Spoke provider not found');
38
- }
39
-
40
- const result = await sodax.staking.approve({
41
- params: { ...params, action: 'instantUnstake' },
42
- spokeProvider,
34
+ return useSafeMutation<TxReturnType<K, false>, Error, UseInstantUnstakeApproveVars<K>>({
35
+ mutationKey: ['staking', 'approve', 'instantUnstake'],
36
+ ...mutationOptions,
37
+ mutationFn: async ({ params, walletProvider }) =>
38
+ unwrapResult(
39
+ await sodax.staking.approve({
40
+ params: { ...params, action: 'instantUnstake' },
41
+ raw: false,
42
+ walletProvider,
43
+ }),
44
+ ),
45
+ onSuccess: async (data, vars, ctx) => {
46
+ queryClient.invalidateQueries({
47
+ queryKey: ['staking', 'allowance', vars.params.srcChainKey, 'instantUnstake'],
43
48
  });
44
-
45
- if (!result.ok) {
46
- throw new Error(`Instant unstake approval failed: ${result.error.code}`);
47
- }
48
-
49
- return result.value;
49
+ await mutationOptions?.onSuccess?.(data, vars, ctx);
50
50
  },
51
51
  });
52
52
  }
@@ -1,54 +1,37 @@
1
- // packages/dapp-kit/src/hooks/staking/useInstantUnstakeRatio.ts
2
- import { useSodaxContext } from '../shared/useSodaxContext';
3
1
  import { useQuery, type UseQueryResult } from '@tanstack/react-query';
2
+ import { useSodaxContext } from '../shared/useSodaxContext.js';
3
+ import type { ReadHookParams } from '../shared/types.js';
4
+
5
+ export type UseInstantUnstakeRatioParams = ReadHookParams<
6
+ bigint,
7
+ {
8
+ amount: bigint | undefined;
9
+ }
10
+ >;
4
11
 
5
12
  /**
6
- * Hook for fetching instant unstake ratio estimates.
7
- * Uses React Query for efficient caching and state management.
8
- *
9
- * @param {bigint | undefined} amount - The amount of xSoda to estimate instant unstake for
10
- * @param {number} refetchInterval - The interval in milliseconds to refetch data (default: 10000)
11
- * @returns {UseQueryResult<bigint, Error>} Query result object containing instant unstake ratio and state
12
- *
13
- * @example
14
- * ```typescript
15
- * const { data: instantUnstakeRatio, isLoading, error } = useInstantUnstakeRatio(1000000000000000000n); // 1 xSoda
16
- *
17
- * if (isLoading) return <div>Loading instant unstake ratio...</div>;
18
- * if (instantUnstakeRatio) {
19
- * console.log('Instant unstake ratio:', instantUnstakeRatio);
20
- * }
21
- * ```
13
+ * React hook to estimate the SODA amount received from instant-unstaking a given xSODA amount
14
+ * (after slippage). Hub-only read. Throws on `!ok`.
22
15
  */
23
- export function useInstantUnstakeRatio(
24
- amount: bigint | undefined,
25
- refetchInterval = 10000,
26
- ): UseQueryResult<bigint, Error> {
16
+ export function useInstantUnstakeRatio({
17
+ params,
18
+ queryOptions,
19
+ }: UseInstantUnstakeRatioParams = {}): UseQueryResult<bigint, Error> {
27
20
  const { sodax } = useSodaxContext();
21
+ const amount = params?.amount;
28
22
 
29
- console.log('useInstantUnstakeRatio hook called with:', { amount: amount?.toString(), sodax: !!sodax });
30
-
31
- return useQuery({
32
- queryKey: ['soda', 'instantUnstakeRatio', amount?.toString()],
23
+ return useQuery<bigint, Error>({
24
+ queryKey: ['staking', 'instantUnstakeRatio', amount?.toString()],
33
25
  queryFn: async () => {
34
- console.log('useInstantUnstakeRatio queryFn called with amount:', amount?.toString());
35
- if (!amount || amount <= 0n) {
36
- throw new Error('Amount must be greater than 0');
37
- }
38
-
39
- if (!sodax?.staking) {
40
- throw new Error('Staking service not available');
26
+ if (amount === undefined) {
27
+ throw new Error('amount is required');
41
28
  }
42
-
43
29
  const result = await sodax.staking.getInstantUnstakeRatio(amount);
44
-
45
- if (!result.ok) {
46
- throw new Error(`Failed to fetch instant unstake ratio: ${result.error.code}`);
47
- }
48
-
30
+ if (!result.ok) throw result.error;
49
31
  return result.value;
50
32
  },
51
- enabled: !!amount && amount > 0n && !!sodax?.staking,
52
- refetchInterval,
33
+ enabled: amount !== undefined,
34
+ refetchInterval: 10_000,
35
+ ...queryOptions,
53
36
  });
54
37
  }