@sodax/dapp-kit 0.0.1-rc.8 → 1.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 (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +142 -46
  3. package/dist/index.d.mts +1514 -0
  4. package/dist/index.d.ts +1514 -4
  5. package/dist/index.js +1007 -134
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +967 -134
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +7 -8
  10. package/src/contexts/index.ts +3 -2
  11. package/src/core/index.ts +4 -27
  12. package/src/hooks/backend/README.md +135 -0
  13. package/src/hooks/backend/index.ts +23 -0
  14. package/src/hooks/backend/useBackendAllMoneyMarketAssets.ts +49 -0
  15. package/src/hooks/backend/useBackendAllMoneyMarketBorrowers.ts +61 -0
  16. package/src/hooks/backend/useBackendIntentByHash.ts +53 -0
  17. package/src/hooks/backend/useBackendIntentByTxHash.ts +52 -0
  18. package/src/hooks/backend/useBackendMoneyMarketAsset.ts +57 -0
  19. package/src/hooks/backend/useBackendMoneyMarketAssetBorrowers.ts +67 -0
  20. package/src/hooks/backend/useBackendMoneyMarketAssetSuppliers.ts +67 -0
  21. package/src/hooks/backend/useBackendMoneyMarketPosition.ts +56 -0
  22. package/src/hooks/backend/useBackendOrderbook.ts +63 -0
  23. package/src/hooks/bridge/index.ts +5 -0
  24. package/src/hooks/bridge/useBridge.ts +57 -0
  25. package/src/hooks/bridge/useBridgeAllowance.ts +49 -0
  26. package/src/hooks/bridge/useBridgeApprove.ts +68 -0
  27. package/src/hooks/bridge/useGetBridgeableAmount.ts +50 -0
  28. package/src/hooks/bridge/useGetBridgeableTokens.ts +62 -0
  29. package/src/hooks/index.ts +4 -0
  30. package/src/hooks/migrate/index.ts +4 -0
  31. package/src/hooks/migrate/types.ts +15 -0
  32. package/src/hooks/migrate/useMigrate.tsx +110 -0
  33. package/src/hooks/migrate/useMigrationAllowance.tsx +79 -0
  34. package/src/hooks/migrate/useMigrationApprove.tsx +129 -0
  35. package/src/hooks/mm/index.ts +0 -1
  36. package/src/hooks/mm/useBorrow.ts +2 -2
  37. package/src/hooks/mm/useMMAllowance.ts +2 -1
  38. package/src/hooks/mm/useMMApprove.ts +2 -1
  39. package/src/hooks/mm/useRepay.ts +2 -2
  40. package/src/hooks/mm/useReservesData.ts +1 -8
  41. package/src/hooks/mm/useReservesHumanized.ts +30 -0
  42. package/src/hooks/mm/useReservesList.ts +29 -0
  43. package/src/hooks/mm/useReservesUsdFormat.ts +38 -0
  44. package/src/hooks/mm/useSupply.ts +2 -2
  45. package/src/hooks/mm/useUserFormattedSummary.ts +54 -0
  46. package/src/hooks/mm/useUserReservesData.ts +30 -37
  47. package/src/hooks/mm/useWithdraw.ts +2 -2
  48. package/src/hooks/provider/useHubProvider.ts +3 -3
  49. package/src/hooks/provider/useSpokeProvider.ts +50 -18
  50. package/src/hooks/shared/index.ts +4 -0
  51. package/src/hooks/shared/useDeriveUserWalletAddress.ts +44 -0
  52. package/src/hooks/shared/useEstimateGas.ts +18 -0
  53. package/src/hooks/shared/useRequestTrustline.ts +103 -0
  54. package/src/hooks/shared/useStellarTrustlineCheck.ts +71 -0
  55. package/src/hooks/staking/index.ts +19 -0
  56. package/src/hooks/staking/useCancelUnstake.ts +52 -0
  57. package/src/hooks/staking/useClaim.ts +46 -0
  58. package/src/hooks/staking/useConvertedAssets.ts +47 -0
  59. package/src/hooks/staking/useInstantUnstake.ts +50 -0
  60. package/src/hooks/staking/useInstantUnstakeAllowance.ts +59 -0
  61. package/src/hooks/staking/useInstantUnstakeApprove.ts +52 -0
  62. package/src/hooks/staking/useInstantUnstakeRatio.ts +54 -0
  63. package/src/hooks/staking/useStake.ts +47 -0
  64. package/src/hooks/staking/useStakeAllowance.ts +57 -0
  65. package/src/hooks/staking/useStakeApprove.ts +50 -0
  66. package/src/hooks/staking/useStakeRatio.ts +53 -0
  67. package/src/hooks/staking/useStakingConfig.ts +40 -0
  68. package/src/hooks/staking/useStakingInfo.ts +50 -0
  69. package/src/hooks/staking/useUnstake.ts +54 -0
  70. package/src/hooks/staking/useUnstakeAllowance.ts +58 -0
  71. package/src/hooks/staking/useUnstakeApprove.ts +52 -0
  72. package/src/hooks/staking/useUnstakingInfo.ts +53 -0
  73. package/src/hooks/staking/useUnstakingInfoWithPenalty.ts +59 -0
  74. package/src/hooks/swap/index.ts +2 -1
  75. package/src/hooks/swap/useCancelSwap.ts +44 -0
  76. package/src/hooks/swap/useQuote.ts +21 -7
  77. package/src/hooks/swap/useStatus.ts +4 -4
  78. package/src/hooks/swap/{useCreateIntentOrder.ts → useSwap.ts} +19 -14
  79. package/src/hooks/swap/useSwapAllowance.ts +5 -1
  80. package/src/hooks/swap/useSwapApprove.ts +14 -14
  81. package/src/providers/SodaxProvider.tsx +8 -20
  82. package/dist/contexts/index.d.ts +0 -8
  83. package/dist/contexts/index.d.ts.map +0 -1
  84. package/dist/core/index.d.ts +0 -4
  85. package/dist/core/index.d.ts.map +0 -1
  86. package/dist/hooks/index.d.ts +0 -5
  87. package/dist/hooks/index.d.ts.map +0 -1
  88. package/dist/hooks/mm/index.d.ts +0 -10
  89. package/dist/hooks/mm/index.d.ts.map +0 -1
  90. package/dist/hooks/mm/useBorrow.d.ts +0 -35
  91. package/dist/hooks/mm/useBorrow.d.ts.map +0 -1
  92. package/dist/hooks/mm/useHubWalletAddress.d.ts +0 -24
  93. package/dist/hooks/mm/useHubWalletAddress.d.ts.map +0 -1
  94. package/dist/hooks/mm/useMMAllowance.d.ts +0 -26
  95. package/dist/hooks/mm/useMMAllowance.d.ts.map +0 -1
  96. package/dist/hooks/mm/useMMApprove.d.ts +0 -27
  97. package/dist/hooks/mm/useMMApprove.d.ts.map +0 -1
  98. package/dist/hooks/mm/useRepay.d.ts +0 -35
  99. package/dist/hooks/mm/useRepay.d.ts.map +0 -1
  100. package/dist/hooks/mm/useReservesData.d.ts +0 -19
  101. package/dist/hooks/mm/useReservesData.d.ts.map +0 -1
  102. package/dist/hooks/mm/useSupply.d.ts +0 -34
  103. package/dist/hooks/mm/useSupply.d.ts.map +0 -1
  104. package/dist/hooks/mm/useUserReservesData.d.ts +0 -9
  105. package/dist/hooks/mm/useUserReservesData.d.ts.map +0 -1
  106. package/dist/hooks/mm/useWithdraw.d.ts +0 -33
  107. package/dist/hooks/mm/useWithdraw.d.ts.map +0 -1
  108. package/dist/hooks/provider/index.d.ts +0 -3
  109. package/dist/hooks/provider/index.d.ts.map +0 -1
  110. package/dist/hooks/provider/useHubProvider.d.ts +0 -3
  111. package/dist/hooks/provider/useHubProvider.d.ts.map +0 -1
  112. package/dist/hooks/provider/useSpokeProvider.d.ts +0 -18
  113. package/dist/hooks/provider/useSpokeProvider.d.ts.map +0 -1
  114. package/dist/hooks/shared/index.d.ts +0 -2
  115. package/dist/hooks/shared/index.d.ts.map +0 -1
  116. package/dist/hooks/shared/useSodaxContext.d.ts +0 -8
  117. package/dist/hooks/shared/useSodaxContext.d.ts.map +0 -1
  118. package/dist/hooks/swap/index.d.ts +0 -6
  119. package/dist/hooks/swap/index.d.ts.map +0 -1
  120. package/dist/hooks/swap/useCreateIntentOrder.d.ts +0 -33
  121. package/dist/hooks/swap/useCreateIntentOrder.d.ts.map +0 -1
  122. package/dist/hooks/swap/useQuote.d.ts +0 -39
  123. package/dist/hooks/swap/useQuote.d.ts.map +0 -1
  124. package/dist/hooks/swap/useStatus.d.ts +0 -31
  125. package/dist/hooks/swap/useStatus.d.ts.map +0 -1
  126. package/dist/hooks/swap/useSwapAllowance.d.ts +0 -23
  127. package/dist/hooks/swap/useSwapAllowance.d.ts.map +0 -1
  128. package/dist/hooks/swap/useSwapApprove.d.ts +0 -26
  129. package/dist/hooks/swap/useSwapApprove.d.ts.map +0 -1
  130. package/dist/index.d.ts.map +0 -1
  131. package/dist/providers/SodaxProvider.d.ts +0 -10
  132. package/dist/providers/SodaxProvider.d.ts.map +0 -1
  133. package/dist/providers/index.d.ts +0 -2
  134. package/dist/providers/index.d.ts.map +0 -1
  135. package/src/hooks/mm/useHubWalletAddress.ts +0 -49
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import React, { createContext, useContext, useMemo } from 'react';
2
- import { hubAssets, EvmSpokeProvider, spokeChainConfig, SuiSpokeProvider, IconSpokeProvider, CWSpokeProvider, StellarSpokeProvider, encodeAddress, EvmWalletAbstraction, getMoneyMarketConfig, Sodax, getHubChainConfig, EvmHubProvider } from '@sodax/sdk';
3
- import { getXChainType, useWalletProvider } from '@sodax/wallet-sdk';
1
+ import React, { createContext, useContext, useState, useCallback, useMemo, useRef, useEffect } from 'react';
2
+ import { SpokeService, deriveUserWalletAddress, STELLAR_MAINNET_CHAIN_ID, StellarSpokeProvider, StellarSpokeService, spokeChainConfig, SONIC_MAINNET_CHAIN_ID, SonicSpokeProvider, EvmSpokeProvider, SuiSpokeProvider, IconSpokeProvider, InjectiveSpokeProvider, SolanaSpokeProvider, isLegacybnUSDToken, Sodax, hubAssets } from '@sodax/sdk';
4
3
  import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
5
4
  import { parseUnits } from 'viem';
5
+ import { ICON_MAINNET_CHAIN_ID } from '@sodax/types';
6
6
 
7
7
  // src/contexts/index.ts
8
8
  var SodaxContext = createContext(null);
@@ -13,54 +13,165 @@ var useSodaxContext = () => {
13
13
  }
14
14
  return context;
15
15
  };
