fix: migrate remaining DEX components to Asset Hub API

- Update dex/AddLiquidityModal to use assetHubApi
- Update dex/PoolBrowser to use assetHubApi
- Update dex/SwapInterface to use assetHubApi
- Update dex/XCMBridgeSetupModal to use assetHubApi
- Fix all dependency array references
This commit is contained in:
2026-02-04 15:04:25 +03:00
parent 9b66f355f5
commit 7bfa47edd0
4 changed files with 45 additions and 41 deletions
+9 -8
View File
@@ -21,7 +21,8 @@ export const AddLiquidityModal: React.FC<AddLiquidityModalProps> = ({
onClose,
onSuccess,
}) => {
const { api, isApiReady } = usePezkuwi();
// Use Asset Hub API for DEX operations
const { assetHubApi, isAssetHubReady } = usePezkuwi();
const { account, signer } = useWallet();
const [amount1Input, setAmount1Input] = useState('');
@@ -47,11 +48,11 @@ export const AddLiquidityModal: React.FC<AddLiquidityModalProps> = ({
// Fetch balances
useEffect(() => {
const fetchBalances = async () => {
if (!api || !isApiReady || !account || !pool) return;
if (!assetHubApi || !isAssetHubReady || !account || !pool) return;
try {
const balance1Data = await api.query.assets.account(pool.asset1, account);
const balance2Data = await api.query.assets.account(pool.asset2, account);
const balance1Data = await assetHubApi.query.assets.account(pool.asset1, account);
const balance2Data = await assetHubApi.query.assets.account(pool.asset2, account);
setBalance1(balance1Data.isSome ? balance1Data.unwrap().balance.toString() : '0');
setBalance2(balance2Data.isSome ? balance2Data.unwrap().balance.toString() : '0');
@@ -61,7 +62,7 @@ export const AddLiquidityModal: React.FC<AddLiquidityModalProps> = ({
};
fetchBalances();
}, [api, isApiReady, account, pool]);
}, [assetHubApi, isAssetHubReady, account, pool]);
// Auto-calculate amount2 when amount1 changes
const handleAmount1Change = (value: string) => {
@@ -124,7 +125,7 @@ export const AddLiquidityModal: React.FC<AddLiquidityModalProps> = ({
};
const handleAddLiquidity = async () => {
if (!api || !isApiReady || !signer || !account || !pool) {
if (!assetHubApi || !isAssetHubReady || !signer || !account || !pool) {
setErrorMessage('Wallet not connected');
return;
}
@@ -146,7 +147,7 @@ export const AddLiquidityModal: React.FC<AddLiquidityModalProps> = ({
setTxStatus('signing');
setErrorMessage('');
const tx = api.tx.assetConversion.addLiquidity(
const tx = assetHubApi.tx.assetConversion.addLiquidity(
pool.asset1,
pool.asset2,
amount1Raw,
@@ -165,7 +166,7 @@ export const AddLiquidityModal: React.FC<AddLiquidityModalProps> = ({
if (status.isInBlock) {
if (dispatchError) {
if (dispatchError.isModule) {
const decoded = api.registry.findMetaError(dispatchError.asModule);
const decoded = assetHubApi.registry.findMetaError(dispatchError.asModule);
setErrorMessage(`${decoded.section}.${decoded.name}: ${decoded.docs}`);
} else {
setErrorMessage(dispatchError.toString());
+5 -4
View File
@@ -22,7 +22,8 @@ export const PoolBrowser: React.FC<PoolBrowserProps> = ({
onSwap,
onCreatePool,
}) => {
const { api, isApiReady, sudoKey } = usePezkuwi();
// Use Asset Hub API for DEX operations
const { assetHubApi, isAssetHubReady, sudoKey } = usePezkuwi();
const { account } = useWallet();
const [pools, setPools] = useState<PoolInfo[]>([]);
const [loading, setLoading] = useState(true);
@@ -32,11 +33,11 @@ export const PoolBrowser: React.FC<PoolBrowserProps> = ({
useEffect(() => {
const loadPools = async () => {
if (!api || !isApiReady) return;
if (!assetHubApi || !isAssetHubReady) return;
try {
setLoading(true);
const poolsData = await fetchPools(api);
const poolsData = await fetchPools(assetHubApi);
setPools(poolsData);
} catch (error) {
if (import.meta.env.DEV) console.error('Failed to load pools:', error);
@@ -50,7 +51,7 @@ export const PoolBrowser: React.FC<PoolBrowserProps> = ({
// Refresh pools every 10 seconds
const interval = setInterval(loadPools, 10000);
return () => clearInterval(interval);
}, [api, isApiReady]);
}, [assetHubApi, isAssetHubReady]);
const filteredPools = pools.filter((pool) => {
if (!searchTerm) return true;
+23 -22
View File
@@ -32,7 +32,8 @@ const USER_TOKENS = [
] as const;
export const SwapInterface: React.FC<SwapInterfaceProps> = ({ pools }) => {
const { api, isApiReady } = usePezkuwi();
// Use Asset Hub API for DEX operations
const { assetHubApi, isAssetHubReady } = usePezkuwi();
const { account, signer } = useWallet();
const { toast } = useToast();
@@ -73,12 +74,12 @@ export const SwapInterface: React.FC<SwapInterfaceProps> = ({ pools }) => {
// Fetch balances
useEffect(() => {
const fetchBalances = async () => {
if (!api || !isApiReady || !account) return;
if (!assetHubApi || !isAssetHubReady || !account) return;
// For HEZ, fetch native balance (not wHEZ asset balance)
if (fromToken === 'HEZ') {
try {
const balance = await api.query.system.account(account);
const balance = await assetHubApi.query.system.account(account);
const freeBalance = balance.data.free.toString();
setFromBalance(freeBalance);
} catch (error) {
@@ -87,7 +88,7 @@ export const SwapInterface: React.FC<SwapInterfaceProps> = ({ pools }) => {
}
} else if (fromAssetId !== null) {
try {
const balanceData = await api.query.assets.account(fromAssetId, account);
const balanceData = await assetHubApi.query.assets.account(fromAssetId, account);
setFromBalance(balanceData.isSome ? balanceData.unwrap().balance.toString() : '0');
} catch (error) {
if (import.meta.env.DEV) console.error('Failed to fetch from balance:', error);
@@ -98,7 +99,7 @@ export const SwapInterface: React.FC<SwapInterfaceProps> = ({ pools }) => {
// For HEZ, fetch native balance
if (toToken === 'HEZ') {
try {
const balance = await api.query.system.account(account);
const balance = await assetHubApi.query.system.account(account);
const freeBalance = balance.data.free.toString();
setToBalance(freeBalance);
} catch (error) {
@@ -107,7 +108,7 @@ export const SwapInterface: React.FC<SwapInterfaceProps> = ({ pools }) => {
}
} else if (toAssetId !== null) {
try {
const balanceData = await api.query.assets.account(toAssetId, account);
const balanceData = await assetHubApi.query.assets.account(toAssetId, account);
setToBalance(balanceData.isSome ? balanceData.unwrap().balance.toString() : '0');
} catch (error) {
if (import.meta.env.DEV) console.error('Failed to fetch to balance:', error);
@@ -117,7 +118,7 @@ export const SwapInterface: React.FC<SwapInterfaceProps> = ({ pools }) => {
};
fetchBalances();
}, [api, isApiReady, account, fromToken, toToken, fromAssetId, toAssetId]);
}, [assetHubApi, isAssetHubReady, account, fromToken, toToken, fromAssetId, toAssetId]);
// Calculate output amount when input changes
useEffect(() => {
@@ -188,7 +189,7 @@ export const SwapInterface: React.FC<SwapInterfaceProps> = ({ pools }) => {
};
const handleConfirmSwap = async () => {
if (!api || !signer || !account || !fromTokenInfo || !toTokenInfo) {
if (!assetHubApi || !signer || !account || !fromTokenInfo || !toTokenInfo) {
toast({
title: 'Error',
description: 'Please connect your wallet',
@@ -228,55 +229,55 @@ export const SwapInterface: React.FC<SwapInterfaceProps> = ({ pools }) => {
if (fromToken === 'HEZ' && toToken === 'PEZ') {
// HEZ → PEZ: wrap(HEZ→wHEZ) then swap(wHEZ→PEZ)
const wrapTx = api.tx.tokenWrapper.wrap(amountIn.toString());
const swapTx = api.tx.assetConversion.swapExactTokensForTokens(
const wrapTx = assetHubApi.tx.tokenWrapper.wrap(amountIn.toString());
const swapTx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
[0, 1], // wHEZ → PEZ
amountIn.toString(),
minAmountOut.toString(),
account,
true
);
tx = api.tx.utility.batchAll([wrapTx, swapTx]);
tx = assetHubApi.tx.utility.batchAll([wrapTx, swapTx]);
} else if (fromToken === 'PEZ' && toToken === 'HEZ') {
// PEZ → HEZ: swap(PEZ→wHEZ) then unwrap(wHEZ→HEZ)
const swapTx = api.tx.assetConversion.swapExactTokensForTokens(
const swapTx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
[1, 0], // PEZ → wHEZ
amountIn.toString(),
minAmountOut.toString(),
account,
true
);
const unwrapTx = api.tx.tokenWrapper.unwrap(minAmountOut.toString());
tx = api.tx.utility.batchAll([swapTx, unwrapTx]);
const unwrapTx = assetHubApi.tx.tokenWrapper.unwrap(minAmountOut.toString());
tx = assetHubApi.tx.utility.batchAll([swapTx, unwrapTx]);
} else if (fromToken === 'HEZ') {
// HEZ → Any Asset: wrap(HEZ→wHEZ) then swap(wHEZ→Asset)
const wrapTx = api.tx.tokenWrapper.wrap(amountIn.toString());
const swapTx = api.tx.assetConversion.swapExactTokensForTokens(
const wrapTx = assetHubApi.tx.tokenWrapper.wrap(amountIn.toString());
const swapTx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
[0, toAssetId!], // wHEZ → target asset
amountIn.toString(),
minAmountOut.toString(),
account,
true
);
tx = api.tx.utility.batchAll([wrapTx, swapTx]);
tx = assetHubApi.tx.utility.batchAll([wrapTx, swapTx]);
} else if (toToken === 'HEZ') {
// Any Asset → HEZ: swap(Asset→wHEZ) then unwrap(wHEZ→HEZ)
const swapTx = api.tx.assetConversion.swapExactTokensForTokens(
const swapTx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
[fromAssetId!, 0], // source asset → wHEZ
amountIn.toString(),
minAmountOut.toString(),
account,
true
);
const unwrapTx = api.tx.tokenWrapper.unwrap(minAmountOut.toString());
tx = api.tx.utility.batchAll([swapTx, unwrapTx]);
const unwrapTx = assetHubApi.tx.tokenWrapper.unwrap(minAmountOut.toString());
tx = assetHubApi.tx.utility.batchAll([swapTx, unwrapTx]);
} else {
// Direct swap between assets (PEZ ↔ USDT, etc.)
tx = api.tx.assetConversion.swapExactTokensForTokens(
tx = assetHubApi.tx.assetConversion.swapExactTokensForTokens(
[fromAssetId!, toAssetId!],
amountIn.toString(),
minAmountOut.toString(),
@@ -294,7 +295,7 @@ export const SwapInterface: React.FC<SwapInterfaceProps> = ({ pools }) => {
if (status.isInBlock) {
if (dispatchError) {
if (dispatchError.isModule) {
const decoded = api.registry.findMetaError(dispatchError.asModule);
const decoded = assetHubApi.registry.findMetaError(dispatchError.asModule);
setErrorMessage(`${decoded.section}.${decoded.name}: ${decoded.docs}`);
} else {
setErrorMessage(dispatchError.toString());
@@ -34,7 +34,8 @@ export const XCMBridgeSetupModal: React.FC<XCMBridgeSetupModalProps> = ({
onClose,
onSuccess,
}) => {
const { api, isApiReady } = usePezkuwi();
// Use Asset Hub API for DEX operations
const { assetHubApi, isAssetHubReady } = usePezkuwi();
const { account, signer } = useWallet();
const { toast } = useToast();
@@ -52,7 +53,7 @@ export const XCMBridgeSetupModal: React.FC<XCMBridgeSetupModalProps> = ({
* Perform initial status check
*/
const performInitialCheck = useCallback(async () => {
if (!api || !isApiReady) return;
if (!assetHubApi || !isAssetHubReady) return;
setStep('checking');
setStatusMessage('Checking bridge status...');
@@ -75,7 +76,7 @@ export const XCMBridgeSetupModal: React.FC<XCMBridgeSetupModalProps> = ({
setErrorMessage(error instanceof Error ? error.message : 'Status check failed');
setStep('error');
}
}, [api, isApiReady]);
}, [assetHubApi, isAssetHubReady]);
// Reset when modal opens/closes
useEffect(() => {
@@ -86,17 +87,17 @@ export const XCMBridgeSetupModal: React.FC<XCMBridgeSetupModalProps> = ({
setShowPoolCreation(false);
} else {
// Auto-check status when opened
if (api && isApiReady && account) {
if (assetHubApi && isAssetHubReady && account) {
performInitialCheck();
}
}
}, [isOpen, api, isApiReady, account, performInitialCheck]);
}, [isOpen, assetHubApi, isAssetHubReady, account, performInitialCheck]);
/**
* Configure XCM bridge
*/
const handleConfigureBridge = async () => {
if (!api || !isApiReady || !signer || !account) {
if (!assetHubApi || !isAssetHubReady || !signer || !account) {
toast({
title: 'Error',
description: 'Please connect your wallet',
@@ -142,7 +143,7 @@ export const XCMBridgeSetupModal: React.FC<XCMBridgeSetupModalProps> = ({
* Create wUSDT/HEZ pool
*/
const handleCreatePool = async () => {
if (!api || !isApiReady || !signer || !account) {
if (!assetHubApi || !isAssetHubReady || !signer || !account) {
toast({
title: 'Error',
description: 'Please connect your wallet',