@sodax/dapp-kit 1.5.6-beta → 2.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +194 -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 +1594 -1532
  61. package/dist/index.mjs.map +1 -1
  62. package/package.json +20 -10
  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 +27 -84
  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 -2562
  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
package/dist/index.js DELETED
@@ -1,2562 +0,0 @@
1
- 'use strict';
2
-
3
- var React = require('react');
4
- var sdk = require('@sodax/sdk');
5
- var reactQuery = require('@tanstack/react-query');
6
- var viem = require('viem');
7
- var types = require('@sodax/types');
8
-
9
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
-
11
- var React__default = /*#__PURE__*/_interopDefault(React);
12
-
13
- // src/contexts/index.ts
14
- var SodaxContext = React.createContext(null);
15
- var useSodaxContext = () => {
16
- const context = React.useContext(SodaxContext);
17
- if (!context) {
18
- throw new Error("useSodaxContext must be used within a SodaxProvider");
19
- }
20
- return context;
21
- };
22
- function useEstimateGas(spokeProvider) {
23
- return reactQuery.useMutation({
24
- mutationFn: async (rawTx) => {
25
- if (!spokeProvider) {
26
- throw new Error("spokeProvider is not found");
27
- }
28
- const response = await sdk.SpokeService.estimateGas(rawTx, spokeProvider);
29
- return response;
30
- }
31
- });
32
- }
33
- function useDeriveUserWalletAddress(spokeChainId, spokeAddress) {
34
- const { sodax } = useSodaxContext();
35
- return reactQuery.useQuery({
36
- queryKey: ["deriveUserWalletAddress", spokeChainId, spokeAddress],
37
- queryFn: async () => {
38
- if (!spokeChainId || !spokeAddress) {
39
- throw new Error("Spoke chain id and address are required");
40
- }
41
- spokeChainId = typeof spokeChainId === "object" ? spokeChainId.chainConfig.chain.id : spokeChainId;
42
- return await sdk.deriveUserWalletAddress(sodax.hubProvider, spokeChainId, spokeAddress);
43
- },
44
- enabled: !!spokeChainId && !!spokeAddress,
45
- refetchInterval: false
46
- // This is a deterministic operation, no need to refetch
47
- });
48
- }
49
- function useStellarTrustlineCheck(token, amount, spokeProvider, chainId) {
50
- return reactQuery.useQuery({
51
- queryKey: ["stellar-trustline-check", token],
52
- queryFn: async () => {
53
- if (chainId !== sdk.STELLAR_MAINNET_CHAIN_ID) {
54
- return true;
55
- }
56
- if (!spokeProvider || !token || !amount || !(spokeProvider instanceof sdk.StellarSpokeProvider)) {
57
- console.error(
58
- "Spoke provider, token or amount not found. Details: spokeProvider:",
59
- spokeProvider,
60
- "token:",
61
- token,
62
- "amount:",
63
- amount
64
- );
65
- return false;
66
- }
67
- const response = await sdk.StellarSpokeService.hasSufficientTrustline(token, amount, spokeProvider);
68
- return response;
69
- },
70
- enabled: !!spokeProvider && !!token && !!amount
71
- });
72
- }
73
- function useRequestTrustline(token) {
74
- const queryClient = reactQuery.useQueryClient();
75
- const [isLoading, setIsLoading] = React.useState(false);
76
- const [isRequested, setIsRequested] = React.useState(false);
77
- const [error, setError] = React.useState(null);
78
- const [data, setData] = React.useState(null);
79
- const requestTrustline = React.useCallback(
80
- async ({
81
- token: token2,
82
- amount,
83
- spokeProvider
84
- }) => {
85
- if (!spokeProvider || !token2 || !amount || !(spokeProvider instanceof sdk.StellarSpokeProvider)) {
86
- const error2 = new Error("Spoke provider, token or amount not found");
87
- setError(error2);
88
- throw error2;
89
- }
90
- setIsLoading(true);
91
- setError(null);
92
- try {
93
- const result = await sdk.StellarSpokeService.requestTrustline(token2, amount, spokeProvider);
94
- setData(result);
95
- setIsRequested(true);
96
- queryClient.invalidateQueries({ queryKey: ["stellar-trustline-check", token2] });
97
- return result;
98
- } catch (err) {
99
- const error2 = err instanceof Error ? err : new Error("Unknown error occurred");
100
- setError(error2);
101
- throw error2;
102
- } finally {
103
- setIsLoading(false);
104
- }
105
- },
106
- [queryClient]
107
- );
108
- return {
109
- requestTrustline,
110
- isLoading,
111
- isRequested,
112
- error,
113
- data
114
- };
115
- }
116
- function useGetUserHubWalletAddress(spokeChainId, spokeAddress) {
117
- const { sodax } = useSodaxContext();
118
- return reactQuery.useQuery({
119
- queryKey: ["getUserHubWalletAddress", spokeChainId, spokeAddress],
120
- queryFn: async () => {
121
- if (!spokeChainId || !spokeAddress) {
122
- throw new Error("Spoke chain id and address are required");
123
- }
124
- spokeChainId = typeof spokeChainId === "object" ? spokeChainId.chainConfig.chain.id : spokeChainId;
125
- return await sdk.HubService.getUserHubWalletAddress(spokeAddress, spokeChainId, sodax.hubProvider);
126
- },
127
- enabled: !!spokeChainId && !!spokeAddress,
128
- refetchInterval: false
129
- // This is a deterministic operation, no need to refetch
130
- });
131
- }
132
-
133
- // src/hooks/provider/useHubProvider.ts
134
- function useHubProvider() {
135
- const { sodax } = useSodaxContext();
136
- return sodax.hubProvider;
137
- }
138
- function useSpokeProvider(spokeChainId, walletProvider) {
139
- const { rpcConfig } = useSodaxContext();
140
- const xChainType = spokeChainId ? sdk.spokeChainConfig[spokeChainId]?.chain.type : void 0;
141
- const spokeProvider = React.useMemo(() => {
142
- if (!walletProvider) return void 0;
143
- if (!spokeChainId) return void 0;
144
- if (!xChainType) return void 0;
145
- if (!rpcConfig) return void 0;
146
- if (xChainType === "BITCOIN") {
147
- const bitcoinConfig = sdk.spokeChainConfig[spokeChainId];
148
- const btcRpcOverride = rpcConfig[spokeChainId];
149
- return new sdk.BitcoinSpokeProvider(
150
- walletProvider,
151
- bitcoinConfig,
152
- {
153
- url: btcRpcOverride?.radfiApiUrl || bitcoinConfig.radfiApiUrl,
154
- apiKey: bitcoinConfig.radfiApiKey,
155
- umsUrl: btcRpcOverride?.radfiUmsUrl || bitcoinConfig.radfiUmsUrl
156
- },
157
- "TRADING",
158
- btcRpcOverride?.rpcUrl || bitcoinConfig.rpcUrl
159
- );
160
- }
161
- if (xChainType === "EVM") {
162
- if (spokeChainId === sdk.SONIC_MAINNET_CHAIN_ID) {
163
- return new sdk.SonicSpokeProvider(
164
- walletProvider,
165
- sdk.spokeChainConfig[spokeChainId]
166
- );
167
- }
168
- const evmRpcUrl = rpcConfig[spokeChainId];
169
- return new sdk.EvmSpokeProvider(
170
- walletProvider,
171
- sdk.spokeChainConfig[spokeChainId],
172
- typeof evmRpcUrl === "string" ? evmRpcUrl : void 0
173
- );
174
- }
175
- if (xChainType === "SUI") {
176
- return new sdk.SuiSpokeProvider(
177
- sdk.spokeChainConfig[spokeChainId],
178
- walletProvider
179
- );
180
- }
181
- if (xChainType === "ICON") {
182
- return new sdk.IconSpokeProvider(
183
- walletProvider,
184
- sdk.spokeChainConfig[spokeChainId]
185
- );
186
- }
187
- if (xChainType === "INJECTIVE") {
188
- return new sdk.InjectiveSpokeProvider(
189
- sdk.spokeChainConfig[spokeChainId],
190
- walletProvider
191
- );
192
- }
193
- if (xChainType === "STELLAR") {
194
- const stellarConfig = sdk.spokeChainConfig[spokeChainId];
195
- return new sdk.StellarSpokeProvider(
196
- walletProvider,
197
- stellarConfig,
198
- rpcConfig.stellar ? rpcConfig.stellar : {
199
- horizonRpcUrl: stellarConfig.horizonRpcUrl,
200
- sorobanRpcUrl: stellarConfig.sorobanRpcUrl
201
- }
202
- );
203
- }
204
- if (xChainType === "SOLANA") {
205
- return new sdk.SolanaSpokeProvider(
206
- walletProvider,
207
- rpcConfig.solana ? {
208
- ...sdk.spokeChainConfig[spokeChainId],
209
- rpcUrl: rpcConfig.solana
210
- } : sdk.spokeChainConfig[spokeChainId]
211
- );
212
- }
213
- if (xChainType === "NEAR") {
214
- return new sdk.NearSpokeProvider(
215
- walletProvider,
216
- sdk.spokeChainConfig[spokeChainId]
217
- );
218
- }
219
- if (xChainType === "STACKS") {
220
- return new sdk.StacksSpokeProvider(
221
- rpcConfig[spokeChainId] ? {
222
- ...sdk.spokeChainConfig[spokeChainId],
223
- rpcUrl: rpcConfig[spokeChainId]
224
- } : sdk.spokeChainConfig[spokeChainId],
225
- walletProvider
226
- );
227
- }
228
- return void 0;
229
- }, [spokeChainId, xChainType, walletProvider, rpcConfig]);
230
- return spokeProvider;
231
- }
232
- var SESSION_KEY = (address) => `radfi_session_${address}`;
233
- function saveRadfiSession(address, session) {
234
- try {
235
- localStorage.setItem(SESSION_KEY(address), JSON.stringify(session));
236
- } catch {
237
- }
238
- }
239
- function loadRadfiSession(address) {
240
- try {
241
- const raw = localStorage.getItem(SESSION_KEY(address));
242
- return raw ? JSON.parse(raw) : null;
243
- } catch {
244
- return null;
245
- }
246
- }
247
- function clearRadfiSession(address) {
248
- try {
249
- localStorage.removeItem(SESSION_KEY(address));
250
- } catch {
251
- }
252
- }
253
- function useRadfiAuth(spokeProvider) {
254
- return reactQuery.useMutation({
255
- mutationFn: async () => {
256
- if (!spokeProvider) {
257
- throw new Error("Bitcoin spoke provider not found");
258
- }
259
- const walletAddress = await spokeProvider.walletProvider.getWalletAddress();
260
- const existingSession = loadRadfiSession(walletAddress);
261
- const cachedPublicKey = existingSession?.publicKey;
262
- try {
263
- const { accessToken, refreshToken, tradingAddress, publicKey } = await spokeProvider.authenticateWithWallet(cachedPublicKey);
264
- const session = {
265
- accessToken,
266
- refreshToken,
267
- tradingAddress,
268
- publicKey
269
- };
270
- saveRadfiSession(walletAddress, session);
271
- return { accessToken, refreshToken, tradingAddress };
272
- } catch (err) {
273
- const isAlreadyRegistered = err instanceof Error && (err.message.includes("duplicatedPubKey") || err.message.includes("4008"));
274
- if (isAlreadyRegistered && existingSession?.refreshToken) {
275
- try {
276
- const refreshed = await spokeProvider.radfi.refreshAccessToken(existingSession.refreshToken);
277
- const session = {
278
- ...existingSession,
279
- accessToken: refreshed.accessToken,
280
- refreshToken: refreshed.refreshToken
281
- };
282
- spokeProvider.setRadfiAccessToken(refreshed.accessToken, refreshed.refreshToken);
283
- saveRadfiSession(walletAddress, session);
284
- return { accessToken: refreshed.accessToken, refreshToken: refreshed.refreshToken, tradingAddress: existingSession.tradingAddress };
285
- } catch {
286
- clearRadfiSession(walletAddress);
287
- }
288
- throw new Error(
289
- "This wallet is already registered with Radfi from another session. Please clear your browser storage for this site and try again, or wait for the previous session to expire."
290
- );
291
- }
292
- throw err;
293
- }
294
- }
295
- });
296
- }
297
- var REFRESH_INTERVAL = 5 * 60 * 1e3;
298
- function useRadfiSession(spokeProvider) {
299
- const [walletAddress, setWalletAddress] = React.useState();
300
- const [isAuthed, setIsAuthed] = React.useState(false);
301
- const [tradingAddress, setTradingAddress] = React.useState();
302
- const isRefreshingRef = React.useRef(false);
303
- const silentRefresh = React.useCallback(async (address) => {
304
- if (!spokeProvider || isRefreshingRef.current) return;
305
- isRefreshingRef.current = true;
306
- try {
307
- const session = loadRadfiSession(address);
308
- if (!session?.refreshToken) {
309
- setIsAuthed(false);
310
- return;
311
- }
312
- const { accessToken, refreshToken } = await spokeProvider.radfi.refreshAccessToken(session.refreshToken);
313
- const updated = {
314
- ...session,
315
- accessToken,
316
- refreshToken
317
- };
318
- saveRadfiSession(address, updated);
319
- spokeProvider.setRadfiAccessToken(accessToken, refreshToken);
320
- setIsAuthed(true);
321
- setTradingAddress(updated.tradingAddress || void 0);
322
- } catch {
323
- clearRadfiSession(address);
324
- spokeProvider.setRadfiAccessToken("", "");
325
- setIsAuthed(false);
326
- setTradingAddress(void 0);
327
- } finally {
328
- isRefreshingRef.current = false;
329
- }
330
- }, [spokeProvider]);
331
- React.useEffect(() => {
332
- if (!spokeProvider) return;
333
- setIsAuthed(false);
334
- setTradingAddress(void 0);
335
- setWalletAddress(void 0);
336
- spokeProvider.walletProvider.getWalletAddress().then((addr) => {
337
- setWalletAddress(addr);
338
- const session = loadRadfiSession(addr);
339
- if (!session?.refreshToken) return;
340
- silentRefresh(addr);
341
- }).catch(() => {
342
- });
343
- }, [spokeProvider, silentRefresh]);
344
- React.useEffect(() => {
345
- if (!walletAddress || !spokeProvider) return;
346
- const id = setInterval(() => {
347
- silentRefresh(walletAddress);
348
- }, REFRESH_INTERVAL);
349
- return () => clearInterval(id);
350
- }, [walletAddress, spokeProvider, silentRefresh]);
351
- const { mutateAsync: loginMutate, isPending: isLoginPending } = useRadfiAuth(spokeProvider);
352
- const login = React.useCallback(async () => {
353
- const result = await loginMutate();
354
- setIsAuthed(true);
355
- setTradingAddress(result.tradingAddress || void 0);
356
- }, [loginMutate]);
357
- return { walletAddress, isAuthed, tradingAddress, login, isLoginPending };
358
- }
359
- function useFundTradingWallet(spokeProvider) {
360
- const queryClient = reactQuery.useQueryClient();
361
- return reactQuery.useMutation({
362
- mutationFn: async (amount) => {
363
- if (!spokeProvider) {
364
- throw new Error("Bitcoin spoke provider not found");
365
- }
366
- return sdk.BitcoinSpokeService.fundTradingWallet(amount, spokeProvider);
367
- },
368
- onSuccess: () => {
369
- queryClient.invalidateQueries({ queryKey: ["btc-balance"] });
370
- queryClient.invalidateQueries({ queryKey: ["xBalances"] });
371
- }
372
- });
373
- }
374
- function useBitcoinBalance(address, rpcUrl = "https://mempool.space/api") {
375
- return reactQuery.useQuery({
376
- queryKey: ["btc-balance", address],
377
- queryFn: async () => {
378
- if (!address) return 0n;
379
- const response = await fetch(`${rpcUrl}/address/${address}/utxo`);
380
- if (!response.ok) return 0n;
381
- const utxos = await response.json();
382
- return BigInt(utxos.reduce((sum, utxo) => sum + utxo.value, 0));
383
- },
384
- enabled: !!address
385
- });
386
- }
387
- function useTradingWalletBalance(spokeProvider, tradingAddress) {
388
- return reactQuery.useQuery({
389
- queryKey: ["trading-wallet-balance", tradingAddress],
390
- queryFn: () => {
391
- if (!spokeProvider || !tradingAddress) {
392
- throw new Error("spokeProvider and tradingAddress are required");
393
- }
394
- return spokeProvider.radfi.getBalance(tradingAddress);
395
- },
396
- enabled: !!spokeProvider && !!tradingAddress
397
- });
398
- }
399
- function useExpiredUtxos(spokeProvider, tradingAddress) {
400
- return reactQuery.useQuery({
401
- queryKey: ["expired-utxos", tradingAddress],
402
- queryFn: async () => {
403
- if (!spokeProvider || !tradingAddress) {
404
- throw new Error("spokeProvider and tradingAddress are required");
405
- }
406
- const result = await spokeProvider.radfi.getExpiredUtxos(tradingAddress);
407
- return result.data;
408
- },
409
- enabled: !!spokeProvider && !!tradingAddress,
410
- refetchInterval: 6e4
411
- // refetch every minute
412
- });
413
- }
414
- function useRenewUtxos(spokeProvider) {
415
- const queryClient = reactQuery.useQueryClient();
416
- return reactQuery.useMutation({
417
- mutationFn: async ({ txIdVouts }) => {
418
- if (!spokeProvider) {
419
- throw new Error("Bitcoin spoke provider not found");
420
- }
421
- const userAddress = await spokeProvider.walletProvider.getWalletAddress();
422
- const session = loadRadfiSession(userAddress);
423
- const accessToken = session?.accessToken || spokeProvider.radfiAccessToken;
424
- if (!accessToken) {
425
- throw new Error("Radfi authentication required. Please login first.");
426
- }
427
- const buildResult = await spokeProvider.radfi.buildRenewUtxoTransaction(
428
- { userAddress, txIdVouts },
429
- accessToken
430
- );
431
- const signedTx = await spokeProvider.walletProvider.signTransaction(
432
- buildResult.base64Psbt,
433
- false
434
- );
435
- const signedBase64Tx = sdk.normalizePsbtToBase64(signedTx);
436
- return spokeProvider.radfi.signAndBroadcastRenewUtxo(
437
- { userAddress, signedBase64Tx },
438
- accessToken
439
- );
440
- },
441
- onSuccess: () => {
442
- queryClient.invalidateQueries({ queryKey: ["expired-utxos"] });
443
- queryClient.invalidateQueries({ queryKey: ["trading-wallet-balance"] });
444
- }
445
- });
446
- }
447
- function useRadfiWithdraw(spokeProvider) {
448
- const queryClient = reactQuery.useQueryClient();
449
- return reactQuery.useMutation({
450
- mutationFn: async ({ amount, tokenId, withdrawTo }) => {
451
- if (!spokeProvider) {
452
- throw new Error("Bitcoin spoke provider not found");
453
- }
454
- const userAddress = await spokeProvider.walletProvider.getWalletAddress();
455
- const session = loadRadfiSession(userAddress);
456
- const accessToken = session?.accessToken || spokeProvider.radfiAccessToken;
457
- if (!accessToken) {
458
- throw new Error("Radfi authentication required. Please login first.");
459
- }
460
- const buildResult = await spokeProvider.radfi.withdrawToUser(
461
- { userAddress, amount, tokenId, withdrawTo },
462
- accessToken
463
- );
464
- const signedTx = await spokeProvider.walletProvider.signTransaction(
465
- buildResult.base64Psbt,
466
- false
467
- );
468
- const signedBase64Tx = sdk.normalizePsbtToBase64(signedTx);
469
- const txId = await spokeProvider.radfi.signAndBroadcastWithdraw(
470
- { userAddress, signedBase64Tx },
471
- accessToken
472
- );
473
- return { txId, fee: buildResult.fee.totalFee };
474
- },
475
- onSuccess: () => {
476
- queryClient.invalidateQueries({ queryKey: ["trading-wallet-balance"] });
477
- queryClient.invalidateQueries({ queryKey: ["btc-balance"] });
478
- queryClient.invalidateQueries({ queryKey: ["xBalances"] });
479
- }
480
- });
481
- }
482
- function useBorrow() {
483
- const { sodax } = useSodaxContext();
484
- return reactQuery.useMutation({
485
- mutationFn: async ({ params, spokeProvider }) => {
486
- if (!spokeProvider) {
487
- throw new Error("spokeProvider is not found");
488
- }
489
- const response = await sodax.moneyMarket.borrow(params, spokeProvider);
490
- if (!response.ok) {
491
- throw response.error;
492
- }
493
- return response;
494
- }
495
- });
496
- }
497
- function useRepay() {
498
- const { sodax } = useSodaxContext();
499
- return reactQuery.useMutation({
500
- mutationFn: async ({ params, spokeProvider }) => {
501
- if (!spokeProvider) {
502
- throw new Error("spokeProvider is not found");
503
- }
504
- const response = await sodax.moneyMarket.repay(params, spokeProvider);
505
- if (!response.ok) {
506
- throw response.error;
507
- }
508
- return response;
509
- }
510
- });
511
- }
512
- function useSupply() {
513
- const { sodax } = useSodaxContext();
514
- return reactQuery.useMutation({
515
- mutationFn: async ({ params, spokeProvider }) => {
516
- if (!spokeProvider) {
517
- throw new Error("spokeProvider is not found");
518
- }
519
- const response = await sodax.moneyMarket.supply(params, spokeProvider);
520
- if (!response.ok) {
521
- throw response.error;
522
- }
523
- return response;
524
- }
525
- });
526
- }
527
- function useWithdraw() {
528
- const { sodax } = useSodaxContext();
529
- return reactQuery.useMutation({
530
- mutationFn: async ({ params, spokeProvider }) => {
531
- if (!spokeProvider) {
532
- throw new Error("spokeProvider is not found");
533
- }
534
- const response = await sodax.moneyMarket.withdraw(params, spokeProvider);
535
- if (!response.ok) {
536
- throw response.error;
537
- }
538
- return response;
539
- }
540
- });
541
- }
542
- function isLegacyParams(params) {
543
- return "spokeProvider" in params || "address" in params;
544
- }
545
- function resolveParams(params) {
546
- if (isLegacyParams(params)) {
547
- return {
548
- spokeChainId: params.spokeProvider?.chainConfig.chain.id,
549
- userAddress: params.address
550
- };
551
- }
552
- return { spokeChainId: params.spokeChainId, userAddress: params.userAddress };
553
- }
554
- function useUserReservesData(params) {
555
- const { sodax } = useSodaxContext();
556
- const resolved = params ? resolveParams(params) : { spokeChainId: void 0, userAddress: void 0 };
557
- const defaultQueryOptions = {
558
- queryKey: ["mm", "userReservesData", resolved.spokeChainId, resolved.userAddress],
559
- enabled: !!resolved.spokeChainId && !!resolved.userAddress,
560
- refetchInterval: 5e3
561
- };
562
- const queryOptions = {
563
- ...defaultQueryOptions,
564
- ...params?.queryOptions
565
- // override default query options if provided
566
- };
567
- return reactQuery.useQuery({
568
- ...queryOptions,
569
- queryFn: async () => {
570
- if (!resolved.spokeChainId || !resolved.userAddress) {
571
- throw new Error("spokeChainId or userAddress is not defined");
572
- }
573
- return await sodax.moneyMarket.data.getUserReservesData(resolved.spokeChainId, resolved.userAddress);
574
- }
575
- });
576
- }
577
- function useReservesData(params) {
578
- const defaultQueryOptions = {
579
- queryKey: ["mm", "reservesData"],
580
- refetchInterval: 5e3
581
- };
582
- const queryOptions = {
583
- ...defaultQueryOptions,
584
- ...params?.queryOptions
585
- // override default query options if provided
586
- };
587
- const { sodax } = useSodaxContext();
588
- return reactQuery.useQuery({
589
- ...queryOptions,
590
- queryFn: async () => {
591
- return await sodax.moneyMarket.data.getReservesData();
592
- }
593
- });
594
- }
595
- function useMMAllowance({
596
- params,
597
- spokeProvider,
598
- queryOptions
599
- }) {
600
- const { sodax } = useSodaxContext();
601
- const defaultQueryOptions = {
602
- queryKey: ["mm", "allowance", params?.token, params?.action],
603
- /**
604
- * IMPORTANT: Skip allowance checks for 'borrow' and 'withdraw' actions.
605
- *
606
- * Reason: According to the SDK's MoneyMarketService.isAllowanceValid() implementation,
607
- * borrow and withdraw actions do NOT require ERC-20 token approval. The SDK's
608
- * isAllowanceValid() method always returns `true` for these actions without making
609
- * any on-chain allowance checks.
610
- *
611
- * This optimization prevents unnecessary RPC calls and avoids showing confusing states for actions that don't actually need approval.
612
- *
613
- * Only 'supply' and 'repay' actions require token approval and should trigger allowance checks.
614
- */
615
- enabled: !!spokeProvider && !!params && params.action !== "borrow" && params.action !== "withdraw",
616
- refetchInterval: 5e3,
617
- gcTime: 0
618
- // Don't cache failed queries
619
- };
620
- queryOptions = {
621
- ...defaultQueryOptions,
622
- ...queryOptions
623
- // override default query options if provided
624
- };
625
- return reactQuery.useQuery({
626
- ...queryOptions,
627
- queryFn: async () => {
628
- if (!spokeProvider) throw new Error("Spoke provider is required");
629
- if (!params) throw new Error("Params are required");
630
- if (params.action === "borrow" || params.action === "withdraw") {
631
- return true;
632
- }
633
- const allowance = await sodax.moneyMarket.isAllowanceValid(params, spokeProvider);
634
- if (!allowance.ok) {
635
- throw allowance.error;
636
- }
637
- return allowance.value;
638
- }
639
- });
640
- }
641
- function useMMApprove() {
642
- const { sodax } = useSodaxContext();
643
- const queryClient = reactQuery.useQueryClient();
644
- return reactQuery.useMutation({
645
- mutationFn: async ({ params, spokeProvider }) => {
646
- if (!spokeProvider) {
647
- throw new Error("Spoke provider not found");
648
- }
649
- const allowance = await sodax.moneyMarket.approve(params, spokeProvider, false);
650
- if (!allowance.ok) {
651
- throw allowance.error;
652
- }
653
- return allowance.value;
654
- },
655
- onSuccess: (_, { params, spokeProvider }) => {
656
- queryClient.invalidateQueries({
657
- queryKey: ["mm", "allowance", spokeProvider?.chainConfig.chain.id, params.token, params.action]
658
- });
659
- }
660
- });
661
- }
662
- function useAToken({ aToken, queryOptions }) {
663
- const { sodax } = useSodaxContext();
664
- const defaultQueryOptions = {
665
- queryKey: ["mm", "aToken", aToken],
666
- enabled: !!aToken
667
- };
668
- queryOptions = {
669
- ...defaultQueryOptions,
670
- ...queryOptions
671
- // override default query options if provided
672
- };
673
- return reactQuery.useQuery({
674
- ...queryOptions,
675
- queryFn: async () => {
676
- if (!aToken) {
677
- throw new Error("aToken address or hub provider is not defined");
678
- }
679
- if (!viem.isAddress(aToken)) {
680
- throw new Error("aToken address is not a valid address");
681
- }
682
- const aTokenData = await sodax.moneyMarket.data.getATokenData(aToken);
683
- return {
684
- ...aTokenData,
685
- xChainId: sodax.hubProvider.chainConfig.chain.id
686
- };
687
- }
688
- });
689
- }
690
- function useATokensBalances({
691
- aTokens,
692
- spokeProvider,
693
- userAddress,
694
- queryOptions
695
- }) {
696
- const { sodax } = useSodaxContext();
697
- const defaultQueryOptions = {
698
- queryKey: ["mm", "aTokensBalances", aTokens, spokeProvider?.chainConfig.chain.id, userAddress],
699
- enabled: aTokens.length > 0 && aTokens.every((token) => viem.isAddress(token)) && !!spokeProvider && !!userAddress
700
- };
701
- queryOptions = {
702
- ...defaultQueryOptions,
703
- ...queryOptions
704
- // override default query options if provided
705
- };
706
- return reactQuery.useQuery({
707
- ...queryOptions,
708
- queryFn: async () => {
709
- if (aTokens.length === 0) {
710
- return /* @__PURE__ */ new Map();
711
- }
712
- if (!spokeProvider || !userAddress) {
713
- throw new Error("Spoke provider and user address are required");
714
- }
715
- for (const aToken of aTokens) {
716
- if (!viem.isAddress(aToken)) {
717
- throw new Error(`Invalid aToken address: ${aToken}`);
718
- }
719
- }
720
- const hubWalletAddress = await sdk.HubService.getUserHubWalletAddress(userAddress, spokeProvider.chainConfig.chain.id, sodax.hubProvider);
721
- return await sodax.moneyMarket.data.getATokensBalances(aTokens, hubWalletAddress);
722
- }
723
- });
724
- }
725
- function useReservesUsdFormat(params) {
726
- const { sodax } = useSodaxContext();
727
- const defaultQueryOptions = { queryKey: ["mm", "reservesUsdFormat"] };
728
- const queryOptions = {
729
- ...defaultQueryOptions,
730
- ...params?.queryOptions
731
- // override default query options if provided
732
- };
733
- return reactQuery.useQuery({
734
- ...queryOptions,
735
- queryFn: async () => {
736
- const reserves = await sodax.moneyMarket.data.getReservesHumanized();
737
- return sodax.moneyMarket.data.formatReservesUSD(sodax.moneyMarket.data.buildReserveDataWithPrice(reserves));
738
- }
739
- });
740
- }
741
- function isLegacyParams2(params) {
742
- return "spokeProvider" in params || "address" in params;
743
- }
744
- function resolveParams2(params) {
745
- if (isLegacyParams2(params)) {
746
- return {
747
- spokeChainId: params.spokeProvider?.chainConfig.chain.id,
748
- userAddress: params.address
749
- };
750
- }
751
- return { spokeChainId: params.spokeChainId, userAddress: params.userAddress };
752
- }
753
- function useUserFormattedSummary(params) {
754
- const { sodax } = useSodaxContext();
755
- const resolved = params ? resolveParams2(params) : { spokeChainId: void 0, userAddress: void 0 };
756
- const defaultQueryOptions = {
757
- queryKey: ["mm", "userFormattedSummary", resolved.spokeChainId, resolved.userAddress],
758
- enabled: !!resolved.spokeChainId && !!resolved.userAddress,
759
- refetchInterval: 5e3
760
- };
761
- const queryOptions = {
762
- ...defaultQueryOptions,
763
- ...params?.queryOptions
764
- // override default query options if provided
765
- };
766
- return reactQuery.useQuery({
767
- ...queryOptions,
768
- queryFn: async () => {
769
- if (!resolved.spokeChainId || !resolved.userAddress) {
770
- throw new Error("spokeChainId or userAddress is not defined");
771
- }
772
- const reserves = await sodax.moneyMarket.data.getReservesHumanized();
773
- const formattedReserves = sodax.moneyMarket.data.formatReservesUSD(
774
- sodax.moneyMarket.data.buildReserveDataWithPrice(reserves)
775
- );
776
- const userReserves = await sodax.moneyMarket.data.getUserReservesHumanized(
777
- resolved.spokeChainId,
778
- resolved.userAddress
779
- );
780
- return sodax.moneyMarket.data.formatUserSummary(
781
- sodax.moneyMarket.data.buildUserSummaryRequest(reserves, formattedReserves, userReserves)
782
- );
783
- }
784
- });
785
- }
786
- var useQuote = (payload) => {
787
- const { sodax } = useSodaxContext();
788
- const queryKey = React.useMemo(() => {
789
- if (!payload) return ["quote", void 0];
790
- return [
791
- "quote",
792
- {
793
- ...payload,
794
- amount: payload.amount.toString()
795
- }
796
- ];
797
- }, [payload]);
798
- return reactQuery.useQuery({
799
- queryKey,
800
- queryFn: async () => {
801
- if (!payload) {
802
- return void 0;
803
- }
804
- return sodax.swaps.getQuote(payload);
805
- },
806
- enabled: !!payload,
807
- refetchInterval: 3e3
808
- });
809
- };
810
- function useSwap(spokeProvider) {
811
- const { sodax } = useSodaxContext();
812
- const queryClient = reactQuery.useQueryClient();
813
- return reactQuery.useMutation({
814
- mutationFn: async (params) => {
815
- if (!spokeProvider) {
816
- throw new Error("Spoke provider not found");
817
- }
818
- return sodax.swaps.swap({
819
- intentParams: params,
820
- spokeProvider
821
- });
822
- },
823
- onSuccess: () => {
824
- queryClient.invalidateQueries({ queryKey: ["xBalances"] });
825
- }
826
- });
827
- }
828
- var useStatus = (intent_tx_hash) => {
829
- const { sodax } = useSodaxContext();
830
- return reactQuery.useQuery({
831
- queryKey: [intent_tx_hash],
832
- queryFn: async () => {
833
- return sodax.swaps.getStatus({ intent_tx_hash });
834
- },
835
- refetchInterval: 3e3
836
- // 3s
837
- });
838
- };
839
- function useSwapAllowance(params, spokeProvider) {
840
- const { sodax } = useSodaxContext();
841
- return reactQuery.useQuery({
842
- queryKey: ["allowance", params],
843
- queryFn: async () => {
844
- if (!spokeProvider || !params) {
845
- return false;
846
- }
847
- const allowance = await sodax.swaps.isAllowanceValid({
848
- intentParams: params,
849
- spokeProvider
850
- });
851
- if (allowance.ok) {
852
- return allowance.value;
853
- }
854
- return false;
855
- },
856
- enabled: !!spokeProvider && !!params,
857
- refetchInterval: 2e3
858
- });
859
- }
860
- function useSwapApprove(params, spokeProvider) {
861
- const { sodax } = useSodaxContext();
862
- const queryClient = reactQuery.useQueryClient();
863
- const {
864
- mutateAsync: approve,
865
- isPending,
866
- error,
867
- reset: resetError
868
- } = reactQuery.useMutation({
869
- mutationFn: async ({ params: params2 }) => {
870
- if (!spokeProvider) {
871
- throw new Error("Spoke provider not found");
872
- }
873
- if (!params2) {
874
- throw new Error("Swap Params not found");
875
- }
876
- const allowance = await sodax.swaps.approve({
877
- intentParams: params2,
878
- spokeProvider
879
- });
880
- if (!allowance.ok) {
881
- throw new Error("Failed to approve input token");
882
- }
883
- return allowance.ok;
884
- },
885
- onSuccess: () => {
886
- queryClient.invalidateQueries({ queryKey: ["allowance", params] });
887
- }
888
- });
889
- return {
890
- approve,
891
- isLoading: isPending,
892
- error,
893
- resetError
894
- };
895
- }
896
- function useCancelSwap(spokeProvider) {
897
- const { sodax } = useSodaxContext();
898
- return reactQuery.useMutation({
899
- mutationFn: async ({ intent, raw = false }) => {
900
- if (!spokeProvider) {
901
- throw new Error("Spoke provider not found");
902
- }
903
- return sodax.swaps.cancelIntent(intent, spokeProvider, raw);
904
- }
905
- });
906
- }
907
- function useCreateLimitOrder(spokeProvider) {
908
- const { sodax } = useSodaxContext();
909
- return reactQuery.useMutation({
910
- mutationFn: async (params) => {
911
- if (!spokeProvider) {
912
- throw new Error("Spoke provider not found");
913
- }
914
- return sodax.swaps.createLimitOrder({
915
- intentParams: params,
916
- spokeProvider
917
- });
918
- }
919
- });
920
- }
921
- function useCancelLimitOrder() {
922
- const { sodax } = useSodaxContext();
923
- return reactQuery.useMutation({
924
- mutationFn: async ({ intent, spokeProvider, timeout }) => {
925
- return sodax.swaps.cancelLimitOrder({
926
- intent,
927
- spokeProvider,
928
- timeout
929
- });
930
- }
931
- });
932
- }
933
- var useBackendIntentByTxHash = (params) => {
934
- const { sodax } = useSodaxContext();
935
- const defaultQueryOptions = {
936
- queryKey: ["api", "intent", "txHash", params?.params?.txHash],
937
- enabled: !!params?.params?.txHash && params?.params?.txHash.length > 0,
938
- retry: 3,
939
- refetchInterval: 1e3
940
- };
941
- const queryOptions = {
942
- ...defaultQueryOptions,
943
- ...params?.queryOptions
944
- };
945
- return reactQuery.useQuery({
946
- ...queryOptions,
947
- queryFn: async () => {
948
- if (!params?.params?.txHash) {
949
- return void 0;
950
- }
951
- return sodax.backendApi.getIntentByTxHash(params.params.txHash);
952
- }
953
- });
954
- };
955
- var useBackendIntentByHash = (params) => {
956
- const { sodax } = useSodaxContext();
957
- const defaultQueryOptions = {
958
- queryKey: ["api", "intent", "hash", params?.params?.intentHash],
959
- enabled: !!params?.params?.intentHash && params?.params?.intentHash.length > 0,
960
- retry: 3
961
- };
962
- const queryOptions = {
963
- ...defaultQueryOptions,
964
- ...params?.queryOptions
965
- };
966
- return reactQuery.useQuery({
967
- ...queryOptions,
968
- queryFn: async () => {
969
- if (!params?.params?.intentHash) {
970
- return void 0;
971
- }
972
- return sodax.backendApi.getIntentByHash(params.params.intentHash);
973
- }
974
- });
975
- };
976
- var useBackendUserIntents = ({
977
- params,
978
- queryOptions
979
- }) => {
980
- const { sodax } = useSodaxContext();
981
- const defaultQueryOptions = {
982
- queryKey: ["api", "intent", "user", params],
983
- enabled: !!params && !!params.userAddress && params.userAddress.length > 0,
984
- retry: 3
985
- };
986
- queryOptions = {
987
- ...defaultQueryOptions,
988
- ...queryOptions
989
- // override default query options if provided
990
- };
991
- return reactQuery.useQuery({
992
- ...queryOptions,
993
- queryFn: async () => {
994
- if (!params?.userAddress) {
995
- return void 0;
996
- }
997
- return sodax.backendApi.getUserIntents(params);
998
- }
999
- });
1000
- };
1001
- var useBackendSubmitSwapTx = (params) => {
1002
- const { sodax } = useSodaxContext();
1003
- const defaultMutationOptions = {
1004
- retry: 3
1005
- };
1006
- const mutationOptions = {
1007
- ...defaultMutationOptions,
1008
- ...params?.mutationOptions
1009
- };
1010
- return reactQuery.useMutation({
1011
- ...mutationOptions,
1012
- mutationFn: async (request) => {
1013
- return sodax.backendApi.submitSwapTx(request, params?.apiConfig);
1014
- }
1015
- });
1016
- };
1017
- var useBackendSubmitSwapTxStatus = (params) => {
1018
- const { sodax } = useSodaxContext();
1019
- const defaultQueryOptions = {
1020
- queryKey: ["api", "swaps", "submit-tx", "status", params?.params?.txHash, params?.params?.srcChainId],
1021
- enabled: !!params?.params?.txHash && params.params.txHash.length > 0,
1022
- retry: 3,
1023
- refetchInterval: (query) => {
1024
- const status = query.state.data?.data?.status;
1025
- if (status === "executed" || status === "failed") return false;
1026
- return 1e3;
1027
- }
1028
- };
1029
- const queryOptions = {
1030
- ...defaultQueryOptions,
1031
- ...params?.queryOptions
1032
- };
1033
- return reactQuery.useQuery({
1034
- ...queryOptions,
1035
- queryFn: async () => {
1036
- if (!params?.params?.txHash) {
1037
- return void 0;
1038
- }
1039
- return sodax.backendApi.getSubmitSwapTxStatus(
1040
- {
1041
- txHash: params.params.txHash,
1042
- srcChainId: params.params.srcChainId
1043
- },
1044
- params.apiConfig
1045
- );
1046
- }
1047
- });
1048
- };
1049
- var useBackendOrderbook = (params) => {
1050
- const { sodax } = useSodaxContext();
1051
- const defaultQueryOptions = {
1052
- queryKey: ["api", "solver", "orderbook", params?.pagination?.offset, params?.pagination?.limit],
1053
- enabled: !!params?.pagination && !!params?.pagination.offset && !!params?.pagination.limit,
1054
- staleTime: 30 * 1e3,
1055
- // 30 seconds for real-time data
1056
- retry: 3
1057
- };
1058
- const queryOptions = {
1059
- ...defaultQueryOptions,
1060
- ...params?.queryOptions
1061
- // override default query options if provided
1062
- };
1063
- return reactQuery.useQuery({
1064
- ...queryOptions,
1065
- queryFn: async () => {
1066
- if (!params?.pagination || !params?.pagination.offset || !params?.pagination.limit) {
1067
- return void 0;
1068
- }
1069
- return sodax.backendApi.getOrderbook(params.pagination);
1070
- }
1071
- });
1072
- };
1073
- var useBackendMoneyMarketPosition = (params) => {
1074
- const { sodax } = useSodaxContext();
1075
- const defaultQueryOptions = {
1076
- queryKey: ["api", "mm", "position", params?.userAddress],
1077
- enabled: !!params?.userAddress && params?.userAddress.length > 0,
1078
- retry: 3
1079
- };
1080
- const queryOptions = {
1081
- ...defaultQueryOptions,
1082
- ...params?.queryOptions
1083
- };
1084
- return reactQuery.useQuery({
1085
- ...queryOptions,
1086
- queryFn: async () => {
1087
- if (!params?.userAddress) {
1088
- return void 0;
1089
- }
1090
- return sodax.backendApi.getMoneyMarketPosition(params.userAddress);
1091
- }
1092
- });
1093
- };
1094
- var useBackendAllMoneyMarketAssets = (params) => {
1095
- const { sodax } = useSodaxContext();
1096
- const defaultQueryOptions = {
1097
- queryKey: ["api", "mm", "assets", "all"],
1098
- enabled: true,
1099
- retry: 3
1100
- };
1101
- const queryOptions = {
1102
- ...defaultQueryOptions,
1103
- ...params?.queryOptions
1104
- };
1105
- return reactQuery.useQuery({
1106
- ...queryOptions,
1107
- queryFn: async () => {
1108
- return sodax.backendApi.getAllMoneyMarketAssets();
1109
- }
1110
- });
1111
- };
1112
- var useBackendMoneyMarketAsset = (params) => {
1113
- const { sodax } = useSodaxContext();
1114
- const defaultQueryOptions = {
1115
- queryKey: ["api", "mm", "asset", params?.params?.reserveAddress],
1116
- enabled: !!params?.params?.reserveAddress && params?.params?.reserveAddress.length > 0,
1117
- retry: 3
1118
- };
1119
- const queryOptions = {
1120
- ...defaultQueryOptions,
1121
- ...params?.queryOptions
1122
- };
1123
- return reactQuery.useQuery({
1124
- ...queryOptions,
1125
- queryFn: async () => {
1126
- if (!params?.params?.reserveAddress) {
1127
- return void 0;
1128
- }
1129
- return sodax.backendApi.getMoneyMarketAsset(params.params.reserveAddress);
1130
- }
1131
- });
1132
- };
1133
- var useBackendMoneyMarketAssetBorrowers = (params) => {
1134
- const { sodax } = useSodaxContext();
1135
- const defaultQueryOptions = {
1136
- queryKey: ["api", "mm", "asset", "borrowers", params],
1137
- enabled: !!params?.params?.reserveAddress && !!params.pagination.offset && !!params.pagination.limit,
1138
- retry: 3
1139
- };
1140
- const queryOptions = {
1141
- ...defaultQueryOptions,
1142
- ...params?.queryOptions
1143
- };
1144
- return reactQuery.useQuery({
1145
- ...queryOptions,
1146
- queryFn: async () => {
1147
- if (!params?.params?.reserveAddress || !params.pagination.offset || !params.pagination.limit) {
1148
- return void 0;
1149
- }
1150
- return sodax.backendApi.getMoneyMarketAssetBorrowers(params.params.reserveAddress, {
1151
- offset: params.pagination.offset,
1152
- limit: params.pagination.limit
1153
- });
1154
- }
1155
- });
1156
- };
1157
- var useBackendMoneyMarketAssetSuppliers = (params) => {
1158
- const { sodax } = useSodaxContext();
1159
- const defaultQueryOptions = {
1160
- queryKey: ["api", "mm", "asset", "suppliers", params],
1161
- enabled: !!params?.params?.reserveAddress && !!params.pagination.offset && !!params.pagination.limit,
1162
- retry: 3
1163
- };
1164
- const queryOptions = {
1165
- ...defaultQueryOptions,
1166
- ...params?.queryOptions
1167
- };
1168
- return reactQuery.useQuery({
1169
- ...queryOptions,
1170
- queryFn: async () => {
1171
- if (!params?.params?.reserveAddress || !params.pagination.offset || !params.pagination.limit) {
1172
- return void 0;
1173
- }
1174
- return sodax.backendApi.getMoneyMarketAssetSuppliers(params.params.reserveAddress, {
1175
- offset: params.pagination.offset,
1176
- limit: params.pagination.limit
1177
- });
1178
- }
1179
- });
1180
- };
1181
- var useBackendAllMoneyMarketBorrowers = (params) => {
1182
- const { sodax } = useSodaxContext();
1183
- const defaultQueryOptions = {
1184
- queryKey: ["api", "mm", "borrowers", "all", params],
1185
- enabled: !!params && !!params.pagination.offset && !!params.pagination.limit,
1186
- retry: 3
1187
- };
1188
- const queryOptions = {
1189
- ...defaultQueryOptions,
1190
- ...params?.queryOptions
1191
- };
1192
- return reactQuery.useQuery({
1193
- ...queryOptions,
1194
- queryFn: async () => {
1195
- if (!params || !params.pagination.offset || !params.pagination.limit) {
1196
- return void 0;
1197
- }
1198
- return sodax.backendApi.getAllMoneyMarketBorrowers({
1199
- offset: params.pagination.offset,
1200
- limit: params.pagination.limit
1201
- });
1202
- }
1203
- });
1204
- };
1205
- function useBridgeAllowance(params, spokeProvider) {
1206
- const { sodax } = useSodaxContext();
1207
- return reactQuery.useQuery({
1208
- queryKey: ["bridge-allowance", params],
1209
- queryFn: async () => {
1210
- if (!spokeProvider || !params) {
1211
- return false;
1212
- }
1213
- const allowance = await sodax.bridge.isAllowanceValid({
1214
- params,
1215
- spokeProvider
1216
- });
1217
- if (allowance.ok) {
1218
- return allowance.value;
1219
- }
1220
- return false;
1221
- },
1222
- enabled: !!spokeProvider && !!params
1223
- });
1224
- }
1225
- function useBridgeApprove(spokeProvider) {
1226
- const { sodax } = useSodaxContext();
1227
- const queryClient = reactQuery.useQueryClient();
1228
- const {
1229
- mutateAsync: approve,
1230
- isPending,
1231
- error,
1232
- reset: resetError
1233
- } = reactQuery.useMutation({
1234
- mutationFn: async (params) => {
1235
- if (!spokeProvider) {
1236
- throw new Error("Spoke provider not found");
1237
- }
1238
- const allowance = await sodax.bridge.approve({
1239
- params,
1240
- spokeProvider
1241
- });
1242
- if (!allowance.ok) {
1243
- throw new Error("Failed to approve tokens for bridge");
1244
- }
1245
- return true;
1246
- },
1247
- onSuccess: (_, params) => {
1248
- queryClient.invalidateQueries({ queryKey: ["bridge-allowance", params] });
1249
- }
1250
- });
1251
- return {
1252
- approve,
1253
- isLoading: isPending,
1254
- error,
1255
- resetError
1256
- };
1257
- }
1258
- function useBridge(spokeProvider) {
1259
- const { sodax } = useSodaxContext();
1260
- return reactQuery.useMutation({
1261
- mutationFn: async (params) => {
1262
- if (!spokeProvider) {
1263
- throw new Error("Spoke provider not found");
1264
- }
1265
- const result = await sodax.bridge.bridge({
1266
- params,
1267
- spokeProvider
1268
- });
1269
- if (!result.ok) {
1270
- throw new Error(`Bridge failed: ${result.error.code}`);
1271
- }
1272
- return result;
1273
- }
1274
- });
1275
- }
1276
- function useGetBridgeableAmount(from, to) {
1277
- const { sodax } = useSodaxContext();
1278
- return reactQuery.useQuery({
1279
- queryKey: ["spoke-asset-manager-token-balance", from, to],
1280
- queryFn: async () => {
1281
- if (!from || !to) {
1282
- return { amount: 0n, decimals: 0, type: "DEPOSIT_LIMIT" };
1283
- }
1284
- const result = await sodax.bridge.getBridgeableAmount(from, to);
1285
- if (result.ok) {
1286
- return result.value;
1287
- }
1288
- console.error("Error getting bridgeable amount:", result.error);
1289
- return { amount: 0n, decimals: 0, type: "DEPOSIT_LIMIT" };
1290
- },
1291
- enabled: !!from && !!to
1292
- });
1293
- }
1294
- function useGetBridgeableTokens(from, to, token) {
1295
- const { sodax } = useSodaxContext();
1296
- return reactQuery.useQuery({
1297
- queryKey: ["bridgeable-tokens", from, to, token],
1298
- queryFn: async () => {
1299
- if (!from || !to || !token) {
1300
- return [];
1301
- }
1302
- const result = sodax.bridge.getBridgeableTokens(from, to, token);
1303
- if (result.ok) {
1304
- return result.value;
1305
- }
1306
- console.error("Error getting bridgeable tokens:", result.error);
1307
- return [];
1308
- },
1309
- enabled: !!from && !!to && !!token
1310
- });
1311
- }
1312
- function useStake(spokeProvider) {
1313
- const { sodax } = useSodaxContext();
1314
- return reactQuery.useMutation({
1315
- mutationFn: async (params) => {
1316
- if (!spokeProvider) {
1317
- throw new Error("Spoke provider not found");
1318
- }
1319
- const result = await sodax.staking.stake(params, spokeProvider);
1320
- if (!result.ok) {
1321
- throw new Error(`Stake failed: ${result.error.code}`);
1322
- }
1323
- return result.value;
1324
- }
1325
- });
1326
- }
1327
- function useStakeApprove(spokeProvider) {
1328
- const { sodax } = useSodaxContext();
1329
- return reactQuery.useMutation({
1330
- mutationFn: async (params) => {
1331
- if (!spokeProvider) {
1332
- throw new Error("Spoke provider not found");
1333
- }
1334
- const result = await sodax.staking.approve({
1335
- params: { ...params, action: "stake" },
1336
- spokeProvider
1337
- });
1338
- if (!result.ok) {
1339
- throw new Error(`Stake approval failed: ${result.error.code}`);
1340
- }
1341
- return result.value;
1342
- }
1343
- });
1344
- }
1345
- function useStakeAllowance(params, spokeProvider) {
1346
- const { sodax } = useSodaxContext();
1347
- return reactQuery.useQuery({
1348
- queryKey: ["soda", "stakeAllowance", params, spokeProvider?.chainConfig.chain.id],
1349
- queryFn: async () => {
1350
- if (!params || !spokeProvider) {
1351
- return false;
1352
- }
1353
- const result = await sodax.staking.isAllowanceValid({
1354
- params: { ...params, action: "stake" },
1355
- spokeProvider
1356
- });
1357
- if (!result.ok) {
1358
- throw new Error(`Allowance check failed: ${result.error.code}`);
1359
- }
1360
- return result.value;
1361
- },
1362
- enabled: !!params && !!spokeProvider,
1363
- refetchInterval: 5e3
1364
- // Refetch every 5 seconds
1365
- });
1366
- }
1367
- function useUnstake(spokeProvider) {
1368
- const { sodax } = useSodaxContext();
1369
- const queryClient = reactQuery.useQueryClient();
1370
- return reactQuery.useMutation({
1371
- mutationFn: async (params) => {
1372
- if (!spokeProvider) {
1373
- throw new Error("Spoke provider not found");
1374
- }
1375
- const result = await sodax.staking.unstake({ ...params, action: "unstake" }, spokeProvider);
1376
- if (!result.ok) {
1377
- throw new Error(`Unstake failed: ${result.error.code}`);
1378
- }
1379
- return result.value;
1380
- },
1381
- onSuccess: () => {
1382
- queryClient.invalidateQueries({ queryKey: ["stakingInfo"] });
1383
- queryClient.invalidateQueries({ queryKey: ["unstakingInfo"] });
1384
- queryClient.invalidateQueries({ queryKey: ["unstakingInfoWithPenalty"] });
1385
- }
1386
- });
1387
- }
1388
- function useClaim(spokeProvider) {
1389
- const { sodax } = useSodaxContext();
1390
- return reactQuery.useMutation({
1391
- mutationFn: async (params) => {
1392
- if (!spokeProvider) {
1393
- throw new Error("Spoke provider not found");
1394
- }
1395
- const result = await sodax.staking.claim({ ...params, action: "claim" }, spokeProvider);
1396
- if (!result.ok) {
1397
- throw new Error(`Claim failed: ${result.error.code}`);
1398
- }
1399
- return result.value;
1400
- }
1401
- });
1402
- }
1403
- function useCancelUnstake(spokeProvider) {
1404
- const { sodax } = useSodaxContext();
1405
- const queryClient = reactQuery.useQueryClient();
1406
- return reactQuery.useMutation({
1407
- mutationFn: async (params) => {
1408
- if (!spokeProvider) {
1409
- throw new Error("Spoke provider not available");
1410
- }
1411
- const result = await sodax.staking.cancelUnstake({ ...params, action: "cancelUnstake" }, spokeProvider);
1412
- if (!result.ok) {
1413
- throw new Error(`Cancel unstake failed: ${result.error.code}`);
1414
- }
1415
- return result.value;
1416
- },
1417
- onSuccess: () => {
1418
- queryClient.invalidateQueries({ queryKey: ["stakingInfo"] });
1419
- queryClient.invalidateQueries({ queryKey: ["unstakingInfo"] });
1420
- queryClient.invalidateQueries({ queryKey: ["unstakingInfoWithPenalty"] });
1421
- }
1422
- });
1423
- }
1424
- function useStakingInfo(spokeProvider, refetchInterval = 5e3) {
1425
- const { sodax } = useSodaxContext();
1426
- return reactQuery.useQuery({
1427
- queryKey: ["soda", "stakingInfo", spokeProvider?.chainConfig.chain.id],
1428
- queryFn: async () => {
1429
- if (!spokeProvider) {
1430
- throw new Error("Spoke provider not found");
1431
- }
1432
- const result = await sodax.staking.getStakingInfoFromSpoke(spokeProvider);
1433
- if (!result.ok) {
1434
- throw new Error(`Failed to fetch staking info: ${result.error.code}`);
1435
- }
1436
- return result.value;
1437
- },
1438
- enabled: !!spokeProvider,
1439
- refetchInterval
1440
- });
1441
- }
1442
- function useUnstakingInfoWithPenalty(userAddress, spokeProvider, refetchInterval = 5e3) {
1443
- const { sodax } = useSodaxContext();
1444
- return reactQuery.useQuery({
1445
- queryKey: ["soda", "unstakingInfoWithPenalty", spokeProvider?.chainConfig.chain.id, userAddress],
1446
- queryFn: async () => {
1447
- if (!spokeProvider) {
1448
- throw new Error("Spoke provider not found");
1449
- }
1450
- const penaltyResult = await sodax.staking.getUnstakingInfoWithPenalty(spokeProvider);
1451
- if (!penaltyResult.ok) {
1452
- throw new Error(`Failed to fetch unstaking info with penalty: ${penaltyResult.error.code}`);
1453
- }
1454
- return penaltyResult.value;
1455
- },
1456
- enabled: !!spokeProvider && !!userAddress,
1457
- refetchInterval
1458
- });
1459
- }
1460
- function useStakingConfig(refetchInterval = 3e4) {
1461
- const { sodax } = useSodaxContext();
1462
- return reactQuery.useQuery({
1463
- queryKey: ["soda", "stakingConfig"],
1464
- queryFn: async () => {
1465
- const result = await sodax.staking.getStakingConfig();
1466
- if (!result.ok) {
1467
- throw new Error(`Failed to fetch staking config: ${result.error.code}`);
1468
- }
1469
- return result.value;
1470
- },
1471
- refetchInterval
1472
- });
1473
- }
1474
- function useStakeRatio(amount, refetchInterval = 1e4) {
1475
- const { sodax } = useSodaxContext();
1476
- return reactQuery.useQuery({
1477
- queryKey: ["soda", "stakeRatio", amount?.toString()],
1478
- queryFn: async () => {
1479
- if (!amount || amount <= 0n) {
1480
- throw new Error("Amount must be greater than 0");
1481
- }
1482
- if (!sodax?.staking) {
1483
- throw new Error("Staking service not available");
1484
- }
1485
- const result = await sodax.staking.getStakeRatio(amount);
1486
- if (!result.ok) {
1487
- throw new Error(`Failed to fetch stake ratio: ${result.error.code}`);
1488
- }
1489
- return result.value;
1490
- },
1491
- enabled: !!amount && amount > 0n && !!sodax?.staking,
1492
- refetchInterval
1493
- });
1494
- }
1495
- function useInstantUnstakeRatio(amount, refetchInterval = 1e4) {
1496
- const { sodax } = useSodaxContext();
1497
- console.log("useInstantUnstakeRatio hook called with:", { amount: amount?.toString(), sodax: !!sodax });
1498
- return reactQuery.useQuery({
1499
- queryKey: ["soda", "instantUnstakeRatio", amount?.toString()],
1500
- queryFn: async () => {
1501
- console.log("useInstantUnstakeRatio queryFn called with amount:", amount?.toString());
1502
- if (!amount || amount <= 0n) {
1503
- throw new Error("Amount must be greater than 0");
1504
- }
1505
- if (!sodax?.staking) {
1506
- throw new Error("Staking service not available");
1507
- }
1508
- const result = await sodax.staking.getInstantUnstakeRatio(amount);
1509
- if (!result.ok) {
1510
- throw new Error(`Failed to fetch instant unstake ratio: ${result.error.code}`);
1511
- }
1512
- return result.value;
1513
- },
1514
- enabled: !!amount && amount > 0n && !!sodax?.staking,
1515
- refetchInterval
1516
- });
1517
- }
1518
- function useConvertedAssets(amount, refetchInterval = 1e4) {
1519
- const { sodax } = useSodaxContext();
1520
- return reactQuery.useQuery({
1521
- queryKey: ["soda", "convertedAssets", amount?.toString()],
1522
- queryFn: async () => {
1523
- if (!amount || amount <= 0n) {
1524
- throw new Error("Amount must be greater than 0");
1525
- }
1526
- const result = await sodax.staking.getConvertedAssets(amount);
1527
- if (!result.ok) {
1528
- throw new Error(`Failed to fetch converted assets: ${result.error.code}`);
1529
- }
1530
- return result.value;
1531
- },
1532
- enabled: !!amount && amount > 0n && !!sodax?.staking,
1533
- refetchInterval
1534
- });
1535
- }
1536
- function useInstantUnstake(spokeProvider) {
1537
- const { sodax } = useSodaxContext();
1538
- return reactQuery.useMutation({
1539
- mutationFn: async (params) => {
1540
- if (!spokeProvider) {
1541
- throw new Error("spokeProvider is not found");
1542
- }
1543
- const result = await sodax.staking.instantUnstake({ ...params, action: "instantUnstake" }, spokeProvider);
1544
- if (!result.ok) {
1545
- throw new Error(`Instant unstake failed: ${result.error.code}`);
1546
- }
1547
- return result.value;
1548
- },
1549
- onError: (error) => {
1550
- console.error("Instant unstake error:", error);
1551
- }
1552
- });
1553
- }
1554
- function useUnstakeAllowance(params, spokeProvider) {
1555
- const { sodax } = useSodaxContext();
1556
- return reactQuery.useQuery({
1557
- queryKey: ["soda", "unstakeAllowance", params, spokeProvider?.chainConfig.chain.id],
1558
- queryFn: async () => {
1559
- if (!params || !spokeProvider) {
1560
- return false;
1561
- }
1562
- const result = await sodax.staking.isAllowanceValid({
1563
- params: { ...params, action: "unstake" },
1564
- spokeProvider
1565
- });
1566
- if (!result.ok) {
1567
- console.error(`Unstake allowance check failed: ${result.error.code}, error: ${result.error.error}`);
1568
- throw new Error(`Unstake allowance check failed: ${result.error.code}`);
1569
- }
1570
- return result.value;
1571
- },
1572
- enabled: !!params && !!spokeProvider,
1573
- refetchInterval: 5e3
1574
- // Refetch every 5 seconds
1575
- });
1576
- }
1577
- function useUnstakeApprove(spokeProvider) {
1578
- const { sodax } = useSodaxContext();
1579
- return reactQuery.useMutation({
1580
- mutationFn: async (params) => {
1581
- console.log("useUnstakeApprove called with params:", params);
1582
- if (!spokeProvider) {
1583
- throw new Error("Spoke provider not found");
1584
- }
1585
- const result = await sodax.staking.approve({
1586
- params: { ...params, action: "unstake" },
1587
- spokeProvider
1588
- });
1589
- if (!result.ok) {
1590
- throw new Error(`Unstake approval failed: ${result.error.code}`);
1591
- }
1592
- return result.value;
1593
- }
1594
- });
1595
- }
1596
- function useUnstakingInfo(userAddress, spokeProvider, refetchInterval = 5e3) {
1597
- const { sodax } = useSodaxContext();
1598
- return reactQuery.useQuery({
1599
- queryKey: ["soda", "unstakingInfoWithPenalty", spokeProvider?.chainConfig.chain.id, userAddress],
1600
- queryFn: async () => {
1601
- if (!spokeProvider || !userAddress) {
1602
- throw new Error("Spoke provider or user address not found");
1603
- }
1604
- const result = await sodax.staking.getUnstakingInfo(spokeProvider);
1605
- if (!result.ok) {
1606
- throw new Error(`Failed to fetch unstaking info: ${result.error.code}`);
1607
- }
1608
- return result.value;
1609
- },
1610
- enabled: !!spokeProvider && !!userAddress,
1611
- refetchInterval
1612
- });
1613
- }
1614
- function useInstantUnstakeApprove(spokeProvider) {
1615
- const { sodax } = useSodaxContext();
1616
- return reactQuery.useMutation({
1617
- mutationFn: async (params) => {
1618
- console.log("useInstantUnstakeApprove called with params:", params);
1619
- if (!spokeProvider) {
1620
- throw new Error("Spoke provider not found");
1621
- }
1622
- const result = await sodax.staking.approve({
1623
- params: { ...params, action: "instantUnstake" },
1624
- spokeProvider
1625
- });
1626
- if (!result.ok) {
1627
- throw new Error(`Instant unstake approval failed: ${result.error.code}`);
1628
- }
1629
- return result.value;
1630
- }
1631
- });
1632
- }
1633
- function useInstantUnstakeAllowance(params, spokeProvider) {
1634
- const { sodax } = useSodaxContext();
1635
- return reactQuery.useQuery({
1636
- queryKey: ["soda", "instantUnstakeAllowance", params, spokeProvider?.chainConfig.chain.id],
1637
- queryFn: async () => {
1638
- if (!params || !spokeProvider) {
1639
- return false;
1640
- }
1641
- const result = await sodax.staking.isAllowanceValid({
1642
- params: { ...params, action: "instantUnstake" },
1643
- spokeProvider
1644
- });
1645
- if (!result.ok) {
1646
- console.error(`Unstake allowance check failed: ${result.error.code}, error: ${result.error.error}`);
1647
- throw new Error(`Unstake allowance check failed: ${result.error.code}`);
1648
- }
1649
- return result.value;
1650
- },
1651
- enabled: !!params && !!spokeProvider,
1652
- refetchInterval: 5e3
1653
- // Refetch every 5 seconds
1654
- });
1655
- }
1656
-
1657
- // src/hooks/migrate/types.ts
1658
- var MIGRATION_MODE_ICX_SODA = "icxsoda";
1659
- var MIGRATION_MODE_BNUSD = "bnusd";
1660
-
1661
- // src/hooks/migrate/useMigrate.tsx
1662
- function useMigrate(spokeProvider) {
1663
- const { sodax } = useSodaxContext();
1664
- return reactQuery.useMutation({
1665
- mutationFn: async (params) => {
1666
- const { token, amount, migrationMode = MIGRATION_MODE_ICX_SODA, toToken, destinationAddress } = params;
1667
- const amountToMigrate = viem.parseUnits(amount ?? "0", token?.decimals ?? 0);
1668
- if (!spokeProvider) {
1669
- throw new Error("Spoke provider not found");
1670
- }
1671
- if (migrationMode === MIGRATION_MODE_ICX_SODA) {
1672
- if (token?.xChainId === types.ICON_MAINNET_CHAIN_ID) {
1673
- const params2 = {
1674
- address: sdk.spokeChainConfig[types.ICON_MAINNET_CHAIN_ID].nativeToken,
1675
- amount: amountToMigrate,
1676
- to: destinationAddress
1677
- };
1678
- const result2 = await sodax.migration.migrateIcxToSoda(params2, spokeProvider, 3e4);
1679
- if (result2.ok) {
1680
- const [spokeTxHash, hubTxHash] = result2.value;
1681
- return { spokeTxHash, hubTxHash };
1682
- }
1683
- throw new Error("ICX to SODA migration failed. Please try again.");
1684
- }
1685
- const revertParams = {
1686
- amount: amountToMigrate,
1687
- to: destinationAddress
1688
- };
1689
- const result = await sodax.migration.revertMigrateSodaToIcx(
1690
- revertParams,
1691
- spokeProvider,
1692
- 3e4
1693
- );
1694
- if (result.ok) {
1695
- const [hubTxHash, spokeTxHash] = result.value;
1696
- return { spokeTxHash, hubTxHash };
1697
- }
1698
- throw new Error("SODA to ICX migration failed. Please try again.");
1699
- }
1700
- if (migrationMode === MIGRATION_MODE_BNUSD) {
1701
- const params2 = {
1702
- srcChainId: token?.xChainId,
1703
- dstChainId: toToken?.xChainId,
1704
- srcbnUSD: token?.address,
1705
- dstbnUSD: toToken?.address,
1706
- amount: amountToMigrate,
1707
- to: destinationAddress
1708
- };
1709
- const result = await sodax.migration.migratebnUSD(params2, spokeProvider, 3e4);
1710
- if (result.ok) {
1711
- const [spokeTxHash, hubTxHash] = result.value;
1712
- return { spokeTxHash, hubTxHash };
1713
- }
1714
- const errorMessage = sdk.isLegacybnUSDToken(token?.address) ? "bnUSD migration failed. Please try again." : "bnUSD reverse migration failed. Please try again.";
1715
- throw new Error(errorMessage);
1716
- }
1717
- throw new Error("Invalid migration mode");
1718
- }
1719
- });
1720
- }
1721
- function useMigrationAllowance(params, spokeProvider) {
1722
- const { sodax } = useSodaxContext();
1723
- return reactQuery.useQuery({
1724
- queryKey: ["migration-allowance", params],
1725
- queryFn: async () => {
1726
- if (!spokeProvider || !params) {
1727
- return false;
1728
- }
1729
- const { token, amount, migrationMode = MIGRATION_MODE_ICX_SODA, toToken, destinationAddress } = params;
1730
- if (token?.xChainId === types.ICON_MAINNET_CHAIN_ID) {
1731
- return true;
1732
- }
1733
- if (!spokeProvider) throw new Error("Spoke provider is required");
1734
- const amountToMigrate = viem.parseUnits(amount ?? "0", token?.decimals ?? 0);
1735
- let migrationParams;
1736
- if (migrationMode === MIGRATION_MODE_ICX_SODA) {
1737
- migrationParams = {
1738
- amount: amountToMigrate,
1739
- to: destinationAddress
1740
- };
1741
- } else {
1742
- if (!toToken) throw new Error("Destination token is required for bnUSD migration");
1743
- migrationParams = {
1744
- srcChainId: token?.xChainId,
1745
- dstChainId: toToken?.xChainId,
1746
- srcbnUSD: token?.address,
1747
- dstbnUSD: toToken?.address,
1748
- amount: amountToMigrate,
1749
- to: destinationAddress
1750
- };
1751
- }
1752
- const allowance = await sodax.migration.isAllowanceValid(migrationParams, "revert", spokeProvider);
1753
- if (allowance.ok) {
1754
- return allowance.value;
1755
- }
1756
- return false;
1757
- },
1758
- enabled: !!spokeProvider && !!params,
1759
- refetchInterval: 2e3
1760
- });
1761
- }
1762
- function useMigrationApprove(params, spokeProvider) {
1763
- const { sodax } = useSodaxContext();
1764
- const [isLoading, setIsLoading] = React.useState(false);
1765
- const [error, setError] = React.useState(null);
1766
- const [isApproved, setIsApproved] = React.useState(false);
1767
- const queryClient = reactQuery.useQueryClient();
1768
- const prevTokenAddress = React.useRef(void 0);
1769
- const prevAmount = React.useRef(void 0);
1770
- React.useEffect(() => {
1771
- if (prevTokenAddress.current !== params?.token?.address || prevAmount.current !== params?.amount) {
1772
- setIsApproved(false);
1773
- prevTokenAddress.current = params?.token?.address;
1774
- prevAmount.current = params?.amount;
1775
- }
1776
- }, [params?.token?.address, params?.amount]);
1777
- const approve = React.useCallback(
1778
- async ({ params: approveParams }) => {
1779
- try {
1780
- setIsLoading(true);
1781
- setError(null);
1782
- if (!spokeProvider) {
1783
- throw new Error("Spoke provider not found");
1784
- }
1785
- if (!approveParams) {
1786
- throw new Error("Migration intent not found");
1787
- }
1788
- const { token, amount, migrationMode = MIGRATION_MODE_ICX_SODA, toToken, destinationAddress } = approveParams;
1789
- const amountToMigrate = viem.parseUnits(amount ?? "0", token?.decimals ?? 0);
1790
- let result;
1791
- if (migrationMode === MIGRATION_MODE_ICX_SODA) {
1792
- const revertParams = {
1793
- amount: amountToMigrate,
1794
- to: destinationAddress
1795
- };
1796
- result = await sodax.migration.approve(revertParams, "revert", spokeProvider, false);
1797
- } else if (migrationMode === MIGRATION_MODE_BNUSD) {
1798
- if (!toToken) throw new Error("Destination token is required for bnUSD migration");
1799
- const migrationParams = {
1800
- srcChainId: token?.xChainId,
1801
- dstChainId: toToken?.xChainId,
1802
- srcbnUSD: token?.address,
1803
- dstbnUSD: toToken?.address,
1804
- amount: amountToMigrate,
1805
- to: destinationAddress
1806
- };
1807
- result = await sodax.migration.approve(migrationParams, "revert", spokeProvider, false);
1808
- } else {
1809
- throw new Error("Invalid migration mode");
1810
- }
1811
- if (!result.ok) {
1812
- throw new Error("Failed to approve tokens");
1813
- }
1814
- setIsApproved(true);
1815
- queryClient.invalidateQueries({ queryKey: ["migration-allowance", params] });
1816
- return result.ok;
1817
- } catch (err) {
1818
- const error2 = err instanceof Error ? err : new Error("An unknown error occurred");
1819
- setError(error2);
1820
- throw error2;
1821
- } finally {
1822
- setIsLoading(false);
1823
- }
1824
- },
1825
- [spokeProvider, sodax, queryClient, params]
1826
- );
1827
- const resetError = React.useCallback(() => {
1828
- setError(null);
1829
- }, []);
1830
- return {
1831
- approve,
1832
- isLoading,
1833
- error,
1834
- resetError,
1835
- isApproved
1836
- };
1837
- }
1838
- function usePools(params) {
1839
- const { sodax } = useSodaxContext();
1840
- const defaultQueryOptions = {
1841
- queryKey: ["dex", "pools"],
1842
- staleTime: Number.POSITIVE_INFINITY
1843
- // Pools list is static, cache indefinitely
1844
- };
1845
- const queryOptions = { ...defaultQueryOptions, ...params?.queryOptions };
1846
- return reactQuery.useQuery({
1847
- ...queryOptions,
1848
- queryFn: async () => {
1849
- return sodax.dex.clService.getPools();
1850
- }
1851
- });
1852
- }
1853
- function usePoolData({
1854
- poolKey,
1855
- queryOptions = {
1856
- queryKey: ["dex", "poolData", poolKey],
1857
- enabled: poolKey !== null,
1858
- staleTime: 1e4,
1859
- refetchInterval: 3e4
1860
- }
1861
- }) {
1862
- const { sodax } = useSodaxContext();
1863
- return reactQuery.useQuery({
1864
- ...queryOptions,
1865
- queryFn: async () => {
1866
- if (!poolKey) {
1867
- throw new Error("Pool key is required");
1868
- }
1869
- return await sodax.dex.clService.getPoolData(poolKey, sodax.hubProvider.publicClient);
1870
- },
1871
- enabled: poolKey !== null
1872
- });
1873
- }
1874
- function usePoolBalances({
1875
- poolData,
1876
- poolKey,
1877
- spokeProvider,
1878
- enabled = true,
1879
- queryOptions = {
1880
- queryKey: [
1881
- "dex",
1882
- "poolBalances",
1883
- poolData?.poolKey,
1884
- spokeProvider?.chainConfig.chain.id
1885
- ],
1886
- enabled: enabled && poolData !== null && poolKey !== null && spokeProvider !== null,
1887
- staleTime: 5e3,
1888
- // Consider data stale after 5 seconds
1889
- refetchInterval: 1e4
1890
- // Refetch every 10 seconds
1891
- }
1892
- }) {
1893
- const { sodax } = useSodaxContext();
1894
- return reactQuery.useQuery({
1895
- ...queryOptions,
1896
- queryFn: async () => {
1897
- if (!poolData || !spokeProvider || !poolKey) {
1898
- throw new Error("Pool data, pool key, and spoke provider are required");
1899
- }
1900
- const [balance0, balance1] = await Promise.all([
1901
- sodax.dex.assetService.getDeposit(poolData.token0.address, spokeProvider),
1902
- sodax.dex.assetService.getDeposit(poolData.token1.address, spokeProvider)
1903
- ]);
1904
- return {
1905
- token0Balance: balance0,
1906
- token1Balance: balance1
1907
- };
1908
- }
1909
- });
1910
- }
1911
- function usePositionInfo({
1912
- tokenId,
1913
- poolKey,
1914
- queryOptions = {
1915
- queryKey: ["dex", "positionInfo", tokenId, poolKey],
1916
- enabled: tokenId !== null && poolKey !== null && tokenId !== "",
1917
- staleTime: 1e4
1918
- // Consider data stale after 10 seconds
1919
- }
1920
- }) {
1921
- const { sodax } = useSodaxContext();
1922
- return reactQuery.useQuery({
1923
- queryFn: async () => {
1924
- if (!tokenId || !poolKey) {
1925
- throw new Error("Token ID and pool key are required");
1926
- }
1927
- const tokenIdBigInt = BigInt(tokenId);
1928
- const publicClient = sodax.hubProvider.publicClient;
1929
- const info = await sodax.dex.clService.getPositionInfo(tokenIdBigInt, publicClient);
1930
- const isValid = info.poolKey.currency0.toLowerCase() === poolKey.currency0.toLowerCase() && info.poolKey.currency1.toLowerCase() === poolKey.currency1.toLowerCase() && info.poolKey.fee === poolKey.fee;
1931
- return {
1932
- positionInfo: info,
1933
- isValid
1934
- };
1935
- },
1936
- ...queryOptions
1937
- });
1938
- }
1939
- function useDexDeposit() {
1940
- const { sodax } = useSodaxContext();
1941
- const queryClient = reactQuery.useQueryClient();
1942
- return reactQuery.useMutation({
1943
- mutationFn: async ({ params, spokeProvider }) => {
1944
- if (!spokeProvider) {
1945
- throw new Error("Spoke provider is required");
1946
- }
1947
- if (!params) {
1948
- throw new Error("Deposit params are required");
1949
- }
1950
- const depositResult = await sodax.dex.assetService.deposit({
1951
- params,
1952
- spokeProvider
1953
- });
1954
- if (!depositResult.ok) {
1955
- throw new Error(`Deposit failed: ${depositResult.error?.code || "Unknown error"}`);
1956
- }
1957
- return depositResult.value;
1958
- },
1959
- onSuccess: () => {
1960
- queryClient.invalidateQueries({ queryKey: ["dex", "poolBalances"] });
1961
- }
1962
- });
1963
- }
1964
- function useDexWithdraw() {
1965
- const { sodax } = useSodaxContext();
1966
- const queryClient = reactQuery.useQueryClient();
1967
- return reactQuery.useMutation({
1968
- mutationFn: async ({ params, spokeProvider }) => {
1969
- if (!spokeProvider) {
1970
- throw new Error("Spoke provider is required");
1971
- }
1972
- const withdrawResult = await sodax.dex.assetService.withdraw({
1973
- params,
1974
- spokeProvider
1975
- });
1976
- if (!withdrawResult.ok) {
1977
- throw new Error(`Withdraw failed: ${withdrawResult.error.code}`);
1978
- }
1979
- return withdrawResult.value;
1980
- },
1981
- onSuccess: () => {
1982
- queryClient.invalidateQueries({ queryKey: ["dex", "poolBalances"] });
1983
- }
1984
- });
1985
- }
1986
- function useDexAllowance({
1987
- params,
1988
- spokeProvider,
1989
- queryOptions = {
1990
- queryKey: [
1991
- "dex",
1992
- "allowance",
1993
- params?.asset,
1994
- params?.poolToken,
1995
- params?.amount.toString(),
1996
- spokeProvider?.chainConfig.chain.id
1997
- ],
1998
- enabled: !!params && !!spokeProvider
1999
- }
2000
- }) {
2001
- const { sodax } = useSodaxContext();
2002
- return reactQuery.useQuery({
2003
- ...queryOptions,
2004
- queryFn: async () => {
2005
- if (!params || !spokeProvider) {
2006
- throw new Error("Params and spoke provider are required");
2007
- }
2008
- const allowanceResult = await sodax.dex.assetService.isAllowanceValid({
2009
- params: {
2010
- asset: params.asset,
2011
- amount: params.amount,
2012
- poolToken: params.poolToken
2013
- },
2014
- spokeProvider
2015
- });
2016
- if (!allowanceResult.ok) {
2017
- return false;
2018
- }
2019
- return allowanceResult.value;
2020
- }
2021
- });
2022
- }
2023
- function useDexApprove() {
2024
- const { sodax } = useSodaxContext();
2025
- const queryClient = reactQuery.useQueryClient();
2026
- return reactQuery.useMutation({
2027
- mutationFn: async ({ params, spokeProvider }) => {
2028
- const approveResult = await sodax.dex.assetService.approve({
2029
- params,
2030
- spokeProvider,
2031
- raw: false
2032
- });
2033
- if (!approveResult.ok) {
2034
- throw new Error("Approval failed");
2035
- }
2036
- return approveResult.value;
2037
- },
2038
- onSuccess: () => {
2039
- queryClient.invalidateQueries({ queryKey: ["dex", "allowance"] });
2040
- }
2041
- });
2042
- }
2043
- function useLiquidityAmounts(minPrice, maxPrice, poolData) {
2044
- const [liquidityToken0Amount, setLiquidityToken0Amount] = React.useState("");
2045
- const [liquidityToken1Amount, setLiquidityToken1Amount] = React.useState("");
2046
- const [lastEditedToken, setLastEditedToken] = React.useState(null);
2047
- const { minPriceNum, maxPriceNum, isValidPriceRange } = React.useMemo(() => {
2048
- const parsedMin = Number.parseFloat(minPrice);
2049
- const parsedMax = Number.parseFloat(maxPrice);
2050
- const isValid = parsedMin > 0 && parsedMax > 0 && parsedMin < parsedMax;
2051
- return {
2052
- minPriceNum: parsedMin,
2053
- maxPriceNum: parsedMax,
2054
- isValidPriceRange: isValid
2055
- };
2056
- }, [minPrice, maxPrice]);
2057
- const { tickLower, tickUpper, currentTick } = React.useMemo(() => {
2058
- if (!poolData || !isValidPriceRange) {
2059
- return {
2060
- tickLower: null,
2061
- tickUpper: null,
2062
- currentTick: null
2063
- };
2064
- }
2065
- try {
2066
- const lower = sdk.ClService.priceToTick(minPriceNum, poolData.token0, poolData.token1, poolData.tickSpacing);
2067
- const upper = sdk.ClService.priceToTick(maxPriceNum, poolData.token0, poolData.token1, poolData.tickSpacing);
2068
- return {
2069
- tickLower: lower,
2070
- tickUpper: upper,
2071
- currentTick: BigInt(poolData.currentTick)
2072
- };
2073
- } catch (err) {
2074
- console.error("Failed to calculate ticks:", err);
2075
- return {
2076
- tickLower: null,
2077
- tickUpper: null,
2078
- currentTick: null
2079
- };
2080
- }
2081
- }, [minPriceNum, maxPriceNum, poolData, isValidPriceRange]);
2082
- const handleToken0AmountChange = React.useCallback(
2083
- (value) => {
2084
- setLiquidityToken0Amount(value);
2085
- setLastEditedToken("token0");
2086
- if (!value || !poolData || !tickLower || !tickUpper || !currentTick) {
2087
- return;
2088
- }
2089
- const amount0 = Number.parseFloat(value);
2090
- if (amount0 <= 0 || !isValidPriceRange) {
2091
- return;
2092
- }
2093
- try {
2094
- const amount0BigInt = BigInt(Math.floor(amount0 * 10 ** poolData.token0.decimals));
2095
- const amount1BigInt = sdk.ClService.calculateAmount1FromAmount0(amount0BigInt, tickLower, tickUpper, currentTick);
2096
- const amount1 = Number(amount1BigInt) / 10 ** poolData.token1.decimals;
2097
- setLiquidityToken1Amount(amount1.toFixed(6));
2098
- } catch (err) {
2099
- console.error("Failed to calculate token1 amount:", err);
2100
- }
2101
- },
2102
- [poolData, tickLower, tickUpper, currentTick, isValidPriceRange]
2103
- );
2104
- const handleToken1AmountChange = React.useCallback(
2105
- (value) => {
2106
- setLiquidityToken1Amount(value);
2107
- setLastEditedToken("token1");
2108
- if (!value || !poolData || !tickLower || !tickUpper || !currentTick) {
2109
- return;
2110
- }
2111
- const amount1 = Number.parseFloat(value);
2112
- if (amount1 <= 0 || !isValidPriceRange) {
2113
- return;
2114
- }
2115
- try {
2116
- const amount1BigInt = BigInt(Math.floor(amount1 * 10 ** poolData.token1.decimals));
2117
- const amount0BigInt = sdk.ClService.calculateAmount0FromAmount1(amount1BigInt, tickLower, tickUpper, currentTick);
2118
- const amount0 = Number(amount0BigInt) / 10 ** poolData.token0.decimals;
2119
- setLiquidityToken0Amount(amount0.toFixed(6));
2120
- } catch (err) {
2121
- console.error("Failed to calculate token0 amount:", err);
2122
- }
2123
- },
2124
- [poolData, tickLower, tickUpper, currentTick, isValidPriceRange]
2125
- );
2126
- React.useEffect(() => {
2127
- if (!poolData || !tickLower || !tickUpper || !lastEditedToken || !isValidPriceRange) {
2128
- return;
2129
- }
2130
- if (lastEditedToken === "token0" && liquidityToken0Amount) {
2131
- handleToken0AmountChange(liquidityToken0Amount);
2132
- } else if (lastEditedToken === "token1" && liquidityToken1Amount) {
2133
- handleToken1AmountChange(liquidityToken1Amount);
2134
- }
2135
- }, [
2136
- poolData,
2137
- lastEditedToken,
2138
- liquidityToken0Amount,
2139
- liquidityToken1Amount,
2140
- handleToken0AmountChange,
2141
- handleToken1AmountChange,
2142
- tickLower,
2143
- tickUpper,
2144
- isValidPriceRange
2145
- ]);
2146
- return {
2147
- liquidityToken0Amount,
2148
- liquidityToken1Amount,
2149
- lastEditedToken,
2150
- setLiquidityToken0Amount,
2151
- setLiquidityToken1Amount,
2152
- handleToken0AmountChange,
2153
- handleToken1AmountChange
2154
- };
2155
- }
2156
- function useSupplyLiquidity() {
2157
- const { sodax } = useSodaxContext();
2158
- const queryClient = reactQuery.useQueryClient();
2159
- return reactQuery.useMutation({
2160
- mutationFn: async ({ params, spokeProvider }) => {
2161
- if (params.tokenId && params.isValidPosition) {
2162
- const increaseResult = await sodax.dex.clService.increaseLiquidity({
2163
- params: {
2164
- poolKey: params.poolKey,
2165
- tokenId: BigInt(params.tokenId),
2166
- tickLower: params.tickLower,
2167
- tickUpper: params.tickUpper,
2168
- liquidity: params.liquidity,
2169
- amount0Max: params.amount0Max,
2170
- amount1Max: params.amount1Max,
2171
- sqrtPriceX96: params.sqrtPriceX96
2172
- },
2173
- spokeProvider
2174
- });
2175
- if (!increaseResult.ok) {
2176
- throw new Error(`Increase liquidity failed: ${increaseResult.error?.code || "Unknown error"}`);
2177
- }
2178
- return increaseResult.value;
2179
- }
2180
- const supplyResult = await sodax.dex.clService.supplyLiquidity({
2181
- params: {
2182
- poolKey: params.poolKey,
2183
- tickLower: params.tickLower,
2184
- tickUpper: params.tickUpper,
2185
- liquidity: params.liquidity,
2186
- amount0Max: params.amount0Max,
2187
- amount1Max: params.amount1Max,
2188
- sqrtPriceX96: params.sqrtPriceX96
2189
- },
2190
- spokeProvider
2191
- });
2192
- if (!supplyResult.ok) {
2193
- throw new Error(`Supply liquidity failed: ${supplyResult.error?.code || "Unknown error"}`);
2194
- }
2195
- return supplyResult.value;
2196
- },
2197
- onSuccess: () => {
2198
- queryClient.invalidateQueries({ queryKey: ["dex", "poolBalances"] });
2199
- queryClient.invalidateQueries({ queryKey: ["dex", "positionInfo"] });
2200
- }
2201
- });
2202
- }
2203
- function useDecreaseLiquidity() {
2204
- const { sodax } = useSodaxContext();
2205
- const queryClient = reactQuery.useQueryClient();
2206
- return reactQuery.useMutation({
2207
- mutationFn: async ({ params, spokeProvider }) => {
2208
- if (!spokeProvider) {
2209
- throw new Error("Spoke provider is required");
2210
- }
2211
- const decreaseResult = await sodax.dex.clService.decreaseLiquidity({
2212
- params,
2213
- spokeProvider
2214
- });
2215
- if (!decreaseResult.ok) {
2216
- throw new Error(`Decrease liquidity failed: ${decreaseResult.error?.code || "Unknown error"}`);
2217
- }
2218
- return decreaseResult.value;
2219
- },
2220
- onSuccess: () => {
2221
- queryClient.invalidateQueries({ queryKey: ["dex", "poolBalances"] });
2222
- queryClient.invalidateQueries({ queryKey: ["dex", "positionInfo"] });
2223
- }
2224
- });
2225
- }
2226
- function createDecreaseLiquidityParamsProps({
2227
- poolKey,
2228
- tokenId,
2229
- percentage,
2230
- positionInfo,
2231
- slippageTolerance
2232
- }) {
2233
- const percentageNum = Number.parseFloat(String(percentage));
2234
- const slippage = Number.parseFloat(String(slippageTolerance));
2235
- if (percentageNum <= 0 || percentageNum > 100) {
2236
- throw new Error("Percentage must be between 0 and 100");
2237
- }
2238
- if (slippage <= 0 || slippage > 100) {
2239
- throw new Error("Slippage must be between 0 and 100");
2240
- }
2241
- const liquidityToRemove = percentageNum === 100 ? positionInfo.liquidity : positionInfo.liquidity * BigInt(Math.floor(percentageNum * 100)) / 10000n;
2242
- const expectedAmount0 = percentageNum === 100 ? positionInfo.amount0 : positionInfo.amount0 * BigInt(Math.floor(percentageNum * 100)) / 10000n;
2243
- const expectedAmount1 = percentageNum === 100 ? positionInfo.amount1 : positionInfo.amount1 * BigInt(Math.floor(percentageNum * 100)) / 10000n;
2244
- const slippageMultiplier = BigInt(Math.floor((100 - slippage) * 100));
2245
- const amount0Min = expectedAmount0 * slippageMultiplier / 10000n;
2246
- const amount1Min = expectedAmount1 * slippageMultiplier / 10000n;
2247
- return {
2248
- poolKey,
2249
- tokenId: BigInt(tokenId),
2250
- liquidity: liquidityToRemove,
2251
- amount0Min,
2252
- amount1Min
2253
- };
2254
- }
2255
- function createDepositParamsProps({
2256
- tokenIndex,
2257
- amount,
2258
- poolData,
2259
- poolSpokeAssets
2260
- }) {
2261
- const amountNum = Number.parseFloat(String(amount));
2262
- if (!amount || amountNum <= 0) {
2263
- throw new Error("Amount must be greater than 0");
2264
- }
2265
- const token = tokenIndex === 0 ? poolData.token0 : poolData.token1;
2266
- const originalAsset = tokenIndex === 0 ? poolSpokeAssets.token0 : poolSpokeAssets.token1;
2267
- return {
2268
- asset: originalAsset.address,
2269
- // Use deposit token decimals (original asset) for correct unit parsing
2270
- amount: viem.parseUnits(String(amount), originalAsset.decimals),
2271
- poolToken: token.address
2272
- };
2273
- }
2274
- function createSupplyLiquidityParamsProps({
2275
- poolData,
2276
- poolKey,
2277
- minPrice,
2278
- maxPrice,
2279
- liquidityToken0Amount,
2280
- liquidityToken1Amount,
2281
- slippageTolerance,
2282
- positionId,
2283
- isValidPosition
2284
- }) {
2285
- const slippage = Number.parseFloat(String(slippageTolerance));
2286
- if (slippage <= 0 || slippage > 100) {
2287
- throw new Error("Slippage must be between 0 and 100");
2288
- }
2289
- const minPriceNum = Number.parseFloat(minPrice);
2290
- const maxPriceNum = Number.parseFloat(maxPrice);
2291
- const amount0 = Number.parseFloat(liquidityToken0Amount);
2292
- const amount1 = Number.parseFloat(liquidityToken1Amount);
2293
- if (minPriceNum <= 0 || maxPriceNum <= 0 || amount0 <= 0 || amount1 <= 0) {
2294
- throw new Error("All values must be greater than 0");
2295
- }
2296
- if (minPriceNum >= maxPriceNum) {
2297
- throw new Error("Min price must be less than max price");
2298
- }
2299
- const amount0BigInt = viem.parseUnits(liquidityToken0Amount, poolData.token0.decimals);
2300
- const amount1BigInt = viem.parseUnits(liquidityToken1Amount, poolData.token1.decimals);
2301
- const token0 = poolData.token0;
2302
- const token1 = poolData.token1;
2303
- const tickSpacing = poolData.tickSpacing;
2304
- const tickLower = sdk.ClService.priceToTick(minPriceNum, token0, token1, tickSpacing);
2305
- const tickUpper = sdk.ClService.priceToTick(maxPriceNum, token0, token1, tickSpacing);
2306
- const liquidity = sdk.ClService.calculateLiquidityFromAmounts(
2307
- amount0BigInt,
2308
- amount1BigInt,
2309
- tickLower,
2310
- tickUpper,
2311
- BigInt(poolData.currentTick)
2312
- );
2313
- const { amount0Max, amount1Max } = sdk.ClService.calculateMaxAmountsForSlippage(
2314
- liquidity,
2315
- tickLower,
2316
- tickUpper,
2317
- BigInt(poolData.currentTick),
2318
- poolData.sqrtPriceX96,
2319
- slippage
2320
- );
2321
- const tokenId = positionId ? BigInt(positionId) : void 0;
2322
- return {
2323
- poolKey,
2324
- tickLower,
2325
- tickUpper,
2326
- liquidity,
2327
- amount0Max,
2328
- amount1Max,
2329
- sqrtPriceX96: poolData.sqrtPriceX96,
2330
- positionId,
2331
- isValidPosition,
2332
- tokenId
2333
- };
2334
- }
2335
- function createWithdrawParamsProps({
2336
- tokenIndex,
2337
- amount,
2338
- poolData,
2339
- poolSpokeAssets,
2340
- dst
2341
- }) {
2342
- const amountNum = Number.parseFloat(String(amount));
2343
- if (!amount || amountNum <= 0) {
2344
- throw new Error("Please enter a valid amount");
2345
- }
2346
- const token = tokenIndex === 0 ? poolData.token0 : poolData.token1;
2347
- const originalAsset = tokenIndex === 0 ? poolSpokeAssets.token0 : poolSpokeAssets.token1;
2348
- return {
2349
- asset: originalAsset.address,
2350
- amount: viem.parseUnits(String(amount), token.decimals),
2351
- poolToken: token.address,
2352
- dst
2353
- };
2354
- }
2355
-
2356
- // src/hooks/dex/useCreateDepositParams.ts
2357
- function useCreateDepositParams({
2358
- tokenIndex,
2359
- amount,
2360
- poolData,
2361
- poolSpokeAssets
2362
- }) {
2363
- return React.useMemo(() => {
2364
- if (!amount || Number.parseFloat(String(amount)) <= 0) {
2365
- return void 0;
2366
- }
2367
- return createDepositParamsProps({ tokenIndex, amount, poolData, poolSpokeAssets });
2368
- }, [tokenIndex, amount, poolData, poolSpokeAssets]);
2369
- }
2370
- function useCreateSupplyLiquidityParams({
2371
- poolData,
2372
- poolKey,
2373
- minPrice,
2374
- maxPrice,
2375
- liquidityToken0Amount,
2376
- liquidityToken1Amount,
2377
- slippageTolerance,
2378
- positionId,
2379
- isValidPosition
2380
- }) {
2381
- return React.useMemo(() => {
2382
- return createSupplyLiquidityParamsProps({
2383
- poolData,
2384
- poolKey,
2385
- minPrice,
2386
- maxPrice,
2387
- liquidityToken0Amount,
2388
- liquidityToken1Amount,
2389
- slippageTolerance,
2390
- positionId,
2391
- isValidPosition
2392
- });
2393
- }, [
2394
- minPrice,
2395
- maxPrice,
2396
- liquidityToken0Amount,
2397
- liquidityToken1Amount,
2398
- slippageTolerance,
2399
- poolData,
2400
- poolKey,
2401
- positionId,
2402
- isValidPosition
2403
- ]);
2404
- }
2405
- function useCreateDecreaseLiquidityParams({
2406
- poolKey,
2407
- tokenId,
2408
- percentage,
2409
- positionInfo,
2410
- slippageTolerance
2411
- }) {
2412
- return React.useMemo(() => {
2413
- return createDecreaseLiquidityParamsProps({ poolKey, tokenId, percentage, positionInfo, slippageTolerance });
2414
- }, [poolKey, tokenId, percentage, positionInfo, slippageTolerance]);
2415
- }
2416
- function useCreateWithdrawParams({
2417
- tokenIndex,
2418
- amount,
2419
- poolData,
2420
- poolSpokeAssets,
2421
- dst
2422
- }) {
2423
- return React.useMemo(() => {
2424
- if (!amount || Number.parseFloat(String(amount)) <= 0) {
2425
- return void 0;
2426
- }
2427
- return createWithdrawParamsProps({ tokenIndex, amount, poolData, poolSpokeAssets, dst });
2428
- }, [tokenIndex, amount, poolData, poolSpokeAssets, dst]);
2429
- }
2430
- function useClaimRewards() {
2431
- const { sodax } = useSodaxContext();
2432
- const queryClient = reactQuery.useQueryClient();
2433
- return reactQuery.useMutation({
2434
- mutationFn: async ({ params, spokeProvider }) => {
2435
- if (!spokeProvider) {
2436
- throw new Error("Spoke provider is required");
2437
- }
2438
- const result = await sodax.dex.clService.claimRewards({
2439
- params,
2440
- spokeProvider
2441
- });
2442
- if (!result.ok) {
2443
- throw new Error(`Claim rewards failed: ${result.error?.code || "Unknown error"}`);
2444
- }
2445
- return result.value;
2446
- },
2447
- onSuccess: (_, { params, spokeProvider }) => {
2448
- queryClient.invalidateQueries({
2449
- queryKey: ["dex", "poolBalances", params.poolKey, spokeProvider.chainConfig.chain.id]
2450
- });
2451
- queryClient.invalidateQueries({ queryKey: ["dex", "positionInfo", params.tokenId, params.poolKey] });
2452
- queryClient.invalidateQueries({ queryKey: ["dex", "poolData", params.poolKey] });
2453
- }
2454
- });
2455
- }
2456
- var SodaxProvider = ({ children, testnet = false, config, rpcConfig }) => {
2457
- const sodax = new sdk.Sodax(config);
2458
- return /* @__PURE__ */ React__default.default.createElement(SodaxContext.Provider, { value: { sodax, testnet, rpcConfig } }, children);
2459
- };
2460
-
2461
- exports.MIGRATION_MODE_BNUSD = MIGRATION_MODE_BNUSD;
2462
- exports.MIGRATION_MODE_ICX_SODA = MIGRATION_MODE_ICX_SODA;
2463
- exports.SodaxProvider = SodaxProvider;
2464
- exports.clearRadfiSession = clearRadfiSession;
2465
- exports.createDecreaseLiquidityParamsProps = createDecreaseLiquidityParamsProps;
2466
- exports.createDepositParamsProps = createDepositParamsProps;
2467
- exports.createSupplyLiquidityParamsProps = createSupplyLiquidityParamsProps;
2468
- exports.createWithdrawParamsProps = createWithdrawParamsProps;
2469
- exports.loadRadfiSession = loadRadfiSession;
2470
- exports.saveRadfiSession = saveRadfiSession;
2471
- exports.useAToken = useAToken;
2472
- exports.useATokensBalances = useATokensBalances;
2473
- exports.useBackendAllMoneyMarketAssets = useBackendAllMoneyMarketAssets;
2474
- exports.useBackendAllMoneyMarketBorrowers = useBackendAllMoneyMarketBorrowers;
2475
- exports.useBackendIntentByHash = useBackendIntentByHash;
2476
- exports.useBackendIntentByTxHash = useBackendIntentByTxHash;
2477
- exports.useBackendMoneyMarketAsset = useBackendMoneyMarketAsset;
2478
- exports.useBackendMoneyMarketAssetBorrowers = useBackendMoneyMarketAssetBorrowers;
2479
- exports.useBackendMoneyMarketAssetSuppliers = useBackendMoneyMarketAssetSuppliers;
2480
- exports.useBackendMoneyMarketPosition = useBackendMoneyMarketPosition;
2481
- exports.useBackendOrderbook = useBackendOrderbook;
2482
- exports.useBackendSubmitSwapTx = useBackendSubmitSwapTx;
2483
- exports.useBackendSubmitSwapTxStatus = useBackendSubmitSwapTxStatus;
2484
- exports.useBackendUserIntents = useBackendUserIntents;
2485
- exports.useBitcoinBalance = useBitcoinBalance;
2486
- exports.useBorrow = useBorrow;
2487
- exports.useBridge = useBridge;
2488
- exports.useBridgeAllowance = useBridgeAllowance;
2489
- exports.useBridgeApprove = useBridgeApprove;
2490
- exports.useCancelLimitOrder = useCancelLimitOrder;
2491
- exports.useCancelSwap = useCancelSwap;
2492
- exports.useCancelUnstake = useCancelUnstake;
2493
- exports.useClaim = useClaim;
2494
- exports.useClaimRewards = useClaimRewards;
2495
- exports.useConvertedAssets = useConvertedAssets;
2496
- exports.useCreateDecreaseLiquidityParams = useCreateDecreaseLiquidityParams;
2497
- exports.useCreateDepositParams = useCreateDepositParams;
2498
- exports.useCreateLimitOrder = useCreateLimitOrder;
2499
- exports.useCreateSupplyLiquidityParams = useCreateSupplyLiquidityParams;
2500
- exports.useCreateWithdrawParams = useCreateWithdrawParams;
2501
- exports.useDecreaseLiquidity = useDecreaseLiquidity;
2502
- exports.useDeriveUserWalletAddress = useDeriveUserWalletAddress;
2503
- exports.useDexAllowance = useDexAllowance;
2504
- exports.useDexApprove = useDexApprove;
2505
- exports.useDexDeposit = useDexDeposit;
2506
- exports.useDexWithdraw = useDexWithdraw;
2507
- exports.useEstimateGas = useEstimateGas;
2508
- exports.useExpiredUtxos = useExpiredUtxos;
2509
- exports.useFundTradingWallet = useFundTradingWallet;
2510
- exports.useGetBridgeableAmount = useGetBridgeableAmount;
2511
- exports.useGetBridgeableTokens = useGetBridgeableTokens;
2512
- exports.useGetUserHubWalletAddress = useGetUserHubWalletAddress;
2513
- exports.useHubProvider = useHubProvider;
2514
- exports.useInstantUnstake = useInstantUnstake;
2515
- exports.useInstantUnstakeAllowance = useInstantUnstakeAllowance;
2516
- exports.useInstantUnstakeApprove = useInstantUnstakeApprove;
2517
- exports.useInstantUnstakeRatio = useInstantUnstakeRatio;
2518
- exports.useLiquidityAmounts = useLiquidityAmounts;
2519
- exports.useMMAllowance = useMMAllowance;
2520
- exports.useMMApprove = useMMApprove;
2521
- exports.useMigrate = useMigrate;
2522
- exports.useMigrationAllowance = useMigrationAllowance;
2523
- exports.useMigrationApprove = useMigrationApprove;
2524
- exports.usePoolBalances = usePoolBalances;
2525
- exports.usePoolData = usePoolData;
2526
- exports.usePools = usePools;
2527
- exports.usePositionInfo = usePositionInfo;
2528
- exports.useQuote = useQuote;
2529
- exports.useRadfiAuth = useRadfiAuth;
2530
- exports.useRadfiSession = useRadfiSession;
2531
- exports.useRadfiWithdraw = useRadfiWithdraw;
2532
- exports.useRenewUtxos = useRenewUtxos;
2533
- exports.useRepay = useRepay;
2534
- exports.useRequestTrustline = useRequestTrustline;
2535
- exports.useReservesData = useReservesData;
2536
- exports.useReservesUsdFormat = useReservesUsdFormat;
2537
- exports.useSodaxContext = useSodaxContext;
2538
- exports.useSpokeProvider = useSpokeProvider;
2539
- exports.useStake = useStake;
2540
- exports.useStakeAllowance = useStakeAllowance;
2541
- exports.useStakeApprove = useStakeApprove;
2542
- exports.useStakeRatio = useStakeRatio;
2543
- exports.useStakingConfig = useStakingConfig;
2544
- exports.useStakingInfo = useStakingInfo;
2545
- exports.useStatus = useStatus;
2546
- exports.useStellarTrustlineCheck = useStellarTrustlineCheck;
2547
- exports.useSupply = useSupply;
2548
- exports.useSupplyLiquidity = useSupplyLiquidity;
2549
- exports.useSwap = useSwap;
2550
- exports.useSwapAllowance = useSwapAllowance;
2551
- exports.useSwapApprove = useSwapApprove;
2552
- exports.useTradingWalletBalance = useTradingWalletBalance;
2553
- exports.useUnstake = useUnstake;
2554
- exports.useUnstakeAllowance = useUnstakeAllowance;
2555
- exports.useUnstakeApprove = useUnstakeApprove;
2556
- exports.useUnstakingInfo = useUnstakingInfo;
2557
- exports.useUnstakingInfoWithPenalty = useUnstakingInfoWithPenalty;
2558
- exports.useUserFormattedSummary = useUserFormattedSummary;
2559
- exports.useUserReservesData = useUserReservesData;
2560
- exports.useWithdraw = useWithdraw;
2561
- //# sourceMappingURL=index.js.map
2562
- //# sourceMappingURL=index.js.map