swap functionality

This commit is contained in:
2025-10-16 16:56:59 -04:00
parent 7ead103f86
commit f543b27620
2 changed files with 331 additions and 137 deletions

View File

@@ -7,9 +7,9 @@ import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { ArrowDownUp, ChevronDown } from 'lucide-react';
import { useAccount } from 'wagmi';
import { useTokenDetails, useGetPoolsByToken, type TokenDetails, type AvailableToken } from '@/hooks/usePartyPlanner';
import { useSwapAmounts } from '@/hooks/usePartyPool';
import { formatUnits } from 'viem';
import { useTokenDetails, useGetPoolsByToken, type TokenDetails } from '@/hooks/usePartyPlanner';
import { useSwapAmounts, useSwap, selectBestSwapRoute } from '@/hooks/usePartyPool';
import { formatUnits, parseUnits } from 'viem';
export function SwapForm() {
const { t } = useTranslation();
@@ -27,7 +27,7 @@ export function SwapForm() {
const toDropdownRef = useRef<HTMLDivElement>(null);
// Use the custom hook to get all token details with a single batched RPC call
const { tokenDetails, loading, error } = useTokenDetails(address);
const { tokenDetails, loading } = useTokenDetails(address);
// Get available tokens for the selected "from" token
const { availableTokens } = useGetPoolsByToken(selectedFromToken?.address);
@@ -43,26 +43,19 @@ export function SwapForm() {
return null;
}, [selectedFromToken, selectedToToken, availableTokens]);
// Get the current slippage value (either custom or preset)
const currentSlippage = isCustomSlippage ? parseFloat(customSlippage) || 0.5 : slippage;
// Calculate swap amounts for the selected token pair only
const { swapAmounts } = useSwapAmounts(
filteredAvailableTokens,
fromAmount,
selectedFromToken?.decimals || 18
selectedFromToken?.decimals || 18,
currentSlippage
);
// Trigger the hook to fetch data when address is available
useEffect(() => {
if (tokenDetails) {
// console.log('Token details loaded in swap-form');
}
}, [tokenDetails]);
// Log swap amounts only once when user selects the "to" token
useEffect(() => {
if (swapAmounts && swapAmounts.length > 0 && selectedFromToken && selectedToToken) {
console.log('Swap amounts for', selectedFromToken.symbol, '→', selectedToToken.symbol, ':', swapAmounts);
}
}, [selectedToToken]); // Only fires when selectedToToken changes
// Initialize swap hook
const { executeSwap, isSwapping } = useSwap();
// Update "You Receive" amount when swap calculation completes
useEffect(() => {
@@ -88,22 +81,41 @@ export function SwapForm() {
return () => document.removeEventListener('mousedown', handleClickOutside);
}, []);
// Calculate and log limit price when amount or slippage changes
useEffect(() => {
if (fromAmount && parseFloat(fromAmount) > 0) {
const amount = parseFloat(fromAmount);
const slippagePercent = isCustomSlippage ? parseFloat(customSlippage) || 0 : slippage;
const limitPrice = amount * (1 + slippagePercent / 100);
console.log('Limit Price:', limitPrice);
console.log('From Amount:', amount);
console.log('Slippage %:', slippagePercent);
console.log('Additional Amount from Slippage:', limitPrice - amount);
const handleSwap = async () => {
if (!swapAmounts || swapAmounts.length === 0) {
console.error('No swap amounts available');
return;
}
}, [fromAmount, slippage, customSlippage, isCustomSlippage]);
const handleSwap = () => {
// Swap logic will be implemented later
console.log('Swap clicked');
if (!selectedFromToken || !selectedToToken) {
console.error('Tokens not selected');
return;
}
try {
// Use the shared helper to select the best swap route
const bestRoute = selectBestSwapRoute(swapAmounts);
if (!bestRoute) {
console.error('No valid swap route found');
return;
}
// Convert fromAmount to Wei
const maxAmountIn = parseUnits(fromAmount, selectedFromToken.decimals);
// Execute the swap
await executeSwap(
bestRoute.poolAddress,
selectedFromToken.address,
bestRoute.inputTokenIndex,
bestRoute.outputTokenIndex,
maxAmountIn,
currentSlippage
);
} catch (err) {
console.error('Swap failed:', err);
}
};
const switchTokens = () => {
@@ -153,16 +165,13 @@ export function SwapForm() {
tokenDetails.map((token) => (
<button
key={token.address}
className="w-full px-4 py-3 text-left hover:bg-accent focus:bg-accent focus:outline-none flex items-center justify-between"
className="w-full px-4 py-3 text-left hover:bg-accent focus:bg-accent focus:outline-none"
onClick={() => {
setSelectedFromToken(token);
setIsFromDropdownOpen(false);
}}
>
<span className="font-medium">{token.symbol}</span>
<span className="text-sm text-muted-foreground">
{formatUnits(token.balance, token.decimals)}
</span>
</button>
))
) : (
@@ -232,16 +241,13 @@ export function SwapForm() {
.map((token) => (
<button
key={token.address}
className="w-full px-4 py-3 text-left hover:bg-accent focus:bg-accent focus:outline-none flex items-center justify-between"
className="w-full px-4 py-3 text-left hover:bg-accent focus:bg-accent focus:outline-none"
onClick={() => {
setSelectedToToken(token);
setIsToDropdownOpen(false);
}}
>
<span className="font-medium">{token.symbol}</span>
<span className="text-sm text-muted-foreground">
{formatUnits(token.balance, token.decimals)}
</span>
</button>
))
) : selectedFromToken ? (
@@ -308,9 +314,13 @@ export function SwapForm() {
<Button
className="w-full h-14 text-lg"
onClick={handleSwap}
disabled={!isConnected || !fromAmount || !toAmount}
disabled={!isConnected || !fromAmount || !toAmount || isSwapping}
>
{!isConnected ? t('swap.connectWalletToSwap') : t('swap.swapButton')}
{!isConnected
? t('swap.connectWalletToSwap')
: isSwapping
? 'Swapping...'
: t('swap.swapButton')}
</Button>
</CardContent>
</Card>