@sodax/dapp-kit 0.0.1-rc.3 → 0.0.1-rc.31

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 (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +152 -53
  3. package/dist/index.d.mts +1514 -0
  4. package/dist/index.d.ts +1514 -4
  5. package/dist/index.js +1141 -189
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +1096 -187
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +7 -8
  10. package/src/contexts/index.ts +2 -0
  11. package/src/core/index.ts +5 -33
  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 +3 -1
  36. package/src/hooks/mm/useBorrow.ts +20 -10
  37. package/src/hooks/mm/useMMAllowance.ts +56 -0
  38. package/src/hooks/mm/useMMApprove.ts +68 -0
  39. package/src/hooks/mm/useRepay.ts +20 -10
  40. package/src/hooks/mm/useReservesData.ts +30 -0
  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 +9 -6
  45. package/src/hooks/mm/useUserFormattedSummary.ts +54 -0
  46. package/src/hooks/mm/useUserReservesData.ts +30 -48
  47. package/src/hooks/mm/useWithdraw.ts +17 -11
  48. package/src/hooks/provider/useHubProvider.ts +3 -21
  49. package/src/hooks/provider/useSpokeProvider.ts +97 -6
  50. package/src/hooks/shared/index.ts +4 -2
  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 +4 -1
  75. package/src/hooks/swap/useCancelSwap.ts +44 -0
  76. package/src/hooks/swap/useQuote.ts +20 -6
  77. package/src/hooks/swap/useStatus.ts +3 -3
  78. package/src/hooks/swap/{useCreateIntentOrder.ts → useSwap.ts} +22 -19
  79. package/src/hooks/swap/useSwapAllowance.ts +48 -0
  80. package/src/hooks/swap/useSwapApprove.ts +68 -0
  81. package/src/providers/SodaxProvider.tsx +7 -4
  82. package/dist/contexts/index.d.ts +0 -7
  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 -7
  89. package/dist/hooks/mm/index.d.ts.map +0 -1
  90. package/dist/hooks/mm/useBorrow.d.ts +0 -26
  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/useRepay.d.ts +0 -26
  95. package/dist/hooks/mm/useRepay.d.ts.map +0 -1
  96. package/dist/hooks/mm/useSupply.d.ts +0 -32
  97. package/dist/hooks/mm/useSupply.d.ts.map +0 -1
  98. package/dist/hooks/mm/useUserReservesData.d.ts +0 -9
  99. package/dist/hooks/mm/useUserReservesData.d.ts.map +0 -1
  100. package/dist/hooks/mm/useWithdraw.d.ts +0 -26
  101. package/dist/hooks/mm/useWithdraw.d.ts.map +0 -1
  102. package/dist/hooks/provider/index.d.ts +0 -3
  103. package/dist/hooks/provider/index.d.ts.map +0 -1
  104. package/dist/hooks/provider/useHubProvider.d.ts +0 -3
  105. package/dist/hooks/provider/useHubProvider.d.ts.map +0 -1
  106. package/dist/hooks/provider/useSpokeProvider.d.ts +0 -4
  107. package/dist/hooks/provider/useSpokeProvider.d.ts.map +0 -1
  108. package/dist/hooks/shared/index.d.ts +0 -4
  109. package/dist/hooks/shared/index.d.ts.map +0 -1
  110. package/dist/hooks/shared/useAllowance.d.ts +0 -3
  111. package/dist/hooks/shared/useAllowance.d.ts.map +0 -1
  112. package/dist/hooks/shared/useApprove.d.ts +0 -10
  113. package/dist/hooks/shared/useApprove.d.ts.map +0 -1
  114. package/dist/hooks/shared/useSodaxContext.d.ts +0 -8
  115. package/dist/hooks/shared/useSodaxContext.d.ts.map +0 -1
  116. package/dist/hooks/swap/index.d.ts +0 -4
  117. package/dist/hooks/swap/index.d.ts.map +0 -1
  118. package/dist/hooks/swap/useCreateIntentOrder.d.ts +0 -33
  119. package/dist/hooks/swap/useCreateIntentOrder.d.ts.map +0 -1
  120. package/dist/hooks/swap/useQuote.d.ts +0 -39
  121. package/dist/hooks/swap/useQuote.d.ts.map +0 -1
  122. package/dist/hooks/swap/useStatus.d.ts +0 -31
  123. package/dist/hooks/swap/useStatus.d.ts.map +0 -1
  124. package/dist/index.d.ts.map +0 -1
  125. package/dist/providers/SodaxProvider.d.ts +0 -10
  126. package/dist/providers/SodaxProvider.d.ts.map +0 -1
  127. package/dist/providers/index.d.ts +0 -2
  128. package/dist/providers/index.d.ts.map +0 -1
  129. package/src/hooks/mm/useHubWalletAddress.ts +0 -49
  130. package/src/hooks/shared/useAllowance.ts +0 -31
  131. package/src/hooks/shared/useApprove.ts +0 -53
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
- import React, { createContext, useContext, useMemo } from 'react';
2
- import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
3
- import { hubAssets, EvmSpokeProvider, spokeChainConfig, SuiSpokeProvider, getHubChainConfig, EvmHubProvider, EvmWalletAbstraction, getMoneyMarketConfig, Sodax } from '@sodax/sdk';
4
- import { getXChainType, useWalletProvider, useXAccount } 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';
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,117 +13,179 @@ var useSodaxContext = () => {
13
13
  }
14
14
  return context;
15
15
  };
