@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.
- package/LICENSE +21 -0
- package/README.md +152 -53
- package/dist/index.d.mts +1514 -0
- package/dist/index.d.ts +1514 -4
- package/dist/index.js +1141 -189
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1096 -187
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -8
- package/src/contexts/index.ts +2 -0
- package/src/core/index.ts +5 -33
- package/src/hooks/backend/README.md +135 -0
- package/src/hooks/backend/index.ts +23 -0
- package/src/hooks/backend/useBackendAllMoneyMarketAssets.ts +49 -0
- package/src/hooks/backend/useBackendAllMoneyMarketBorrowers.ts +61 -0
- package/src/hooks/backend/useBackendIntentByHash.ts +53 -0
- package/src/hooks/backend/useBackendIntentByTxHash.ts +52 -0
- package/src/hooks/backend/useBackendMoneyMarketAsset.ts +57 -0
- package/src/hooks/backend/useBackendMoneyMarketAssetBorrowers.ts +67 -0
- package/src/hooks/backend/useBackendMoneyMarketAssetSuppliers.ts +67 -0
- package/src/hooks/backend/useBackendMoneyMarketPosition.ts +56 -0
- package/src/hooks/backend/useBackendOrderbook.ts +63 -0
- package/src/hooks/bridge/index.ts +5 -0
- package/src/hooks/bridge/useBridge.ts +57 -0
- package/src/hooks/bridge/useBridgeAllowance.ts +49 -0
- package/src/hooks/bridge/useBridgeApprove.ts +68 -0
- package/src/hooks/bridge/useGetBridgeableAmount.ts +50 -0
- package/src/hooks/bridge/useGetBridgeableTokens.ts +62 -0
- package/src/hooks/index.ts +4 -0
- package/src/hooks/migrate/index.ts +4 -0
- package/src/hooks/migrate/types.ts +15 -0
- package/src/hooks/migrate/useMigrate.tsx +110 -0
- package/src/hooks/migrate/useMigrationAllowance.tsx +79 -0
- package/src/hooks/migrate/useMigrationApprove.tsx +129 -0
- package/src/hooks/mm/index.ts +3 -1
- package/src/hooks/mm/useBorrow.ts +20 -10
- package/src/hooks/mm/useMMAllowance.ts +56 -0
- package/src/hooks/mm/useMMApprove.ts +68 -0
- package/src/hooks/mm/useRepay.ts +20 -10
- package/src/hooks/mm/useReservesData.ts +30 -0
- package/src/hooks/mm/useReservesHumanized.ts +30 -0
- package/src/hooks/mm/useReservesList.ts +29 -0
- package/src/hooks/mm/useReservesUsdFormat.ts +38 -0
- package/src/hooks/mm/useSupply.ts +9 -6
- package/src/hooks/mm/useUserFormattedSummary.ts +54 -0
- package/src/hooks/mm/useUserReservesData.ts +30 -48
- package/src/hooks/mm/useWithdraw.ts +17 -11
- package/src/hooks/provider/useHubProvider.ts +3 -21
- package/src/hooks/provider/useSpokeProvider.ts +97 -6
- package/src/hooks/shared/index.ts +4 -2
- package/src/hooks/shared/useDeriveUserWalletAddress.ts +44 -0
- package/src/hooks/shared/useEstimateGas.ts +18 -0
- package/src/hooks/shared/useRequestTrustline.ts +103 -0
- package/src/hooks/shared/useStellarTrustlineCheck.ts +71 -0
- package/src/hooks/staking/index.ts +19 -0
- package/src/hooks/staking/useCancelUnstake.ts +52 -0
- package/src/hooks/staking/useClaim.ts +46 -0
- package/src/hooks/staking/useConvertedAssets.ts +47 -0
- package/src/hooks/staking/useInstantUnstake.ts +50 -0
- package/src/hooks/staking/useInstantUnstakeAllowance.ts +59 -0
- package/src/hooks/staking/useInstantUnstakeApprove.ts +52 -0
- package/src/hooks/staking/useInstantUnstakeRatio.ts +54 -0
- package/src/hooks/staking/useStake.ts +47 -0
- package/src/hooks/staking/useStakeAllowance.ts +57 -0
- package/src/hooks/staking/useStakeApprove.ts +50 -0
- package/src/hooks/staking/useStakeRatio.ts +53 -0
- package/src/hooks/staking/useStakingConfig.ts +40 -0
- package/src/hooks/staking/useStakingInfo.ts +50 -0
- package/src/hooks/staking/useUnstake.ts +54 -0
- package/src/hooks/staking/useUnstakeAllowance.ts +58 -0
- package/src/hooks/staking/useUnstakeApprove.ts +52 -0
- package/src/hooks/staking/useUnstakingInfo.ts +53 -0
- package/src/hooks/staking/useUnstakingInfoWithPenalty.ts +59 -0
- package/src/hooks/swap/index.ts +4 -1
- package/src/hooks/swap/useCancelSwap.ts +44 -0
- package/src/hooks/swap/useQuote.ts +20 -6
- package/src/hooks/swap/useStatus.ts +3 -3
- package/src/hooks/swap/{useCreateIntentOrder.ts → useSwap.ts} +22 -19
- package/src/hooks/swap/useSwapAllowance.ts +48 -0
- package/src/hooks/swap/useSwapApprove.ts +68 -0
- package/src/providers/SodaxProvider.tsx +7 -4
- package/dist/contexts/index.d.ts +0 -7
- package/dist/contexts/index.d.ts.map +0 -1
- package/dist/core/index.d.ts +0 -4
- package/dist/core/index.d.ts.map +0 -1
- package/dist/hooks/index.d.ts +0 -5
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/mm/index.d.ts +0 -7
- package/dist/hooks/mm/index.d.ts.map +0 -1
- package/dist/hooks/mm/useBorrow.d.ts +0 -26
- package/dist/hooks/mm/useBorrow.d.ts.map +0 -1
- package/dist/hooks/mm/useHubWalletAddress.d.ts +0 -24
- package/dist/hooks/mm/useHubWalletAddress.d.ts.map +0 -1
- package/dist/hooks/mm/useRepay.d.ts +0 -26
- package/dist/hooks/mm/useRepay.d.ts.map +0 -1
- package/dist/hooks/mm/useSupply.d.ts +0 -32
- package/dist/hooks/mm/useSupply.d.ts.map +0 -1
- package/dist/hooks/mm/useUserReservesData.d.ts +0 -9
- package/dist/hooks/mm/useUserReservesData.d.ts.map +0 -1
- package/dist/hooks/mm/useWithdraw.d.ts +0 -26
- package/dist/hooks/mm/useWithdraw.d.ts.map +0 -1
- package/dist/hooks/provider/index.d.ts +0 -3
- package/dist/hooks/provider/index.d.ts.map +0 -1
- package/dist/hooks/provider/useHubProvider.d.ts +0 -3
- package/dist/hooks/provider/useHubProvider.d.ts.map +0 -1
- package/dist/hooks/provider/useSpokeProvider.d.ts +0 -4
- package/dist/hooks/provider/useSpokeProvider.d.ts.map +0 -1
- package/dist/hooks/shared/index.d.ts +0 -4
- package/dist/hooks/shared/index.d.ts.map +0 -1
- package/dist/hooks/shared/useAllowance.d.ts +0 -3
- package/dist/hooks/shared/useAllowance.d.ts.map +0 -1
- package/dist/hooks/shared/useApprove.d.ts +0 -10
- package/dist/hooks/shared/useApprove.d.ts.map +0 -1
- package/dist/hooks/shared/useSodaxContext.d.ts +0 -8
- package/dist/hooks/shared/useSodaxContext.d.ts.map +0 -1
- package/dist/hooks/swap/index.d.ts +0 -4
- package/dist/hooks/swap/index.d.ts.map +0 -1
- package/dist/hooks/swap/useCreateIntentOrder.d.ts +0 -33
- package/dist/hooks/swap/useCreateIntentOrder.d.ts.map +0 -1
- package/dist/hooks/swap/useQuote.d.ts +0 -39
- package/dist/hooks/swap/useQuote.d.ts.map +0 -1
- package/dist/hooks/swap/useStatus.d.ts +0 -31
- package/dist/hooks/swap/useStatus.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/providers/SodaxProvider.d.ts +0 -10
- package/dist/providers/SodaxProvider.d.ts.map +0 -1
- package/dist/providers/index.d.ts +0 -2
- package/dist/providers/index.d.ts.map +0 -1
- package/src/hooks/mm/useHubWalletAddress.ts +0 -49
- package/src/hooks/shared/useAllowance.ts +0 -31
- 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 {
|
|
3
|
-
import {
|
|
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
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
|
|
34
|
-
}, [walletProvider, xChainType, spokeChainId]);
|
|
35
|
-
return spokeProvider;
|
|
25
|
+
});
|
|
36
26
|
}
|
|
37
|
-
function
|
|
27
|
+
function useDeriveUserWalletAddress(spokeProvider, walletAddress) {
|
|
38
28
|
const { sodax } = useSodaxContext();
|
|
39
|
-
const spokeProvider = useSpokeProvider(token.xChainId);
|
|
40
29
|
return useQuery({
|
|
41
|
-
queryKey: ["
|
|
30
|
+
queryKey: ["deriveUserWalletAddress", spokeProvider?.chainConfig.chain.id, walletAddress],
|
|
42
31
|
queryFn: async () => {
|
|
43
32
|
if (!spokeProvider) {
|
|
44
|
-
|
|
33
|
+
throw new Error("Spoke provider is required");
|
|
45
34
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
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
|
|
62
|
-
const { sodax } = useSodaxContext();
|
|
63
|
-
const spokeProvider = useSpokeProvider(token.xChainId);
|
|
66
|
+
function useRequestTrustline(token) {
|
|
64
67
|
const queryClient = useQueryClient();
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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);
|
|
83
97
|
}
|
|
84
|
-
return allowance.ok;
|
|
85
98
|
},
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
});
|
|
99
|
+
[queryClient]
|
|
100
|
+
);
|
|
90
101
|
return {
|
|
91
|
-
|
|
92
|
-
isLoading
|
|
102
|
+
requestTrustline,
|
|
103
|
+
isLoading,
|
|
104
|
+
isRequested,
|
|
93
105
|
error,
|
|
94
|
-
|
|
106
|
+
data
|
|
95
107
|
};
|
|
96
108
|
}
|
|
109
|
+
|
|
110
|
+
// src/hooks/provider/useHubProvider.ts
|
|
97
111
|
function useHubProvider() {
|
|
98
112
|
const { sodax } = useSodaxContext();
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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,
|
|
113
|
-
return
|
|
174
|
+
}, [spokeChainId, xChainType, walletProvider, rpcConfig]);
|
|
175
|
+
return spokeProvider;
|
|
114
176
|
}
|
|
115
|
-
function useBorrow(
|
|
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.
|
|
184
|
+
const response = await sodax.moneyMarket.borrow(
|
|
124
185
|
{
|
|
125
|
-
token:
|
|
126
|
-
amount: parseUnits(amount,
|
|
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(
|
|
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.
|
|
207
|
+
const response = await sodax.moneyMarket.repay(
|
|
147
208
|
{
|
|
148
|
-
token:
|
|
149
|
-
amount: parseUnits(amount,
|
|
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.
|
|
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(
|
|
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.
|
|
253
|
+
const response = await sodax.moneyMarket.withdraw(
|
|
193
254
|
{
|
|
194
|
-
token:
|
|
195
|
-
|
|
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
|
-
|
|
208
|
-
|
|
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: ["
|
|
273
|
+
queryKey: ["userReserves", spokeProvider?.chainConfig.chain.id, address],
|
|
239
274
|
queryFn: async () => {
|
|
240
|
-
if (!
|
|
241
|
-
|
|
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: !!
|
|
280
|
+
enabled: !!spokeProvider && !!address,
|
|
281
|
+
refetchInterval
|
|
254
282
|
});
|
|
255
283
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
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 (!
|
|
273
|
-
|
|
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
|
-
|
|
276
|
-
|
|
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
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
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
|
-
|
|
297
|
-
|
|
343
|
+
onSuccess: () => {
|
|
344
|
+
queryClient.invalidateQueries({ queryKey: ["allowance", token.address] });
|
|
345
|
+
}
|
|
298
346
|
});
|
|
299
|
-
return
|
|
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
|
|
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
|
|
378
|
+
function useSwap(spokeProvider) {
|
|
316
379
|
const { sodax } = useSodaxContext();
|
|
317
|
-
const
|
|
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.
|
|
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
|
-
|
|
339
|
-
const sodax =
|
|
340
|
-
return
|
|
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 {
|
|
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
|