16
+ function useEstimateGas(spokeProvider) {
17
+ return useMutation({
18
+ mutationFn: async (rawTx) => {
19
+ if (!spokeProvider) {
20
+ throw new Error("spokeProvider is not found");
21
+ }
22
+ const response = await SpokeService.estimateGas(rawTx, spokeProvider);
23
+ return response;
24
+ }
25
+ });
26
+ }
27
+ function useDeriveUserWalletAddress(spokeProvider, walletAddress) {
28
+ const { sodax } = useSodaxContext();
29
+ return useQuery({
30
+ queryKey: ["deriveUserWalletAddress", spokeProvider?.chainConfig.chain.id, walletAddress],
31
+ queryFn: async () => {
32
+ if (!spokeProvider) {
33
+ throw new Error("Spoke provider is required");
34
+ }
35
+ return await deriveUserWalletAddress(spokeProvider, sodax.hubProvider, walletAddress);
36
+ },
37
+ enabled: !!spokeProvider,
38
+ refetchInterval: false
39
+ // This is a deterministic operation, no need to refetch
40
+ });
41
+ }
42
+ function useStellarTrustlineCheck(token, amount, spokeProvider, chainId) {
43
+ return useQuery({
44
+ queryKey: ["stellar-trustline-check", token],
45
+ queryFn: async () => {
46
+ if (chainId !== STELLAR_MAINNET_CHAIN_ID) {
47
+ return true;
48
+ }
49
+ if (!spokeProvider || !token || !amount || !(spokeProvider instanceof StellarSpokeProvider)) {
50
+ console.error(
51
+ "Spoke provider, token or amount not found. Details: spokeProvider:",
52
+ spokeProvider,
53
+ "token:",
54
+ token,
55
+ "amount:",
56
+ amount
57
+ );
58
+ return false;
59
+ }
60
+ const response = await StellarSpokeService.hasSufficientTrustline(token, amount, spokeProvider);
61
+ return response;
62
+ },
63
+ enabled: !!spokeProvider && !!token && !!amount
64
+ });
65
+ }
66
+ function useRequestTrustline(token) {
67
+ const queryClient = useQueryClient();
68
+ const [isLoading, setIsLoading] = useState(false);
69
+ const [isRequested, setIsRequested] = useState(false);
70
+ const [error, setError] = useState(null);
71
+ const [data, setData] = useState(null);
72
+ const requestTrustline = useCallback(
73
+ async ({
74
+ token: token2,
75
+ amount,
76
+ spokeProvider
77
+ }) => {
78
+ if (!spokeProvider || !token2 || !amount || !(spokeProvider instanceof StellarSpokeProvider)) {
79
+ const error2 = new Error("Spoke provider, token or amount not found");
80
+ setError(error2);
81
+ throw error2;
82
+ }
83
+ setIsLoading(true);
84
+ setError(null);
85
+ try {
86
+ const result = await StellarSpokeService.requestTrustline(token2, amount, spokeProvider);
87
+ setData(result);
88
+ setIsRequested(true);
89
+ queryClient.invalidateQueries({ queryKey: ["stellar-trustline-check", token2] });
90
+ return result;
91
+ } catch (err) {
92
+ const error2 = err instanceof Error ? err : new Error("Unknown error occurred");
93
+ setError(error2);
94
+ throw error2;
95
+ } finally {
96
+ setIsLoading(false);
97
+ }
98
+ },
99
+ [queryClient]
100
+ );
101
+ return {
102
+ requestTrustline,
103
+ isLoading,
104
+ isRequested,
105
+ error,
106
+ data
107
+ };
108
+ }
16
109
 
17
110
  // src/hooks/provider/useHubProvider.ts
18
111
  function useHubProvider() {
19
- const { hubProvider } = useSodaxContext();
20
- return hubProvider;
112
+ const { sodax } = useSodaxContext();
113
+ return sodax.hubProvider;
21
114
  }