16
- function useSpokeProvider(spokeChainId) {
17
- const xChainType = getXChainType(spokeChainId);
18
- const walletProvider = useWalletProvider(spokeChainId);
19
- const spokeProvider = useMemo(() => {
20
- if (!walletProvider) return void 0;
21
- if (xChainType === "EVM") {
22
- return new EvmSpokeProvider(
23
- walletProvider,
24
- spokeChainConfig[spokeChainId]
25
- );
26
- }
27
- if (xChainType === "SUI") {
28
- return new SuiSpokeProvider(
29
- spokeChainConfig[spokeChainId],
30
- walletProvider
31
- );
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;
32
24
  }
33
- return void 0;
34
- }, [walletProvider, xChainType, spokeChainId]);
35
- return spokeProvider;
25
+ });
36
26
  }
37
- function useAllowance(token, amount) {
27
+ function useDeriveUserWalletAddress(spokeProvider, walletAddress) {
38
28
  const { sodax } = useSodaxContext();
39
- const spokeProvider = useSpokeProvider(token.xChainId);
40
29
  return useQuery({
41
- queryKey: ["allowance", token.address, amount],
30
+ queryKey: ["deriveUserWalletAddress", spokeProvider?.chainConfig.chain.id, walletAddress],
42
31
  queryFn: async () => {
43
32
  if (!spokeProvider) {
44
- return false;
33
+ throw new Error("Spoke provider is required");
45
34
  }
46
- const allowance = await sodax.moneyMarket.isAllowanceValid(
47
- {
48
- token: token.address,
49
- amount: parseUnits(amount, token.decimals)
50
- },
51
- spokeProvider
52
- );
53
- if (allowance.ok) {
54
- return allowance.value;
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;
55
48
  }
56
- return false;
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;
57
62
  },
58
- enabled: !!spokeProvider
63
+ enabled: !!spokeProvider && !!token && !!amount
59
64
  });
60
65
  }
61
- function useApprove(token) {
62
- const { sodax } = useSodaxContext();
63
- const spokeProvider = useSpokeProvider(token.xChainId);
66
+ function useRequestTrustline(token) {
64
67
  const queryClient = useQueryClient();
65
- const {
66
- mutateAsync: approve,
67
- isPending,
68
- error,
69
- reset: resetError
70
- } = useMutation({
71
- mutationFn: async (amount) => {
72
- if (!spokeProvider) {
73
- throw new Error("Spoke provider not found");
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;
74
82
  }
75
- const allowance = await sodax.moneyMarket.approve(
76
- token.address,
77
- parseUnits(amount, token.decimals),
78
- spokeProvider.chainConfig.addresses.assetManager,
79
- spokeProvider
80
- );
81
- if (!allowance.ok) {
82
- throw new Error("Failed to approve tokens");
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);
83
97
  }
84
- return allowance.ok;
85
98
  },
86
- onSuccess: () => {
87
- queryClient.invalidateQueries({ queryKey: ["allowance", token.address] });
88
- }
89
- });
99
+ [queryClient]
100
+ );
90
101
  return {
91
- approve,
92
- isLoading: isPending,
102
+ requestTrustline,
103
+ isLoading,
104
+ isRequested,
93
105
  error,
94
- resetError
106
+ data
95
107
  };
96
108
  }
