diff --git a/src/components/swap-form.tsx b/src/components/swap-form.tsx
index a60788f..07c88d5 100644
--- a/src/components/swap-form.tsx
+++ b/src/components/swap-form.tsx
@@ -11,6 +11,7 @@ import { useTokenDetails, useGetPoolsByToken, type TokenDetails } from '@/hooks/
import { useSwapAmounts, useSwap, selectBestSwapRoute, type ActualSwapAmounts } from '@/hooks/usePartyPool';
import { formatUnits, parseUnits } from 'viem';
import { SwapReviewModal } from './swap-review-modal';
+import UniswapQuote from './uniswap-quote';
type TransactionStatus = 'idle' | 'pending' | 'success' | 'error';
@@ -404,6 +405,11 @@ export function SwapForm() {
)}
+ {/* Uniswap Quote */}
+ {fromAmount && (
+
+ )}
+
{/* Gas Estimate, Slippage, and Fees */}
{isConnected && fromAmount && toAmount && (
diff --git a/src/components/uniswap-quote.tsx b/src/components/uniswap-quote.tsx
new file mode 100644
index 0000000..7236b2b
--- /dev/null
+++ b/src/components/uniswap-quote.tsx
@@ -0,0 +1,234 @@
+'use client';
+
+import { useState, useEffect } from 'react';
+
+// ETH and SHIB addresses
+const ETH_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE';
+const SHIB_ADDRESS = '0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE';
+
+interface UniswapQuoteProps {
+ amountIn: string;
+}
+
+interface TokenPrices {
+ eth: number;
+ shib: number;
+}
+
+export default function UniswapQuote({ amountIn }: UniswapQuoteProps) {
+ const [quote, setQuote] = useState
(null);
+ const [loading, setLoading] = useState(false);
+ const [error, setError] = useState('');
+ const [prices, setPrices] = useState(null);
+
+ // Fetch token prices from CoinGecko
+ useEffect(() => {
+ const fetchPrices = async () => {
+ try {
+ const response = await fetch(
+ 'https://api.coingecko.com/api/v3/simple/price?ids=ethereum,shiba-inu&vs_currencies=usd'
+ );
+ const data = await response.json();
+ setPrices({
+ eth: data.ethereum.usd,
+ shib: data['shiba-inu'].usd
+ });
+ } catch (err) {
+ console.error('Failed to fetch prices:', err);
+ }
+ };
+
+ fetchPrices();
+ // Refresh prices every 30 seconds
+ const interval = setInterval(fetchPrices, 30000);
+ return () => clearInterval(interval);
+ }, []);
+
+ const getQuote = async () => {
+ if (!amountIn || parseFloat(amountIn) <= 0) {
+ setError('Please enter a valid amount');
+ return;
+ }
+
+ setLoading(true);
+ setError('');
+
+ try {
+ // Convert ETH amount to wei
+ const amountInWei = (parseFloat(amountIn) * 1e18).toString();
+
+ const response = await fetch('https://api.uniswap.org/v2/quote', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Origin': 'https://app.uniswap.org'
+ },
+ body: JSON.stringify({
+ amount: amountInWei,
+ tokenIn: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH
+ tokenInChainId: 1,
+ tokenOut: SHIB_ADDRESS,
+ tokenOutChainId: 1,
+ type: 'EXACT_INPUT',
+ configs: [
+ {
+ protocols: ['V2', 'V3', 'V4'],
+ enableUniversalRouter: true,
+ routingType: 'CLASSIC'
+ }
+ ]
+ })
+ });
+
+ if (!response.ok) throw new Error('Failed to fetch quote');
+
+ const data = await response.json();
+ console.log('Uniswap Quote:', data);
+ setQuote(data);
+ } catch (err: any) {
+ setError(err.message);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ const formatSHIB = (amount: string) => {
+ return (parseFloat(amount) / 1e18).toLocaleString('en-US', { maximumFractionDigits: 0 });
+ };
+
+ const getQuoteAmount = () => {
+ if (!quote) return '0';
+ // Handle nested quote structure
+ return quote.quote?.quote || quote.quote || '0';
+ };
+
+ const calculateCostBreakdown = () => {
+ if (!quote || !prices) return null;
+
+ const ethAmount = parseFloat(amountIn);
+ const tradeValueUSD = ethAmount * prices.eth;
+
+ // Access nested quote object
+ const quoteData = quote.quote || quote;
+
+ // 1. Gas Cost
+ const gasCostUSD = parseFloat(quoteData.gasUseEstimateUSD || '0');
+
+ // 2. Price Impact
+ const priceImpactPercent = parseFloat(quoteData.priceImpact || '0');
+ const priceImpactUSD = (priceImpactPercent / 100) * tradeValueUSD;
+
+ // 3. Trading Fees (estimate 0.3% for typical Uniswap pools)
+ const tradingFeePercent = 0.3;
+ const tradingFeeUSD = (tradingFeePercent / 100) * tradeValueUSD;
+
+ const totalCostUSD = gasCostUSD + priceImpactUSD + tradingFeeUSD;
+
+ console.log('Cost breakdown calc:', {
+ gasCostUSD,
+ priceImpactPercent,
+ priceImpactUSD,
+ tradingFeeUSD,
+ totalCostUSD,
+ tradeValueUSD,
+ quoteData
+ });
+
+ return {
+ gasCostUSD,
+ priceImpactPercent,
+ priceImpactUSD,
+ tradingFeePercent,
+ tradingFeeUSD,
+ totalCostUSD,
+ tradeValueUSD
+ };
+ };
+
+ const costBreakdown = calculateCostBreakdown();
+
+ return (
+
+
+
+ {error && (
+
+ {error}
+
+ )}
+
+ {quote && costBreakdown && (
+
+
+
You Get (SHIB)
+
+ {formatSHIB(getQuoteAmount())}
+
+
+
+ {/* Total Costs Breakdown */}
+
+
Total Costs Breakdown
+
+ {/* 1. Gas Cost */}
+
+
+ 1. Gas Cost (Network Fee)
+
+ ${costBreakdown.gasCostUSD.toFixed(2)} USD
+
+
+
+
+ {/* 2. Price Impact */}
+
+
+ 2. Price Impact
+
+ {costBreakdown.priceImpactPercent.toFixed(2)}%
+
+
+
+ Cost: ~${costBreakdown.priceImpactUSD.toFixed(2)} USD
+
+
+
+ {/* 3. Trading Fees */}
+
+
+ 3. Trading Fees (DEX Fees)
+
+ {costBreakdown.tradingFeePercent}%
+
+
+
+ ${costBreakdown.tradingFeeUSD.toFixed(2)} USD
+
+
+
+ {/* Total */}
+
+
+ Total Estimated Cost
+
+ ${costBreakdown.totalCostUSD.toFixed(2)} USD
+
+
+
+
+ {/* Trade Value Reference */}
+
+ Trade Value: ${costBreakdown.tradeValueUSD.toFixed(2)} USD
+
+
+
+ )}
+
+ );
+}