22
115
  function useSpokeProvider(spokeChainId, walletProvider) {
23
- const xChainType = getXChainType(spokeChainId);
24
- const walletProvider_ = useWalletProvider(spokeChainId);
25
- const _walletProvider = walletProvider ?? walletProvider_;
116
+ const { rpcConfig } = useSodaxContext();
117
+ const xChainType = spokeChainId ? spokeChainConfig[spokeChainId]?.chain.type : void 0;
26
118
  const spokeProvider = useMemo(() => {
27
- if (!_walletProvider) return void 0;
119
+ if (!walletProvider) return void 0;
28
120
  if (!spokeChainId) return void 0;
121
+ if (!xChainType) return void 0;
122
+ if (!rpcConfig) return void 0;
29
123
  if (xChainType === "EVM") {
124
+ if (spokeChainId === SONIC_MAINNET_CHAIN_ID) {
125
+ return new SonicSpokeProvider(
126
+ walletProvider,
127
+ spokeChainConfig[spokeChainId]
128
+ );
129
+ }
30
130
  return new EvmSpokeProvider(
31
- _walletProvider,
131
+ walletProvider,
32
132
  spokeChainConfig[spokeChainId]
33
133
  );
34
134
  }
35
135
  if (xChainType === "SUI") {
36
136
  return new SuiSpokeProvider(
37
137
  spokeChainConfig[spokeChainId],
38
- _walletProvider
138
+ walletProvider
39
139
  );
40
140
  }
41
141
  if (xChainType === "ICON") {
42
142
  return new IconSpokeProvider(
43
- _walletProvider,
143
+ walletProvider,
44
144
  spokeChainConfig[spokeChainId]
45
145
  );
46
146
  }
47
147
  if (xChainType === "INJECTIVE") {
48
- return new CWSpokeProvider(
148
+ return new InjectiveSpokeProvider(
49
149
  spokeChainConfig[spokeChainId],
50
- _walletProvider
150
+ walletProvider
51
151
  );
52
152
  }
53
153
  if (xChainType === "STELLAR") {
54
154
  const stellarConfig = spokeChainConfig[spokeChainId];
55
155
  return new StellarSpokeProvider(
56
- _walletProvider,
57
- stellarConfig.addresses.assetManager,
156
+ walletProvider,
58
157
  stellarConfig,
59
- stellarConfig.rpc_url
158
+ rpcConfig.stellar ? rpcConfig.stellar : {
159
+ horizonRpcUrl: stellarConfig.horizonRpcUrl,
160
+ sorobanRpcUrl: stellarConfig.sorobanRpcUrl
161
+ }
162
+ );
163
+ }
164
+ if (xChainType === "SOLANA") {
165
+ return new SolanaSpokeProvider(
166
+ walletProvider,
167
+ rpcConfig.solana ? {
168
+ ...spokeChainConfig[spokeChainId],
169
+ rpcUrl: rpcConfig.solana
170
+ } : spokeChainConfig[spokeChainId]
60
171
  );
61
172
  }
62
173
  return void 0;
63
- }, [spokeChainId, xChainType, _walletProvider]);
174
+ }, [spokeChainId, xChainType, walletProvider, rpcConfig]);
64
175
  return spokeProvider;
65
176
  }