109
+
110
+ // src/hooks/provider/useHubProvider.ts
97
111
  function useHubProvider() {
98
112
  const { sodax } = useSodaxContext();
99
- const hubChainId = sodax.config?.hubProviderConfig?.chainConfig.chain.id;
100
- const hubRpcUrl = sodax.config?.hubProviderConfig?.hubRpcUrl;
101
- const xChainType = getXChainType(hubChainId);
102
- const hubProvider = useMemo(() => {
103
- if (xChainType === "EVM" && hubChainId && hubRpcUrl) {
104
- const hubChainCfg = getHubChainConfig(hubChainId);
105
- if (!hubChainCfg) return void 0;
106
- return new EvmHubProvider({
107
- hubRpcUrl,
108
- chainConfig: hubChainCfg
109
- });
113
+ return sodax.hubProvider;
114
+ }
115
+ function useSpokeProvider(spokeChainId, walletProvider) {
116
+ const { rpcConfig } = useSodaxContext();
117
+ const xChainType = spokeChainId ? spokeChainConfig[spokeChainId]?.chain.type : void 0;
118
+ const spokeProvider = useMemo(() => {
119
+ if (!walletProvider) return void 0;
120
+ if (!spokeChainId) return void 0;
121
+ if (!xChainType) return void 0;
122
+ if (!rpcConfig) return void 0;
123
+ if (xChainType === "EVM") {
124
+ if (spokeChainId === SONIC_MAINNET_CHAIN_ID) {
125
+ return new SonicSpokeProvider(
126
+ walletProvider,
127
+ spokeChainConfig[spokeChainId]
128
+ );
129
+ }
130
+ return new EvmSpokeProvider(
131
+ walletProvider,
132
+ spokeChainConfig[spokeChainId]
133
+ );
134
+ }
135
+ if (xChainType === "SUI") {
136
+ return new SuiSpokeProvider(
137
+ spokeChainConfig[spokeChainId],
138
+ walletProvider
139
+ );
140
+ }
141
+ if (xChainType === "ICON") {
142
+ return new IconSpokeProvider(
143
+ walletProvider,
144
+ spokeChainConfig[spokeChainId]
145
+ );
146
+ }
147
+ if (xChainType === "INJECTIVE") {
148
+ return new InjectiveSpokeProvider(
149
+ spokeChainConfig[spokeChainId],
150
+ walletProvider
151
+ );
152
+ }
153
+ if (xChainType === "STELLAR") {
154
+ const stellarConfig = spokeChainConfig[spokeChainId];
155
+ return new StellarSpokeProvider(
156
+ walletProvider,
157
+ stellarConfig,
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]
171
+ );
110
172
  }
111
173
  return void 0;
112
- }, [xChainType, hubChainId, hubRpcUrl]);
113
- return hubProvider;
174
+ }, [spokeChainId, xChainType, walletProvider, rpcConfig]);
175
+ return spokeProvider;
114
176
  }
115
- function useBorrow(hubToken, spokeChainId) {
177
+ function useBorrow(spokeToken, spokeProvider) {
116
178
  const { sodax } = useSodaxContext();
117
- const spokeProvider = useSpokeProvider(spokeChainId);
118
179
  return useMutation({
119
180
  mutationFn: async (amount) => {
120
181
  if (!spokeProvider) {
121
182
  throw new Error("spokeProvider is not found");
122
183
  }
123
- const response = await sodax.moneyMarket.borrowAndSubmit(
184
+ const response = await sodax.moneyMarket.borrow(
124
185
  {
125
- token: hubToken.address,
126
- amount: parseUnits(amount, hubToken.decimals)
186
+ token: spokeToken.address,
187
+ amount: parseUnits(amount, 18),
188
+ action: "borrow"
127
189
  },
128
190
  spokeProvider
129
191
  );
@@ -135,18 +197,18 @@ function useBorrow(hubToken, spokeChainId) {
135
197
  }
136
198
  });
137
199
  }
138
- function useRepay(hubToken, spokeChainId) {
200
+ function useRepay(spokeToken, spokeProvider) {
139
201
  const { sodax } = useSodaxContext();
140
- const spokeProvider = useSpokeProvider(spokeChainId);
141
202
  return useMutation({
142
203
  mutationFn: async (amount) => {
143
204
  if (!spokeProvider) {
144
205
  throw new Error("spokeProvider is not found");
145
206
  }
146
- const response = await sodax.moneyMarket.repayAndSubmit(
207
+ const response = await sodax.moneyMarket.repay(
147
208
  {
148
- token: hubToken.address,
149
- amount: parseUnits(amount, hubToken.decimals)
209
+ token: spokeToken.address,
210
+ amount: parseUnits(amount, spokeToken.decimals),
211
+ action: "repay"
150
212
  },
151
213
  spokeProvider
152
214
  );
@@ -158,18 +220,18 @@ function useRepay(hubToken, spokeChainId) {
158
220
  }
159
221
  });
160
222
  }
161
- function useSupply(spokeToken) {
223
+ function useSupply(spokeToken, spokeProvider) {
162
224
  const { sodax } = useSodaxContext();
163
- const spokeProvider = useSpokeProvider(spokeToken.xChainId);
164
225
  return useMutation({
165
226
  mutationFn: async (amount) => {
166
227
  if (!spokeProvider) {
167
228
  throw new Error("spokeProvider is not found");
168
229
  }
169
- const response = await sodax.moneyMarket.supplyAndSubmit(
230
+ const response = await sodax.moneyMarket.supply(
170
231
  {
171
232
  token: spokeToken.address,
172
- amount: parseUnits(amount, spokeToken.decimals)
233
+ amount: parseUnits(amount, spokeToken.decimals),
234
+ action: "supply"
173
235
  },
174
236
  spokeProvider
175
237
  );
@@ -181,18 +243,19 @@ function useSupply(spokeToken) {
181
243
  }
182
244
  });
183
245
  }
184
- function useWithdraw(hubToken, spokeChainId) {
246
+ function useWithdraw(spokeToken, spokeProvider) {
185
247
  const { sodax } = useSodaxContext();
186
- const spokeProvider = useSpokeProvider(spokeChainId);
187
248
  return useMutation({
188
249
  mutationFn: async (amount) => {
189
250
  if (!spokeProvider) {
190
251
  throw new Error("spokeProvider is not found");
191
252
  }
192
- const response = await sodax.moneyMarket.withdrawAndSubmit(
253
+ const response = await sodax.moneyMarket.withdraw(
193
254
  {
194
- token: hubToken.address,
195
- amount: parseUnits(amount, hubToken.decimals)
255
+ token: spokeToken.address,
256
+ // vault token on hub chain decimals is 18
257
+ amount: parseUnits(amount, 18),
258
+ action: "withdraw"
196
259
  },
197
260
  spokeProvider
198
261
  );
@@ -204,104 +267,104 @@ function useWithdraw(hubToken, spokeChainId) {
204
267
  }
205
268
  });
206
269
  }
207
- var allXTokens = [];
208
- Object.keys(hubAssets).forEach((xChainId) => {
209
- const tokens = hubAssets[xChainId];
210
- Object.keys(tokens).forEach((tokenAddress) => {
211
- const token = tokens[tokenAddress];
212
- allXTokens.push({
213
- xChainId,
214
- symbol: token.symbol,
215
- name: token.name,
216
- decimals: token.decimal,
217
- address: tokenAddress
218
- });
219
- allXTokens.push({
220
- xChainId: "sonic",
221
- symbol: token.symbol,
222
- name: token.name,
223
- decimals: token.decimal,
224
- address: token.vault
225
- });
226
- });
227
- });
228
- var getSpokeTokenAddressByVault = (spokeChainId, vault) => {
229
- const tokens = hubAssets[spokeChainId];
230
- const token = Object.keys(tokens).find((tokenAddress) => tokens[tokenAddress].vault === vault);
231
- if (!token) {
232
- throw new Error("Token not found");
233
- }
234
- return token;
235
- };
236
- function useHubWalletAddress(spokeChainId, address, hubProvider) {
270
+ function useUserReservesData(spokeProvider, address, refetchInterval = 5e3) {
271
+ const { sodax } = useSodaxContext();
237
272
  return useQuery({
238
- queryKey: ["hubWallet", spokeChainId, address],
273
+ queryKey: ["userReserves", spokeProvider?.chainConfig.chain.id, address],
239
274
  queryFn: async () => {
240
- if (!address) return null;
241
- try {
242
- const hubWalletAddress = await EvmWalletAbstraction.getUserHubWalletAddress(
243
- spokeChainId,
244
- address,
245
- hubProvider
246
- );
247
- return hubWalletAddress;
248
- } catch (error) {
249
- console.log("error", error);
250
- return null;
275
+ if (!spokeProvider) {
276
+ throw new Error("Spoke provider or address is not defined");
251
277
  }
278
+ return await sodax.moneyMarket.data.getUserReservesData(spokeProvider);
252
279
  },
253
- enabled: !!address && !!hubProvider
280
+ enabled: !!spokeProvider && !!address,
281
+ refetchInterval
254
282
  });
255
283
  }
256
-
257
- // src/hooks/mm/useUserReservesData.ts
258
- function useUserReservesData(spokeChainId) {
259
- const { sodax } = useSodaxContext();
260
- const hubChainId = sodax.config?.hubProviderConfig?.chainConfig.chain.id ?? "sonic";
261
- const hubWalletProvider = useWalletProvider(hubChainId);
262
- const hubProvider = useHubProvider();
263
- const { address } = useXAccount(spokeChainId);
264
- const { data: hubWalletAddress } = useHubWalletAddress(
265
- spokeChainId,
266
- address,
267
- hubProvider
268
- );
269
- const { data: userReserves } = useQuery({
270
- queryKey: ["userReserves", hubWalletAddress],
284
+ function useReservesData() {
285
+ const { sodax } = useSodaxContext();
286
+ return useQuery({
287
+ queryKey: ["reservesData"],
288
+ queryFn: async () => {
289
+ return await sodax.moneyMarket.data.getReservesData();
290
+ }
291
+ });
292
+ }
293
+ function useMMAllowance(token, amount, action, spokeProvider) {
294
+ const { sodax } = useSodaxContext();
295
+ return useQuery({
296
+ queryKey: ["allowance", token.address, amount, action],
271
297
  queryFn: async () => {
272
- if (!hubWalletProvider) {
273
- return;
298
+ if (!spokeProvider) throw new Error("Spoke provider is required");
299
+ const actionBasedDecimals = action === "withdraw" || action === "borrow" ? 18 : token.decimals;
300
+ const allowance = await sodax.moneyMarket.isAllowanceValid(
301
+ {
302
+ token: token.address,
303
+ amount: parseUnits(amount, actionBasedDecimals),
304
+ action
305
+ },
306
+ spokeProvider
307
+ );
308
+ if (allowance.ok) {
309
+ return allowance.value;
274
310
  }
275
- if (!hubWalletAddress) {
276
- return;
311
+ return false;
312
+ },
313
+ enabled: !!spokeProvider
314
+ });
315
+ }
316
+ function useMMApprove(token, spokeProvider) {
317
+ const { sodax } = useSodaxContext();
318
+ const queryClient = useQueryClient();
319
+ const {
320
+ mutateAsync: approve,
321
+ isPending,
322
+ error,
323
+ reset: resetError
324
+ } = useMutation({
325
+ mutationFn: async ({ amount, action }) => {
326
+ if (!spokeProvider) {
327
+ throw new Error("Spoke provider not found");
277
328
  }
278
- const moneyMarketConfig = getMoneyMarketConfig(hubChainId);
279
- try {
280
- const [res] = await sodax.moneyMarket.getUserReservesData(
281
- hubWalletAddress,
282
- moneyMarketConfig.uiPoolDataProvider,
283
- moneyMarketConfig.poolAddressesProvider
284
- );
285
- return res?.map((r) => {
286
- return {
287
- ...r,
288
- token: allXTokens.find((t) => t.address === r.underlyingAsset)
289
- };
290
- });
291
- } catch (error) {
292
- console.log("error", error);
293
- return;
329
+ const actionBasedDecimals = action === "withdraw" || action === "borrow" ? 18 : token.decimals;
330
+ const allowance = await sodax.moneyMarket.approve(
331
+ {
332
+ token: token.address,
333
+ amount: parseUnits(amount, actionBasedDecimals),
334
+ action
335
+ },
336
+ spokeProvider
337
+ );
338
+ if (!allowance.ok) {
339
+ throw new Error("Failed to approve tokens");
294
340
  }
341
+ return allowance.ok;
295
342
  },
296
- enabled: !!address && !!hubWalletProvider && !!hubWalletAddress,
297
- refetchInterval: 5e3
343
+ onSuccess: () => {
344
+ queryClient.invalidateQueries({ queryKey: ["allowance", token.address] });
345
+ }
298
346
  });
299
- return userReserves;
347
+ return {
348
+ approve,
349
+ isLoading: isPending,
350
+ error,
351
+ resetError
352
+ };
300
353
  }
301
354
  var useQuote = (payload) => {
302
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]);
303
366
  return useQuery({
304
- queryKey: [payload],
367
+ queryKey,
305
368
  queryFn: async () => {
306
369
  if (!payload) {
307
370
  return void 0;
@@ -312,15 +375,21 @@ var useQuote = (payload) => {
312
375
  refetchInterval: 3e3
313
376
  });
314
377
  };
315
- function useCreateIntentOrder(chainId) {
378
+ function useSwap(spokeProvider) {
316
379
  const { sodax } = useSodaxContext();
317
- const spokeProvider = useSpokeProvider(chainId);
380
+ const queryClient = useQueryClient();
318
381
  return useMutation({
319
382
  mutationFn: async (params) => {
320
383
  if (!spokeProvider) {
321
384
  throw new Error("Spoke provider not found");
322
385
  }
323
- return sodax.solver.createAndSubmitIntent(params, spokeProvider);
386
+ return sodax.solver.swap({
387
+ intentParams: params,
388
+ spokeProvider
389
+ });
390
+ },
391
+ onSuccess: () => {
392
+ queryClient.invalidateQueries({ queryKey: ["xBalances"] });
324
393
  }
325
394
  });
326
395
  }
@@ -335,11 +404,851 @@ var useStatus = (intent_tx_hash) => {
335
404
  // 3s
336
405
  });
337
406
  };
338
- var SodaxProvider = ({ children, testnet = false, config }) => {
339
- const sodax = new Sodax(config);
340
- return /* @__PURE__ */ React.createElement(SodaxContext.Provider, { value: { sodax, testnet } }, children);
407
+ function useSwapAllowance(params, spokeProvider) {
408
+ const { sodax } = useSodaxContext();
409
+ return useQuery({
410
+ queryKey: ["allowance", params],
411
+ queryFn: async () => {
412
+ if (!spokeProvider || !params) {
413
+ return false;
414
+ }
415
+ const allowance = await sodax.solver.isAllowanceValid({
416
+ intentParams: params,
417
+ spokeProvider
418
+ });
419
+ if (allowance.ok) {
420
+ return allowance.value;
421
+ }
422
+ return false;
423
+ },
424
+ enabled: !!spokeProvider && !!params,
425
+ refetchInterval: 2e3
426
+ });
427
+ }
428
+ function useSwapApprove(params, spokeProvider) {
429
+ const { sodax } = useSodaxContext();
430
+ const queryClient = useQueryClient();
431
+ const {
432
+ mutateAsync: approve,
433
+ isPending,
434
+ error,
435
+ reset: resetError
436
+ } = useMutation({
437
+ mutationFn: async ({ params: params2 }) => {
438
+ if (!spokeProvider) {
439
+ throw new Error("Spoke provider not found");
440
+ }
441
+ if (!params2) {
442
+ throw new Error("Swap Params not found");
443
+ }
444
+ const allowance = await sodax.solver.approve({
445
+ intentParams: params2,
446
+ spokeProvider
447
+ });
448
+ if (!allowance.ok) {
449
+ throw new Error("Failed to approve input token");
450
+ }
451
+ return allowance.ok;
452
+ },
453
+ onSuccess: () => {
454
+ queryClient.invalidateQueries({ queryKey: ["allowance", params] });
455
+ }
456
+ });
457
+ return {
458
+ approve,
459
+ isLoading: isPending,
460
+ error,
461
+ resetError
462
+ };
463
+ }
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.solver.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.backendApiService.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.backendApiService.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.backendApiService.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.backendApiService.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.backendApiService.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.backendApiService.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.backendApiService.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.backendApiService.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.backendApiService.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
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] });
649
+ }
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;
341
1250
  };
342
1251
 
343
- export { SodaxProvider, allXTokens, getSpokeTokenAddressByVault, useAllowance, useApprove, useBorrow, useCreateIntentOrder, useHubProvider, useHubWalletAddress, useQuote, useRepay, useSodaxContext, useSpokeProvider, useStatus, useSupply, 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 };
344
1253
  //# sourceMappingURL=index.mjs.map
345
1254
  //# sourceMappingURL=index.mjs.map