66
177
  function useBorrow(spokeToken, spokeProvider) {
@@ -70,7 +181,7 @@ function useBorrow(spokeToken, spokeProvider) {
70
181
  if (!spokeProvider) {
71
182
  throw new Error("spokeProvider is not found");
72
183
  }
73
- const response = await sodax.moneyMarket.borrowAndSubmit(
184
+ const response = await sodax.moneyMarket.borrow(
74
185
  {
75
186
  token: spokeToken.address,
76
187
  amount: parseUnits(amount, 18),
@@ -93,7 +204,7 @@ function useRepay(spokeToken, spokeProvider) {
93
204
  if (!spokeProvider) {
94
205
  throw new Error("spokeProvider is not found");
95
206
  }
96
- const response = await sodax.moneyMarket.repayAndSubmit(
207
+ const response = await sodax.moneyMarket.repay(
97
208
  {
98
209
  token: spokeToken.address,
99
210
  amount: parseUnits(amount, spokeToken.decimals),
@@ -116,7 +227,7 @@ function useSupply(spokeToken, spokeProvider) {
116
227
  if (!spokeProvider) {
117
228
  throw new Error("spokeProvider is not found");
118
229
  }
119
- const response = await sodax.moneyMarket.supplyAndSubmit(
230
+ const response = await sodax.moneyMarket.supply(
120
231
  {
121
232
  token: spokeToken.address,
122
233
  amount: parseUnits(amount, spokeToken.decimals),
@@ -139,7 +250,7 @@ function useWithdraw(spokeToken, spokeProvider) {
139
250
  if (!spokeProvider) {
140
251
  throw new Error("spokeProvider is not found");
141
252
  }
142
- const response = await sodax.moneyMarket.withdrawAndSubmit(
253
+ const response = await sodax.moneyMarket.withdraw(
143
254
  {
144
255
  token: spokeToken.address,
145
256
  // vault token on hub chain decimals is 18
@@ -156,97 +267,26 @@ function useWithdraw(spokeToken, spokeProvider) {
156
267
  }
157
268
  });
158
269
  }
159
- var allXTokens = [];
160
- Object.keys(hubAssets).forEach((xChainId) => {
161
- const tokens = hubAssets[xChainId];
162
- Object.keys(tokens).forEach((tokenAddress) => {
163
- const token = tokens[tokenAddress];
164
- allXTokens.push({
165
- xChainId,
166
- symbol: token.symbol,
167
- name: token.name,
168
- decimals: token.decimal,
169
- address: tokenAddress
170
- });
171
- allXTokens.push({
172
- xChainId: "sonic",
173
- symbol: token.symbol,
174
- name: token.name,
175
- decimals: token.decimal,
176
- address: token.vault
177
- });
178
- });
179
- });
180
- var getSpokeTokenAddressByVault = (spokeChainId, vault) => {
181
- const tokens = hubAssets[spokeChainId];
182
- const address = Object.keys(tokens).find((tokenAddress) => tokens[tokenAddress].vault === vault);
183
- return address;
184
- };
185
- function useUserReservesData(spokeChainId, address) {
270
+ function useUserReservesData(spokeProvider, address, refetchInterval = 5e3) {
186
271
  const { sodax } = useSodaxContext();
187
- const hubChainId = sodax.config?.hubProviderConfig?.chainConfig.chain.id ?? "sonic";
188
- const hubProvider = useHubProvider();
189
- const { data: userReserves } = useQuery({
190
- queryKey: ["userReserves", spokeChainId, address],
191
- queryFn: async () => {
192
- if (!hubProvider || !address) {
193
- return;
194
- }
195
- const addressBytes = encodeAddress(spokeChainId, address);
196
- const hubWalletAddress = await EvmWalletAbstraction.getUserHubWalletAddress(
197
- spokeChainId,
198
- addressBytes,
199
- hubProvider
200
- );
201
- const moneyMarketConfig = getMoneyMarketConfig(hubChainId);
202
- const [res] = await sodax.moneyMarket.getUserReservesData(
203
- hubWalletAddress,
204
- moneyMarketConfig.uiPoolDataProvider,
205
- moneyMarketConfig.poolAddressesProvider
206
- );
207
- return res?.map((r) => {
208
- return {
209
- ...r,
210
- token: allXTokens.find((t) => t.address === r.underlyingAsset)
211
- };
212
- });
213
- },
214
- enabled: !!spokeChainId && !!hubProvider && !!address,
215
- refetchInterval: 5e3
216
- });
217
- return userReserves;
218
- }
219
- function useHubWalletAddress(spokeChainId, address, hubProvider) {
220
272
  return useQuery({
221
- queryKey: ["hubWallet", spokeChainId, address],
273
+ queryKey: ["userReserves", spokeProvider?.chainConfig.chain.id, address],
222
274
  queryFn: async () => {
223
- if (!address) return null;
224
- try {
225
- const hubWalletAddress = await EvmWalletAbstraction.getUserHubWalletAddress(
226
- spokeChainId,
227
- address,
228
- hubProvider
229
- );
230
- return hubWalletAddress;
231
- } catch (error) {
232
- console.log("error", error);
233
- return null;
275
+ if (!spokeProvider) {
276
+ throw new Error("Spoke provider or address is not defined");
234
277
  }
278
+ return await sodax.moneyMarket.data.getUserReservesData(spokeProvider);
235
279
  },
236
- enabled: !!address && !!hubProvider
280
+ enabled: !!spokeProvider && !!address,
281
+ refetchInterval
237
282
  });
238
283
  }
239
284
  function useReservesData() {
240
285
  const { sodax } = useSodaxContext();
241
- const hubChainId = sodax.config?.hubProviderConfig?.chainConfig.chain.id ?? "sonic";
242
286
  return useQuery({
243
287
  queryKey: ["reservesData"],
244
288
  queryFn: async () => {
245
- const moneyMarketConfig = getMoneyMarketConfig(hubChainId);
246
- return await sodax.moneyMarket.getReservesData(
247
- moneyMarketConfig.uiPoolDataProvider,
248
- moneyMarketConfig.poolAddressesProvider
249
- );
289
+ return await sodax.moneyMarket.data.getReservesData();
250
290
  }
251
291
  });
252
292
  }
@@ -256,10 +296,11 @@ function useMMAllowance(token, amount, action, spokeProvider) {
256
296
  queryKey: ["allowance", token.address, amount, action],
257
297
  queryFn: async () => {
258
298
  if (!spokeProvider) throw new Error("Spoke provider is required");
299
+ const actionBasedDecimals = action === "withdraw" || action === "borrow" ? 18 : token.decimals;
259
300
  const allowance = await sodax.moneyMarket.isAllowanceValid(
260
301
  {
261
302
  token: token.address,
262
- amount: parseUnits(amount, token.decimals),
303
+ amount: parseUnits(amount, actionBasedDecimals),
263
304
  action
264
305
  },
265
306
  spokeProvider
@@ -285,10 +326,11 @@ function useMMApprove(token, spokeProvider) {
285
326
  if (!spokeProvider) {
286
327
  throw new Error("Spoke provider not found");
287
328
  }
329
+ const actionBasedDecimals = action === "withdraw" || action === "borrow" ? 18 : token.decimals;
288
330
  const allowance = await sodax.moneyMarket.approve(
289
331
  {
290
332
  token: token.address,
291
- amount: parseUnits(amount, token.decimals),
333
+ amount: parseUnits(amount, actionBasedDecimals),
292
334
  action
293
335
  },
294
336
  spokeProvider
@@ -311,26 +353,43 @@ function useMMApprove(token, spokeProvider) {
311
353
  }
312
354
  var useQuote = (payload) => {
313
355
  const { sodax } = useSodaxContext();
356
+ const queryKey = useMemo(() => {
357
+ if (!payload) return ["quote", void 0];
358
+ return [
359
+ "quote",
360
+ {
361
+ ...payload,
362
+ amount: payload.amount.toString()
363
+ }
364
+ ];
365
+ }, [payload]);
314
366
  return useQuery({
315
- queryKey: [payload],
367
+ queryKey,
316
368
  queryFn: async () => {
317
369
  if (!payload) {
318
370
  return void 0;
319
371
  }
320
- return sodax.solver.getQuote(payload);
372
+ return sodax.swap.getQuote(payload);
321
373
  },
322
374
  enabled: !!payload,
323
375
  refetchInterval: 3e3
324
376
  });
325
377
  };
326
- function useCreateIntentOrder(spokeProvider) {
378
+ function useSwap(spokeProvider) {
327
379
  const { sodax } = useSodaxContext();
380
+ const queryClient = useQueryClient();
328
381
  return useMutation({
329
382
  mutationFn: async (params) => {
330
383
  if (!spokeProvider) {
331
384
  throw new Error("Spoke provider not found");
332
385
  }
333
- return sodax.solver.createAndSubmitIntent(params, spokeProvider);
386
+ return sodax.swap.swap({
387
+ intentParams: params,
388
+ spokeProvider
389
+ });
390
+ },
391
+ onSuccess: () => {
392
+ queryClient.invalidateQueries({ queryKey: ["xBalances"] });
334
393
  }
335
394
  });
336
395
  }
@@ -339,7 +398,7 @@ var useStatus = (intent_tx_hash) => {
339
398
  return useQuery({
340
399
  queryKey: [intent_tx_hash],
341
400
  queryFn: async () => {
342
- return sodax.solver.getStatus({ intent_tx_hash });
401
+ return sodax.swap.getStatus({ intent_tx_hash });
343
402
  },
344
403
  refetchInterval: 3e3
345
404
  // 3s
@@ -353,16 +412,20 @@ function useSwapAllowance(params, spokeProvider) {
353
412
  if (!spokeProvider || !params) {
354
413
  return false;
355
414
  }
356
- const allowance = await sodax.solver.isAllowanceValid(params, spokeProvider);
415
+ const allowance = await sodax.swap.isAllowanceValid({
416
+ intentParams: params,
417
+ spokeProvider
418
+ });
357
419
  if (allowance.ok) {
358
420
  return allowance.value;
359
421
  }
360
422
  return false;
361
423
  },
362
- enabled: !!spokeProvider && !!params
424
+ enabled: !!spokeProvider && !!params,
425
+ refetchInterval: 2e3
363
426
  });
364
427
  }
365
- function useSwapApprove(token, spokeProvider) {
428
+ function useSwapApprove(params, spokeProvider) {
366
429
  const { sodax } = useSodaxContext();
367
430
  const queryClient = useQueryClient();
368
431
  const {
@@ -371,25 +434,24 @@ function useSwapApprove(token, spokeProvider) {
371
434
  error,
372
435
  reset: resetError
373
436
  } = useMutation({
374
- mutationFn: async ({ amount }) => {
437
+ mutationFn: async ({ params: params2 }) => {
375
438
  if (!spokeProvider) {
376
439
  throw new Error("Spoke provider not found");
377
440
  }
378
- if (!token) {
379
- throw new Error("Token not found");
441
+ if (!params2) {
442
+ throw new Error("Swap Params not found");
380
443
  }
381
- const allowance = await sodax.solver.approve(
382
- token.address,
383
- parseUnits(amount, token.decimals),
444
+ const allowance = await sodax.swap.approve({
445
+ intentParams: params2,
384
446
  spokeProvider
385
- );
447
+ });
386
448
  if (!allowance.ok) {
387
- throw new Error("Failed to approve tokens");
449
+ throw new Error("Failed to approve input token");
388
450
  }
389
451
  return allowance.ok;
390
452
  },
391
453
  onSuccess: () => {
392
- queryClient.invalidateQueries({ queryKey: ["allowance", token?.address] });
454
+ queryClient.invalidateQueries({ queryKey: ["allowance", params] });
393
455
  }
394
456
  });
395
457
  return {
@@ -399,23 +461,794 @@ function useSwapApprove(token, spokeProvider) {
399
461
  resetError
400
462
  };
401
463
  }
402
- var SodaxProvider = ({ children, testnet = false, config }) => {
403
- const sodax = new Sodax(config);
404
- const hubChainId = config?.hubProviderConfig?.chainConfig.chain.id;
405
- const hubRpcUrl = config?.hubProviderConfig?.hubRpcUrl;
406
- const hubProvider = useMemo(() => {
407
- if (hubChainId && hubRpcUrl) {
408
- const hubChainCfg = getHubChainConfig(hubChainId);
409
- return new EvmHubProvider({
410
- hubRpcUrl,
411
- chainConfig: hubChainCfg
464
+ function useCancelSwap(spokeProvider) {
465
+ const { sodax } = useSodaxContext();
466
+ return useMutation({
467
+ mutationFn: async ({ intent, raw = false }) => {
468
+ if (!spokeProvider) {
469
+ throw new Error("Spoke provider not found");
470
+ }
471
+ return sodax.swap.cancelIntent(intent, spokeProvider, raw);
472
+ }
473
+ });
474
+ }
475
+ var useBackendIntentByTxHash = (txHash) => {
476
+ const { sodax } = useSodaxContext();
477
+ return useQuery({
478
+ queryKey: ["backend", "intent", "txHash", txHash],
479
+ queryFn: async () => {
480
+ if (!txHash) {
481
+ return void 0;
482
+ }
483
+ return sodax.backendApi.getIntentByTxHash(txHash);
484
+ },
485
+ enabled: !!txHash && txHash.length > 0,
486
+ retry: 3
487
+ });
488
+ };
489
+ var useBackendIntentByHash = (intentHash) => {
490
+ const { sodax } = useSodaxContext();
491
+ return useQuery({
492
+ queryKey: ["backend", "intent", "hash", intentHash],
493
+ queryFn: async () => {
494
+ if (!intentHash) {
495
+ return void 0;
496
+ }
497
+ return sodax.backendApi.getIntentByHash(intentHash);
498
+ },
499
+ enabled: !!intentHash && intentHash.length > 0,
500
+ retry: 3
501
+ });
502
+ };
503
+ var useBackendOrderbook = (params) => {
504
+ const { sodax } = useSodaxContext();
505
+ return useQuery({
506
+ queryKey: ["backend", "solver", "orderbook", params],
507
+ queryFn: async () => {
508
+ if (!params || !params.offset || !params.limit) {
509
+ return void 0;
510
+ }
511
+ return sodax.backendApi.getOrderbook(params);
512
+ },
513
+ enabled: !!params && !!params.offset && !!params.limit,
514
+ staleTime: 30 * 1e3,
515
+ // 30 seconds for real-time data
516
+ retry: 3
517
+ });
518
+ };
519
+ var useBackendMoneyMarketPosition = (userAddress) => {
520
+ const { sodax } = useSodaxContext();
521
+ return useQuery({
522
+ queryKey: ["backend", "moneymarket", "position", userAddress],
523
+ queryFn: async () => {
524
+ if (!userAddress) {
525
+ return void 0;
526
+ }
527
+ return sodax.backendApi.getMoneyMarketPosition(userAddress);
528
+ },
529
+ enabled: !!userAddress && userAddress.length > 0,
530
+ retry: 3
531
+ });
532
+ };
533
+ var useBackendAllMoneyMarketAssets = () => {
534
+ const { sodax } = useSodaxContext();
535
+ return useQuery({
536
+ queryKey: ["backend", "moneymarket", "assets", "all"],
537
+ queryFn: async () => {
538
+ return sodax.backendApi.getAllMoneyMarketAssets();
539
+ },
540
+ retry: 3
541
+ });
542
+ };
543
+ var useBackendMoneyMarketAsset = (reserveAddress) => {
544
+ const { sodax } = useSodaxContext();
545
+ return useQuery({
546
+ queryKey: ["backend", "moneymarket", "asset", reserveAddress],
547
+ queryFn: async () => {
548
+ if (!reserveAddress) {
549
+ return void 0;
550
+ }
551
+ return sodax.backendApi.getMoneyMarketAsset(reserveAddress);
552
+ },
553
+ enabled: !!reserveAddress && reserveAddress.length > 0,
554
+ retry: 3
555
+ });
556
+ };
557
+ var useBackendMoneyMarketAssetBorrowers = (params) => {
558
+ const { sodax } = useSodaxContext();
559
+ return useQuery({
560
+ queryKey: ["backend", "moneymarket", "asset", "borrowers", params],
561
+ queryFn: async () => {
562
+ if (!params.reserveAddress || !params.offset || !params.limit) {
563
+ return void 0;
564
+ }
565
+ return sodax.backendApi.getMoneyMarketAssetBorrowers(params.reserveAddress, {
566
+ offset: params.offset,
567
+ limit: params.limit
568
+ });
569
+ },
570
+ enabled: !!params.reserveAddress && !!params.offset && !!params.limit,
571
+ retry: 3
572
+ });
573
+ };
574
+ var useBackendMoneyMarketAssetSuppliers = (params) => {
575
+ const { sodax } = useSodaxContext();
576
+ return useQuery({
577
+ queryKey: ["backend", "moneymarket", "asset", "suppliers", params],
578
+ queryFn: async () => {
579
+ if (!params.reserveAddress || !params.offset || !params.limit) {
580
+ return void 0;
581
+ }
582
+ return sodax.backendApi.getMoneyMarketAssetSuppliers(params.reserveAddress, {
583
+ offset: params.offset,
584
+ limit: params.limit
585
+ });
586
+ },
587
+ enabled: !!params.reserveAddress && !!params.offset && !!params.limit,
588
+ retry: 3
589
+ });
590
+ };
591
+ var useBackendAllMoneyMarketBorrowers = (params) => {
592
+ const { sodax } = useSodaxContext();
593
+ return useQuery({
594
+ queryKey: ["backend", "moneymarket", "borrowers", "all", params],
595
+ queryFn: async () => {
596
+ if (!params || !params.offset || !params.limit) {
597
+ return void 0;
598
+ }
599
+ return sodax.backendApi.getAllMoneyMarketBorrowers(params);
600
+ },
601
+ enabled: !!params && !!params.offset && !!params.limit,
602
+ retry: 3
603
+ });
604
+ };
605
+ function useBridgeAllowance(params, spokeProvider) {
606
+ const { sodax } = useSodaxContext();
607
+ return useQuery({
608
+ queryKey: ["bridge-allowance", params],
609
+ queryFn: async () => {
610
+ if (!spokeProvider || !params) {
611
+ return false;
612
+ }
613
+ const allowance = await sodax.bridge.isAllowanceValid({
614
+ params,
615
+ spokeProvider
616
+ });
617
+ if (allowance.ok) {
618
+ return allowance.value;
619
+ }
620
+ return false;
621
+ },
622
+ enabled: !!spokeProvider && !!params
623
+ });
624
+ }
625
+ function useBridgeApprove(spokeProvider) {
626
+ const { sodax } = useSodaxContext();
627
+ const queryClient = useQueryClient();
628
+ const {
629
+ mutateAsync: approve,
630
+ isPending,
631
+ error,
632
+ reset: resetError
633
+ } = useMutation({
634
+ mutationFn: async (params) => {
635
+ if (!spokeProvider) {
636
+ throw new Error("Spoke provider not found");
637
+ }
638
+ const allowance = await sodax.bridge.approve({
639
+ params,
640
+ spokeProvider
412
641
  });
642
+ if (!allowance.ok) {
643
+ throw new Error("Failed to approve tokens for bridge");
644
+ }
645
+ return true;
646
+ },
647
+ onSuccess: (_, params) => {
648
+ queryClient.invalidateQueries({ queryKey: ["bridge-allowance", params] });
413
649
  }
414
- return void 0;
415
- }, [hubChainId, hubRpcUrl]);
416
- return /* @__PURE__ */ React.createElement(SodaxContext.Provider, { value: { sodax, testnet, hubProvider } }, children);
650
+ });
651
+ return {
652
+ approve,
653
+ isLoading: isPending,
654
+ error,
655
+ resetError
656
+ };
657
+ }
658
+ function useBridge(spokeProvider) {
659
+ const { sodax } = useSodaxContext();
660
+ return useMutation({
661
+ mutationFn: async (params) => {
662
+ if (!spokeProvider) {
663
+ throw new Error("Spoke provider not found");
664
+ }
665
+ const result = await sodax.bridge.bridge({
666
+ params,
667
+ spokeProvider
668
+ });
669
+ if (!result.ok) {
670
+ throw new Error(`Bridge failed: ${result.error.code}`);
671
+ }
672
+ return result;
673
+ }
674
+ });
675
+ }
676
+ function useGetBridgeableAmount(from, to) {
677
+ const { sodax } = useSodaxContext();
678
+ return useQuery({
679
+ queryKey: ["spoke-asset-manager-token-balance", from, to],
680
+ queryFn: async () => {
681
+ if (!from || !to) {
682
+ return 0n;
683
+ }
684
+ const result = await sodax.bridge.getBridgeableAmount(from, to);
685
+ if (result.ok) {
686
+ return result.value;
687
+ }
688
+ console.error("Error getting bridgeable amount:", result.error);
689
+ return 0n;
690
+ },
691
+ enabled: !!from && !!to
692
+ });
693
+ }
694
+ function useGetBridgeableTokens(from, to, token) {
695
+ const { sodax } = useSodaxContext();
696
+ return useQuery({
697
+ queryKey: ["bridgeable-tokens", from, to, token],
698
+ queryFn: async () => {
699
+ if (!from || !to || !token) {
700
+ return [];
701
+ }
702
+ const result = sodax.bridge.getBridgeableTokens(from, to, token);
703
+ if (result.ok) {
704
+ return result.value;
705
+ }
706
+ console.error("Error getting bridgeable tokens:", result.error);
707
+ return [];
708
+ },
709
+ enabled: !!from && !!to && !!token
710
+ });
711
+ }
712
+ function useStake(spokeProvider) {
713
+ const { sodax } = useSodaxContext();
714
+ return useMutation({
715
+ mutationFn: async (params) => {
716
+ if (!spokeProvider) {
717
+ throw new Error("Spoke provider not found");
718
+ }
719
+ const result = await sodax.staking.stake(params, spokeProvider);
720
+ if (!result.ok) {
721
+ throw new Error(`Stake failed: ${result.error.code}`);
722
+ }
723
+ return result.value;
724
+ }
725
+ });
726
+ }
727
+ function useStakeApprove(spokeProvider) {
728
+ const { sodax } = useSodaxContext();
729
+ return useMutation({
730
+ mutationFn: async (params) => {
731
+ if (!spokeProvider) {
732
+ throw new Error("Spoke provider not found");
733
+ }
734
+ const result = await sodax.staking.approve({
735
+ params: { ...params, action: "stake" },
736
+ spokeProvider
737
+ });
738
+ if (!result.ok) {
739
+ throw new Error(`Stake approval failed: ${result.error.code}`);
740
+ }
741
+ return result.value;
742
+ }
743
+ });
744
+ }
745
+ function useStakeAllowance(params, spokeProvider) {
746
+ const { sodax } = useSodaxContext();
747
+ return useQuery({
748
+ queryKey: ["soda", "stakeAllowance", params, spokeProvider?.chainConfig.chain.id],
749
+ queryFn: async () => {
750
+ if (!params || !spokeProvider) {
751
+ return false;
752
+ }
753
+ const result = await sodax.staking.isAllowanceValid({
754
+ params: { ...params, action: "stake" },
755
+ spokeProvider
756
+ });
757
+ if (!result.ok) {
758
+ throw new Error(`Allowance check failed: ${result.error.code}`);
759
+ }
760
+ return result.value;
761
+ },
762
+ enabled: !!params && !!spokeProvider,
763
+ refetchInterval: 5e3
764
+ // Refetch every 5 seconds
765
+ });
766
+ }
767
+ function useUnstake(spokeProvider) {
768
+ const { sodax } = useSodaxContext();
769
+ const queryClient = useQueryClient();
770
+ return useMutation({
771
+ mutationFn: async (params) => {
772
+ if (!spokeProvider) {
773
+ throw new Error("Spoke provider not found");
774
+ }
775
+ const result = await sodax.staking.unstake({ ...params, action: "unstake" }, spokeProvider);
776
+ if (!result.ok) {
777
+ throw new Error(`Unstake failed: ${result.error.code}`);
778
+ }
779
+ return result.value;
780
+ },
781
+ onSuccess: () => {
782
+ queryClient.invalidateQueries({ queryKey: ["stakingInfo"] });
783
+ queryClient.invalidateQueries({ queryKey: ["unstakingInfo"] });
784
+ queryClient.invalidateQueries({ queryKey: ["unstakingInfoWithPenalty"] });
785
+ }
786
+ });
787
+ }
788
+ function useClaim(spokeProvider) {
789
+ const { sodax } = useSodaxContext();
790
+ return useMutation({
791
+ mutationFn: async (params) => {
792
+ if (!spokeProvider) {
793
+ throw new Error("Spoke provider not found");
794
+ }
795
+ const result = await sodax.staking.claim({ ...params, action: "claim" }, spokeProvider);
796
+ if (!result.ok) {
797
+ throw new Error(`Claim failed: ${result.error.code}`);
798
+ }
799
+ return result.value;
800
+ }
801
+ });
802
+ }
803
+ function useCancelUnstake(spokeProvider) {
804
+ const { sodax } = useSodaxContext();
805
+ const queryClient = useQueryClient();
806
+ return useMutation({
807
+ mutationFn: async (params) => {
808
+ if (!spokeProvider) {
809
+ throw new Error("Spoke provider not available");
810
+ }
811
+ const result = await sodax.staking.cancelUnstake({ ...params, action: "cancelUnstake" }, spokeProvider);
812
+ if (!result.ok) {
813
+ throw new Error(`Cancel unstake failed: ${result.error.code}`);
814
+ }
815
+ return result.value;
816
+ },
817
+ onSuccess: () => {
818
+ queryClient.invalidateQueries({ queryKey: ["stakingInfo"] });
819
+ queryClient.invalidateQueries({ queryKey: ["unstakingInfo"] });
820
+ queryClient.invalidateQueries({ queryKey: ["unstakingInfoWithPenalty"] });
821
+ }
822
+ });
823
+ }
824
+ function useStakingInfo(spokeProvider, refetchInterval = 5e3) {
825
+ const { sodax } = useSodaxContext();
826
+ return useQuery({
827
+ queryKey: ["soda", "stakingInfo", spokeProvider?.chainConfig.chain.id],
828
+ queryFn: async () => {
829
+ if (!spokeProvider) {
830
+ throw new Error("Spoke provider not found");
831
+ }
832
+ const result = await sodax.staking.getStakingInfoFromSpoke(spokeProvider);
833
+ if (!result.ok) {
834
+ throw new Error(`Failed to fetch staking info: ${result.error.code}`);
835
+ }
836
+ return result.value;
837
+ },
838
+ enabled: !!spokeProvider,
839
+ refetchInterval
840
+ });
841
+ }
842
+ function useUnstakingInfoWithPenalty(userAddress, spokeProvider, refetchInterval = 5e3) {
843
+ const { sodax } = useSodaxContext();
844
+ return useQuery({
845
+ queryKey: ["soda", "unstakingInfoWithPenalty", spokeProvider?.chainConfig.chain.id, userAddress],
846
+ queryFn: async () => {
847
+ if (!spokeProvider) {
848
+ throw new Error("Spoke provider not found");
849
+ }
850
+ const penaltyResult = await sodax.staking.getUnstakingInfoWithPenalty(spokeProvider);
851
+ if (!penaltyResult.ok) {
852
+ throw new Error(`Failed to fetch unstaking info with penalty: ${penaltyResult.error.code}`);
853
+ }
854
+ return penaltyResult.value;
855
+ },
856
+ enabled: !!spokeProvider && !!userAddress,
857
+ refetchInterval
858
+ });
859
+ }
860
+ function useStakingConfig(refetchInterval = 3e4) {
861
+ const { sodax } = useSodaxContext();
862
+ return useQuery({
863
+ queryKey: ["soda", "stakingConfig"],
864
+ queryFn: async () => {
865
+ const result = await sodax.staking.getStakingConfig();
866
+ if (!result.ok) {
867
+ throw new Error(`Failed to fetch staking config: ${result.error.code}`);
868
+ }
869
+ return result.value;
870
+ },
871
+ refetchInterval
872
+ });
873
+ }
874
+ function useStakeRatio(amount, refetchInterval = 1e4) {
875
+ const { sodax } = useSodaxContext();
876
+ return useQuery({
877
+ queryKey: ["soda", "stakeRatio", amount?.toString()],
878
+ queryFn: async () => {
879
+ if (!amount || amount <= 0n) {
880
+ throw new Error("Amount must be greater than 0");
881
+ }
882
+ if (!sodax?.staking) {
883
+ throw new Error("Staking service not available");
884
+ }
885
+ const result = await sodax.staking.getStakeRatio(amount);
886
+ if (!result.ok) {
887
+ throw new Error(`Failed to fetch stake ratio: ${result.error.code}`);
888
+ }
889
+ return result.value;
890
+ },
891
+ enabled: !!amount && amount > 0n && !!sodax?.staking,
892
+ refetchInterval
893
+ });
894
+ }
895
+ function useInstantUnstakeRatio(amount, refetchInterval = 1e4) {
896
+ const { sodax } = useSodaxContext();
897
+ console.log("useInstantUnstakeRatio hook called with:", { amount: amount?.toString(), sodax: !!sodax });
898
+ return useQuery({
899
+ queryKey: ["soda", "instantUnstakeRatio", amount?.toString()],
900
+ queryFn: async () => {
901
+ console.log("useInstantUnstakeRatio queryFn called with amount:", amount?.toString());
902
+ if (!amount || amount <= 0n) {
903
+ throw new Error("Amount must be greater than 0");
904
+ }
905
+ if (!sodax?.staking) {
906
+ throw new Error("Staking service not available");
907
+ }
908
+ const result = await sodax.staking.getInstantUnstakeRatio(amount);
909
+ if (!result.ok) {
910
+ throw new Error(`Failed to fetch instant unstake ratio: ${result.error.code}`);
911
+ }
912
+ return result.value;
913
+ },
914
+ enabled: !!amount && amount > 0n && !!sodax?.staking,
915
+ refetchInterval
916
+ });
917
+ }
918
+ function useConvertedAssets(amount, refetchInterval = 1e4) {
919
+ const { sodax } = useSodaxContext();
920
+ console.log("useConvertedAssets hook called with:", { amount: amount?.toString(), sodax: !!sodax });
921
+ return useQuery({
922
+ queryKey: ["soda", "convertedAssets", amount?.toString()],
923
+ queryFn: async () => {
924
+ console.log("useConvertedAssets queryFn called with amount:", amount?.toString());
925
+ if (!amount || amount <= 0n) {
926
+ throw new Error("Amount must be greater than 0");
927
+ }
928
+ const result = await sodax.staking.getConvertedAssets(amount);
929
+ if (!result.ok) {
930
+ throw new Error(`Failed to fetch converted assets: ${result.error.code}`);
931
+ }
932
+ return result.value;
933
+ },
934
+ enabled: !!amount && amount > 0n && !!sodax?.staking,
935
+ refetchInterval
936
+ });
937
+ }
938
+ function useInstantUnstake(spokeProvider) {
939
+ const { sodax } = useSodaxContext();
940
+ return useMutation({
941
+ mutationFn: async (params) => {
942
+ if (!spokeProvider) {
943
+ throw new Error("spokeProvider is not found");
944
+ }
945
+ const result = await sodax.staking.instantUnstake({ ...params, action: "instantUnstake" }, spokeProvider);
946
+ if (!result.ok) {
947
+ throw new Error(`Instant unstake failed: ${result.error.code}`);
948
+ }
949
+ return result.value;
950
+ },
951
+ onError: (error) => {
952
+ console.error("Instant unstake error:", error);
953
+ }
954
+ });
955
+ }
956
+ function useUnstakeAllowance(params, spokeProvider) {
957
+ const { sodax } = useSodaxContext();
958
+ return useQuery({
959
+ queryKey: ["soda", "unstakeAllowance", params, spokeProvider?.chainConfig.chain.id],
960
+ queryFn: async () => {
961
+ if (!params || !spokeProvider) {
962
+ return false;
963
+ }
964
+ const result = await sodax.staking.isAllowanceValid({
965
+ params: { ...params, action: "unstake" },
966
+ spokeProvider
967
+ });
968
+ if (!result.ok) {
969
+ console.error(`Unstake allowance check failed: ${result.error.code}, error: ${result.error.error}`);
970
+ throw new Error(`Unstake allowance check failed: ${result.error.code}`);
971
+ }
972
+ return result.value;
973
+ },
974
+ enabled: !!params && !!spokeProvider,
975
+ refetchInterval: 5e3
976
+ // Refetch every 5 seconds
977
+ });
978
+ }
979
+ function useUnstakeApprove(spokeProvider) {
980
+ const { sodax } = useSodaxContext();
981
+ return useMutation({
982
+ mutationFn: async (params) => {
983
+ console.log("useUnstakeApprove called with params:", params);
984
+ if (!spokeProvider) {
985
+ throw new Error("Spoke provider not found");
986
+ }
987
+ const result = await sodax.staking.approve({
988
+ params: { ...params, action: "unstake" },
989
+ spokeProvider
990
+ });
991
+ if (!result.ok) {
992
+ throw new Error(`Unstake approval failed: ${result.error.code}`);
993
+ }
994
+ return result.value;
995
+ }
996
+ });
997
+ }
998
+ function useUnstakingInfo(userAddress, spokeProvider, refetchInterval = 5e3) {
999
+ const { sodax } = useSodaxContext();
1000
+ return useQuery({
1001
+ queryKey: ["soda", "unstakingInfoWithPenalty", spokeProvider?.chainConfig.chain.id, userAddress],
1002
+ queryFn: async () => {
1003
+ if (!spokeProvider || !userAddress) {
1004
+ throw new Error("Spoke provider or user address not found");
1005
+ }
1006
+ const result = await sodax.staking.getUnstakingInfo(spokeProvider);
1007
+ if (!result.ok) {
1008
+ throw new Error(`Failed to fetch unstaking info: ${result.error.code}`);
1009
+ }
1010
+ return result.value;
1011
+ },
1012
+ enabled: !!spokeProvider && !!userAddress,
1013
+ refetchInterval
1014
+ });
1015
+ }
1016
+ function useInstantUnstakeApprove(spokeProvider) {
1017
+ const { sodax } = useSodaxContext();
1018
+ return useMutation({
1019
+ mutationFn: async (params) => {
1020
+ console.log("useInstantUnstakeApprove called with params:", params);
1021
+ if (!spokeProvider) {
1022
+ throw new Error("Spoke provider not found");
1023
+ }
1024
+ const result = await sodax.staking.approve({
1025
+ params: { ...params, action: "instantUnstake" },
1026
+ spokeProvider
1027
+ });
1028
+ if (!result.ok) {
1029
+ throw new Error(`Instant unstake approval failed: ${result.error.code}`);
1030
+ }
1031
+ return result.value;
1032
+ }
1033
+ });
1034
+ }
1035
+ function useInstantUnstakeAllowance(params, spokeProvider) {
1036
+ const { sodax } = useSodaxContext();
1037
+ return useQuery({
1038
+ queryKey: ["soda", "instantUnstakeAllowance", params, spokeProvider?.chainConfig.chain.id],
1039
+ queryFn: async () => {
1040
+ if (!params || !spokeProvider) {
1041
+ return false;
1042
+ }
1043
+ const result = await sodax.staking.isAllowanceValid({
1044
+ params: { ...params, action: "instantUnstake" },
1045
+ spokeProvider
1046
+ });
1047
+ if (!result.ok) {
1048
+ console.error(`Unstake allowance check failed: ${result.error.code}, error: ${result.error.error}`);
1049
+ throw new Error(`Unstake allowance check failed: ${result.error.code}`);
1050
+ }
1051
+ return result.value;
1052
+ },
1053
+ enabled: !!params && !!spokeProvider,
1054
+ refetchInterval: 5e3
1055
+ // Refetch every 5 seconds
1056
+ });
1057
+ }
1058
+
1059
+ // src/hooks/migrate/types.ts
1060
+ var MIGRATION_MODE_ICX_SODA = "icxsoda";
1061
+ var MIGRATION_MODE_BNUSD = "bnusd";
1062
+
1063
+ // src/hooks/migrate/useMigrate.tsx
1064
+ function useMigrate(spokeProvider) {
1065
+ const { sodax } = useSodaxContext();
1066
+ return useMutation({
1067
+ mutationFn: async (params) => {
1068
+ const { token, amount, migrationMode = MIGRATION_MODE_ICX_SODA, toToken, destinationAddress } = params;
1069
+ const amountToMigrate = parseUnits(amount ?? "0", token?.decimals ?? 0);
1070
+ if (!spokeProvider) {
1071
+ throw new Error("Spoke provider not found");
1072
+ }
1073
+ if (migrationMode === MIGRATION_MODE_ICX_SODA) {
1074
+ if (token?.xChainId === ICON_MAINNET_CHAIN_ID) {
1075
+ const params2 = {
1076
+ address: spokeChainConfig[ICON_MAINNET_CHAIN_ID].nativeToken,
1077
+ amount: amountToMigrate,
1078
+ to: destinationAddress
1079
+ };
1080
+ const result2 = await sodax.migration.migrateIcxToSoda(params2, spokeProvider, 3e4);
1081
+ if (result2.ok) {
1082
+ const [spokeTxHash, hubTxHash] = result2.value;
1083
+ return { spokeTxHash, hubTxHash };
1084
+ }
1085
+ throw new Error("ICX to SODA migration failed. Please try again.");
1086
+ }
1087
+ const revertParams = {
1088
+ amount: amountToMigrate,
1089
+ to: destinationAddress
1090
+ };
1091
+ const result = await sodax.migration.revertMigrateSodaToIcx(
1092
+ revertParams,
1093
+ spokeProvider,
1094
+ 3e4
1095
+ );
1096
+ if (result.ok) {
1097
+ const [hubTxHash, spokeTxHash] = result.value;
1098
+ return { spokeTxHash, hubTxHash };
1099
+ }
1100
+ throw new Error("SODA to ICX migration failed. Please try again.");
1101
+ }
1102
+ if (migrationMode === MIGRATION_MODE_BNUSD) {
1103
+ const params2 = {
1104
+ srcChainId: token?.xChainId,
1105
+ dstChainId: toToken?.xChainId,
1106
+ srcbnUSD: token?.address,
1107
+ dstbnUSD: toToken?.address,
1108
+ amount: amountToMigrate,
1109
+ to: destinationAddress
1110
+ };
1111
+ const result = await sodax.migration.migratebnUSD(params2, spokeProvider, 3e4);
1112
+ if (result.ok) {
1113
+ const [spokeTxHash, hubTxHash] = result.value;
1114
+ return { spokeTxHash, hubTxHash };
1115
+ }
1116
+ const errorMessage = isLegacybnUSDToken(token?.address) ? "bnUSD migration failed. Please try again." : "bnUSD reverse migration failed. Please try again.";
1117
+ throw new Error(errorMessage);
1118
+ }
1119
+ throw new Error("Invalid migration mode");
1120
+ }
1121
+ });
1122
+ }
1123
+ function useMigrationAllowance(params, spokeProvider) {
1124
+ const { sodax } = useSodaxContext();
1125
+ return useQuery({
1126
+ queryKey: ["migration-allowance", params],
1127
+ queryFn: async () => {
1128
+ if (!spokeProvider || !params) {
1129
+ return false;
1130
+ }
1131
+ const { token, amount, migrationMode = MIGRATION_MODE_ICX_SODA, toToken, destinationAddress } = params;
1132
+ if (token?.xChainId === ICON_MAINNET_CHAIN_ID) {
1133
+ return true;
1134
+ }
1135
+ if (!spokeProvider) throw new Error("Spoke provider is required");
1136
+ const amountToMigrate = parseUnits(amount ?? "0", token?.decimals ?? 0);
1137
+ let migrationParams;
1138
+ if (migrationMode === MIGRATION_MODE_ICX_SODA) {
1139
+ migrationParams = {
1140
+ amount: amountToMigrate,
1141
+ to: destinationAddress
1142
+ };
1143
+ } else {
1144
+ if (!toToken) throw new Error("Destination token is required for bnUSD migration");
1145
+ migrationParams = {
1146
+ srcChainId: token?.xChainId,
1147
+ dstChainId: toToken?.xChainId,
1148
+ srcbnUSD: token?.address,
1149
+ dstbnUSD: toToken?.address,
1150
+ amount: amountToMigrate,
1151
+ to: destinationAddress
1152
+ };
1153
+ }
1154
+ const allowance = await sodax.migration.isAllowanceValid(migrationParams, "revert", spokeProvider);
1155
+ if (allowance.ok) {
1156
+ return allowance.value;
1157
+ }
1158
+ return false;
1159
+ },
1160
+ enabled: !!spokeProvider && !!params,
1161
+ refetchInterval: 2e3
1162
+ });
1163
+ }
1164
+ function useMigrationApprove(params, spokeProvider) {
1165
+ const { sodax } = useSodaxContext();
1166
+ const [isLoading, setIsLoading] = useState(false);
1167
+ const [error, setError] = useState(null);
1168
+ const [isApproved, setIsApproved] = useState(false);
1169
+ const queryClient = useQueryClient();
1170
+ const prevTokenAddress = useRef(void 0);
1171
+ const prevAmount = useRef(void 0);
1172
+ useEffect(() => {
1173
+ if (prevTokenAddress.current !== params?.token?.address || prevAmount.current !== params?.amount) {
1174
+ setIsApproved(false);
1175
+ prevTokenAddress.current = params?.token?.address;
1176
+ prevAmount.current = params?.amount;
1177
+ }
1178
+ }, [params?.token?.address, params?.amount]);
1179
+ const approve = useCallback(
1180
+ async ({ params: approveParams }) => {
1181
+ try {
1182
+ setIsLoading(true);
1183
+ setError(null);
1184
+ if (!spokeProvider) {
1185
+ throw new Error("Spoke provider not found");
1186
+ }
1187
+ if (!approveParams) {
1188
+ throw new Error("Migration intent not found");
1189
+ }
1190
+ const { token, amount, migrationMode = MIGRATION_MODE_ICX_SODA, toToken, destinationAddress } = approveParams;
1191
+ const amountToMigrate = parseUnits(amount ?? "0", token?.decimals ?? 0);
1192
+ let result;
1193
+ if (migrationMode === MIGRATION_MODE_ICX_SODA) {
1194
+ const revertParams = {
1195
+ amount: amountToMigrate,
1196
+ to: destinationAddress
1197
+ };
1198
+ result = await sodax.migration.approve(revertParams, "revert", spokeProvider, false);
1199
+ } else if (migrationMode === MIGRATION_MODE_BNUSD) {
1200
+ if (!toToken) throw new Error("Destination token is required for bnUSD migration");
1201
+ const migrationParams = {
1202
+ srcChainId: token?.xChainId,
1203
+ dstChainId: toToken?.xChainId,
1204
+ srcbnUSD: token?.address,
1205
+ dstbnUSD: toToken?.address,
1206
+ amount: amountToMigrate,
1207
+ to: destinationAddress
1208
+ };
1209
+ result = await sodax.migration.approve(migrationParams, "revert", spokeProvider, false);
1210
+ } else {
1211
+ throw new Error("Invalid migration mode");
1212
+ }
1213
+ if (!result.ok) {
1214
+ throw new Error("Failed to approve tokens");
1215
+ }
1216
+ setIsApproved(true);
1217
+ queryClient.invalidateQueries({ queryKey: ["migration-allowance", params] });
1218
+ return result.ok;
1219
+ } catch (err) {
1220
+ const error2 = err instanceof Error ? err : new Error("An unknown error occurred");
1221
+ setError(error2);
1222
+ throw error2;
1223
+ } finally {
1224
+ setIsLoading(false);
1225
+ }
1226
+ },
1227
+ [spokeProvider, sodax, queryClient, params]
1228
+ );
1229
+ const resetError = useCallback(() => {
1230
+ setError(null);
1231
+ }, []);
1232
+ return {
1233
+ approve,
1234
+ isLoading,
1235
+ error,
1236
+ resetError,
1237
+ isApproved
1238
+ };
1239
+ }
1240
+ var SodaxProvider = ({ children, testnet = false, config, rpcConfig }) => {
1241
+ const sodax = new Sodax(config);
1242
+ return /* @__PURE__ */ React.createElement(SodaxContext.Provider, { value: { sodax, testnet, rpcConfig } }, children);
1243
+ };
1244
+ var getSpokeTokenAddressByVault = (spokeChainId, vault) => {
1245
+ const tokens = hubAssets[spokeChainId];
1246
+ const address = Object.keys(tokens).find(
1247
+ (tokenAddress) => tokens[tokenAddress].vault.toLowerCase() === vault.toLowerCase()
1248
+ );
1249
+ return address;
417
1250
  };
418
1251
 
419
- export { SodaxProvider, allXTokens, getSpokeTokenAddressByVault, useBorrow, useCreateIntentOrder, useHubProvider, useHubWalletAddress, useMMAllowance, useMMApprove, useQuote, useRepay, useReservesData, useSodaxContext, useSpokeProvider, useStatus, useSupply, useSwapAllowance, useSwapApprove, useUserReservesData, useWithdraw };
1252
+ export { MIGRATION_MODE_BNUSD, MIGRATION_MODE_ICX_SODA, SodaxProvider, getSpokeTokenAddressByVault, useBackendAllMoneyMarketAssets, useBackendAllMoneyMarketBorrowers, useBackendIntentByHash, useBackendIntentByTxHash, useBackendMoneyMarketAsset, useBackendMoneyMarketAssetBorrowers, useBackendMoneyMarketAssetSuppliers, useBackendMoneyMarketPosition, useBackendOrderbook, useBorrow, useBridge, useBridgeAllowance, useBridgeApprove, useCancelSwap, useCancelUnstake, useClaim, useConvertedAssets, useDeriveUserWalletAddress, useEstimateGas, useGetBridgeableAmount, useGetBridgeableTokens, useHubProvider, useInstantUnstake, useInstantUnstakeAllowance, useInstantUnstakeApprove, useInstantUnstakeRatio, useMMAllowance, useMMApprove, useMigrate, useMigrationAllowance, useMigrationApprove, useQuote, useRepay, useRequestTrustline, useReservesData, useSodaxContext, useSpokeProvider, useStake, useStakeAllowance, useStakeApprove, useStakeRatio, useStakingConfig, useStakingInfo, useStatus, useStellarTrustlineCheck, useSupply, useSwap, useSwapAllowance, useSwapApprove, useUnstake, useUnstakeAllowance, useUnstakeApprove, useUnstakingInfo, useUnstakingInfoWithPenalty, useUserReservesData, useWithdraw };
420
1253
  //# sourceMappingURL=index.mjs.map
421
1254
  //# sourceMappingURL=index.mjs.map