adding actual amounts and fees to confirmation pages for swap, stake and unstake
This commit is contained in:
@@ -7,8 +7,8 @@ import { Input } from '@/components/ui/input';
|
|||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { ChevronDown, CheckCircle, XCircle, Loader2, ArrowDownUp } from 'lucide-react';
|
import { ChevronDown, CheckCircle, XCircle, Loader2, ArrowDownUp } from 'lucide-react';
|
||||||
import { useAccount } from 'wagmi';
|
import { useAccount } from 'wagmi';
|
||||||
import { useGetAllPools, useTokenDetails, useSwapMintAmounts, useBurnSwapAmounts, useLPTokenBalance, type PoolDetails, type TokenDetails } from '@/hooks/usePartyPlanner';
|
import { useGetAllPools, useTokenDetails, useSwapMintAmounts, useBurnSwapAmounts, useLPTokenBalance, type PoolDetails, type TokenDetails, type BurnSwapAmounts } from '@/hooks/usePartyPlanner';
|
||||||
import { useSwapMint, useBurnSwap } from '@/hooks/usePartyPool';
|
import { useSwapMint, useBurnSwap, type ActualSwapMintAmounts, type ActualBurnSwapAmounts } from '@/hooks/usePartyPool';
|
||||||
import { formatUnits, parseUnits } from 'viem';
|
import { formatUnits, parseUnits } from 'viem';
|
||||||
import IPartyPoolABI from '@/contracts/IPartyPoolABI';
|
import IPartyPoolABI from '@/contracts/IPartyPoolABI';
|
||||||
|
|
||||||
@@ -30,6 +30,8 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
|
|||||||
const [isTokenDropdownOpen, setIsTokenDropdownOpen] = useState(false);
|
const [isTokenDropdownOpen, setIsTokenDropdownOpen] = useState(false);
|
||||||
const [transactionStatus, setTransactionStatus] = useState<TransactionStatus>('idle');
|
const [transactionStatus, setTransactionStatus] = useState<TransactionStatus>('idle');
|
||||||
const [transactionError, setTransactionError] = useState<string | null>(null);
|
const [transactionError, setTransactionError] = useState<string | null>(null);
|
||||||
|
const [actualSwapMintAmounts, setActualSwapMintAmounts] = useState<ActualSwapMintAmounts | null>(null);
|
||||||
|
const [actualBurnSwapAmounts, setActualBurnSwapAmounts] = useState<ActualBurnSwapAmounts | null>(null);
|
||||||
const poolDropdownRef = useRef<HTMLDivElement>(null);
|
const poolDropdownRef = useRef<HTMLDivElement>(null);
|
||||||
const tokenDropdownRef = useRef<HTMLDivElement>(null);
|
const tokenDropdownRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
@@ -152,21 +154,31 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (mode === 'stake') {
|
if (mode === 'stake') {
|
||||||
// Execute the swap mint transaction
|
// Execute the swap mint transaction and capture actual amounts
|
||||||
await executeSwapMint(
|
const result = await executeSwapMint(
|
||||||
selectedPool.address,
|
selectedPool.address,
|
||||||
selectedToken.address,
|
selectedToken.address,
|
||||||
inputTokenIndex,
|
inputTokenIndex,
|
||||||
maxAmountIn
|
maxAmountIn
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Store actual swap mint amounts if available
|
||||||
|
if (result?.actualSwapMintAmounts) {
|
||||||
|
setActualSwapMintAmounts(result.actualSwapMintAmounts);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Execute the burn swap transaction
|
// Execute the burn swap transaction and capture actual amounts
|
||||||
await executeBurnSwap(
|
const result = await executeBurnSwap(
|
||||||
selectedPool.address,
|
selectedPool.address,
|
||||||
maxAmountIn,
|
maxAmountIn,
|
||||||
inputTokenIndex,
|
inputTokenIndex,
|
||||||
false // unwrap = false by default
|
false // unwrap = false by default
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Store actual burn swap amounts if available
|
||||||
|
if (result?.actualBurnSwapAmounts) {
|
||||||
|
setActualBurnSwapAmounts(result.actualBurnSwapAmounts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setTransactionStatus('success');
|
setTransactionStatus('success');
|
||||||
@@ -490,7 +502,13 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
|
|||||||
<div className="flex justify-between text-sm">
|
<div className="flex justify-between text-sm">
|
||||||
<span className="text-muted-foreground">{t('stake.amountOut')}:</span>
|
<span className="text-muted-foreground">{t('stake.amountOut')}:</span>
|
||||||
<span className="font-medium">
|
<span className="font-medium">
|
||||||
{burnSwapLoading ? 'Calculating...' : `${formatUnits(burnSwapAmounts, selectedToken.decimals)} ${selectedToken.symbol}`}
|
{burnSwapLoading ? 'Calculating...' : `${Number(formatUnits(burnSwapAmounts.amountOut, selectedToken.decimals)).toLocaleString('en-US', { maximumFractionDigits: 6 })} ${selectedToken.symbol}`}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between text-sm">
|
||||||
|
<span className="text-muted-foreground">{t('stake.fee')}:</span>
|
||||||
|
<span className="font-medium">
|
||||||
|
{burnSwapLoading ? 'Calculating...' : `${Number(formatUnits(burnSwapAmounts.outFee, selectedToken.decimals)).toLocaleString('en-US', { maximumFractionDigits: 6 })} ${selectedToken.symbol}`}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -538,12 +556,82 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
|
|||||||
<h3 className="text-xl font-semibold text-center">
|
<h3 className="text-xl font-semibold text-center">
|
||||||
{mode === 'stake' ? 'Stake Confirmed!' : 'Unstake Confirmed!'}
|
{mode === 'stake' ? 'Stake Confirmed!' : 'Unstake Confirmed!'}
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-sm text-muted-foreground text-center">
|
|
||||||
{mode === 'stake'
|
{/* Display actual amounts or estimates */}
|
||||||
? `Successfully staked ${stakeAmount} ${selectedToken?.symbol} to ${selectedPool?.symbol}`
|
{mode === 'stake' ? (
|
||||||
: `Successfully unstaked ${stakeAmount} ${selectedPool?.symbol} LP for ${selectedToken?.symbol}`
|
// Stake mode success message
|
||||||
}
|
<div className="w-full space-y-3">
|
||||||
</p>
|
{actualSwapMintAmounts && selectedToken && selectedPool ? (
|
||||||
|
// Show actual amounts from transaction
|
||||||
|
<>
|
||||||
|
<div className="flex justify-between text-sm">
|
||||||
|
<span className="text-muted-foreground">Token Used:</span>
|
||||||
|
<span className="font-medium">{formatUnits(actualSwapMintAmounts.amountInUsed, selectedToken.decimals)} {selectedToken.symbol}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between text-sm">
|
||||||
|
<span className="text-muted-foreground">LP Received:</span>
|
||||||
|
<span className="font-medium">{formatUnits(actualSwapMintAmounts.lpMinted, 18)} {selectedPool.symbol}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between text-sm">
|
||||||
|
<span className="text-muted-foreground">LP Fee:</span>
|
||||||
|
<span className="font-medium">{formatUnits(actualSwapMintAmounts.lpFee, selectedToken.decimals)} {selectedToken.symbol}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between text-sm">
|
||||||
|
<span className="text-muted-foreground">Protocol Fee:</span>
|
||||||
|
<span className="font-medium">{formatUnits(actualSwapMintAmounts.protocolFee, selectedToken.decimals)} {selectedToken.symbol}</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
// Fallback to estimates
|
||||||
|
<>
|
||||||
|
<p className="text-sm text-muted-foreground text-center">
|
||||||
|
Successfully staked {stakeAmount} {selectedToken?.symbol} to {selectedPool?.symbol}
|
||||||
|
<br />
|
||||||
|
<span className="text-xs italic opacity-70">
|
||||||
|
*Disclaimer: This is an estimate from the protocol. The actual amounts might be slightly different due to slippage.
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
// Unstake mode success message
|
||||||
|
<div className="w-full space-y-3">
|
||||||
|
{actualBurnSwapAmounts && selectedToken && selectedPool ? (
|
||||||
|
// Show actual amounts from transaction
|
||||||
|
<>
|
||||||
|
<div className="flex justify-between text-sm">
|
||||||
|
<span className="text-muted-foreground">LP Burned:</span>
|
||||||
|
<span className="font-medium">{formatUnits(actualBurnSwapAmounts.amountIn, 18)} {selectedPool.symbol}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between text-sm">
|
||||||
|
<span className="text-muted-foreground">Token Received:</span>
|
||||||
|
<span className="font-medium">{formatUnits(actualBurnSwapAmounts.amountOut, selectedToken.decimals)} {selectedToken.symbol}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between text-sm">
|
||||||
|
<span className="text-muted-foreground">LP Fee:</span>
|
||||||
|
<span className="font-medium">{formatUnits(actualBurnSwapAmounts.lpFee, selectedToken.decimals)} {selectedToken.symbol}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between text-sm">
|
||||||
|
<span className="text-muted-foreground">Protocol Fee:</span>
|
||||||
|
<span className="font-medium">{formatUnits(actualBurnSwapAmounts.protocolFee, selectedToken.decimals)} {selectedToken.symbol}</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
// Fallback to estimates
|
||||||
|
<>
|
||||||
|
<p className="text-sm text-muted-foreground text-center">
|
||||||
|
Successfully unstaked {stakeAmount} {selectedPool?.symbol} LP for {selectedToken?.symbol}
|
||||||
|
<br />
|
||||||
|
<span className="text-xs italic opacity-70">
|
||||||
|
*Disclaimer: This is an estimate from the protocol. The actual amounts might be slightly different due to slippage.
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onClick={handleCloseModal}
|
onClick={handleCloseModal}
|
||||||
className="w-full mt-4"
|
className="w-full mt-4"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { Button } from '@/components/ui/button';
|
|||||||
import { ArrowDownUp, ChevronDown, Settings, CheckCircle, XCircle, Loader2 } from 'lucide-react';
|
import { ArrowDownUp, ChevronDown, Settings, CheckCircle, XCircle, Loader2 } from 'lucide-react';
|
||||||
import { useAccount } from 'wagmi';
|
import { useAccount } from 'wagmi';
|
||||||
import { useTokenDetails, useGetPoolsByToken, type TokenDetails } from '@/hooks/usePartyPlanner';
|
import { useTokenDetails, useGetPoolsByToken, type TokenDetails } from '@/hooks/usePartyPlanner';
|
||||||
import { useSwapAmounts, useSwap, selectBestSwapRoute } from '@/hooks/usePartyPool';
|
import { useSwapAmounts, useSwap, selectBestSwapRoute, type ActualSwapAmounts } from '@/hooks/usePartyPool';
|
||||||
import { formatUnits, parseUnits } from 'viem';
|
import { formatUnits, parseUnits } from 'viem';
|
||||||
import { SwapReviewModal } from './swap-review-modal';
|
import { SwapReviewModal } from './swap-review-modal';
|
||||||
|
|
||||||
@@ -28,6 +28,7 @@ export function SwapForm() {
|
|||||||
const [isReviewModalOpen, setIsReviewModalOpen] = useState(false);
|
const [isReviewModalOpen, setIsReviewModalOpen] = useState(false);
|
||||||
const [transactionStatus, setTransactionStatus] = useState<TransactionStatus>('idle');
|
const [transactionStatus, setTransactionStatus] = useState<TransactionStatus>('idle');
|
||||||
const [transactionError, setTransactionError] = useState<string | null>(null);
|
const [transactionError, setTransactionError] = useState<string | null>(null);
|
||||||
|
const [actualSwapAmounts, setActualSwapAmounts] = useState<ActualSwapAmounts | null>(null);
|
||||||
const fromDropdownRef = useRef<HTMLDivElement>(null);
|
const fromDropdownRef = useRef<HTMLDivElement>(null);
|
||||||
const toDropdownRef = useRef<HTMLDivElement>(null);
|
const toDropdownRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
@@ -114,8 +115,8 @@ export function SwapForm() {
|
|||||||
// Use the user's input directly as maxAmountIn
|
// Use the user's input directly as maxAmountIn
|
||||||
const maxAmountIn = parseUnits(fromAmount, selectedFromToken.decimals);
|
const maxAmountIn = parseUnits(fromAmount, selectedFromToken.decimals);
|
||||||
|
|
||||||
// Execute the swap
|
// Execute the swap and capture actual amounts from the transaction
|
||||||
await executeSwap(
|
const result = await executeSwap(
|
||||||
bestRoute.poolAddress,
|
bestRoute.poolAddress,
|
||||||
selectedFromToken.address,
|
selectedFromToken.address,
|
||||||
bestRoute.inputTokenIndex,
|
bestRoute.inputTokenIndex,
|
||||||
@@ -124,6 +125,11 @@ export function SwapForm() {
|
|||||||
currentSlippage
|
currentSlippage
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Store the actual swap amounts if available
|
||||||
|
if (result?.actualSwapAmounts) {
|
||||||
|
setActualSwapAmounts(result.actualSwapAmounts);
|
||||||
|
}
|
||||||
|
|
||||||
setTransactionStatus('success');
|
setTransactionStatus('success');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Swap failed:', err);
|
console.error('Swap failed:', err);
|
||||||
@@ -466,9 +472,43 @@ export function SwapForm() {
|
|||||||
<div className="flex flex-col items-center space-y-4">
|
<div className="flex flex-col items-center space-y-4">
|
||||||
<CheckCircle className="h-16 w-16 text-green-500" />
|
<CheckCircle className="h-16 w-16 text-green-500" />
|
||||||
<h3 className="text-xl font-semibold text-center">Swap Confirmed!</h3>
|
<h3 className="text-xl font-semibold text-center">Swap Confirmed!</h3>
|
||||||
<p className="text-sm text-muted-foreground text-center">
|
|
||||||
Successfully swapped {fromAmount} {selectedFromToken?.symbol} to {toAmount} {selectedToToken?.symbol}
|
{/* Display actual amounts or estimates */}
|
||||||
</p>
|
<div className="w-full space-y-3">
|
||||||
|
{actualSwapAmounts && selectedFromToken && selectedToToken ? (
|
||||||
|
// Show actual amounts from transaction
|
||||||
|
<>
|
||||||
|
<div className="flex justify-between text-sm">
|
||||||
|
<span className="text-muted-foreground">Swapped:</span>
|
||||||
|
<span className="font-medium">{formatUnits(actualSwapAmounts.amountIn, selectedFromToken.decimals)} {selectedFromToken.symbol}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between text-sm">
|
||||||
|
<span className="text-muted-foreground">Received:</span>
|
||||||
|
<span className="font-medium">{formatUnits(actualSwapAmounts.amountOut, selectedToToken.decimals)} {selectedToToken.symbol}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between text-sm">
|
||||||
|
<span className="text-muted-foreground">LP Fee:</span>
|
||||||
|
<span className="font-medium">{formatUnits(actualSwapAmounts.lpFee, selectedFromToken.decimals)} {selectedFromToken.symbol}</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex justify-between text-sm">
|
||||||
|
<span className="text-muted-foreground">Protocol Fee:</span>
|
||||||
|
<span className="font-medium">{formatUnits(actualSwapAmounts.protocolFee, selectedFromToken.decimals)} {selectedFromToken.symbol}</span>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
// Fallback to estimates
|
||||||
|
<>
|
||||||
|
<p className="text-sm text-muted-foreground text-center">
|
||||||
|
Successfully swapped {fromAmount} {selectedFromToken?.symbol} to {toAmount} {selectedToToken?.symbol}
|
||||||
|
<br />
|
||||||
|
<span className="text-xs italic opacity-70">
|
||||||
|
*Disclaimer: This is an estimate from the protocol. The actual amounts might be slightly different due to slippage.
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
onClick={handleCloseModal}
|
onClick={handleCloseModal}
|
||||||
className="w-full mt-4"
|
className="w-full mt-4"
|
||||||
|
|||||||
@@ -195,7 +195,12 @@ const IPartyPoolABI = [
|
|||||||
],
|
],
|
||||||
"outputs": [
|
"outputs": [
|
||||||
{
|
{
|
||||||
"name": "amountOutUint",
|
"name": "amountOut",
|
||||||
|
"type": "uint256",
|
||||||
|
"internalType": "uint256"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "outFee",
|
||||||
"type": "uint256",
|
"type": "uint256",
|
||||||
"internalType": "uint256"
|
"internalType": "uint256"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -448,6 +448,11 @@ export interface SwapMintAmounts {
|
|||||||
lpMinted: bigint;
|
lpMinted: bigint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BurnSwapAmounts {
|
||||||
|
amountOut: bigint;
|
||||||
|
outFee: bigint;
|
||||||
|
}
|
||||||
|
|
||||||
export function useSwapMintAmounts(
|
export function useSwapMintAmounts(
|
||||||
poolAddress: `0x${string}` | undefined,
|
poolAddress: `0x${string}` | undefined,
|
||||||
inputTokenIndex: number | undefined,
|
inputTokenIndex: number | undefined,
|
||||||
@@ -531,7 +536,7 @@ export function useBurnSwapAmounts(
|
|||||||
) {
|
) {
|
||||||
const publicClient = usePublicClient();
|
const publicClient = usePublicClient();
|
||||||
const [mounted, setMounted] = useState(false);
|
const [mounted, setMounted] = useState(false);
|
||||||
const [burnSwapAmounts, setBurnSwapAmounts] = useState<bigint | null>(null);
|
const [burnSwapAmounts, setBurnSwapAmounts] = useState<BurnSwapAmounts | null>(null);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
@@ -567,15 +572,43 @@ export function useBurnSwapAmounts(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call burnSwapAmounts function
|
// Log inputs
|
||||||
|
console.log('🔍 burnSwapAmounts INPUTS:', {
|
||||||
|
chainId: chainId.toString(),
|
||||||
|
rpcUrl: publicClient.transport?.url || 'Unknown',
|
||||||
|
poolAddress,
|
||||||
|
lpAmount: lpAmount.toString(),
|
||||||
|
inputTokenIndex,
|
||||||
|
viewerAddress,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Call burnSwapAmounts function - returns [amountOut, outFee]
|
||||||
const result = await publicClient.readContract({
|
const result = await publicClient.readContract({
|
||||||
address: viewerAddress as `0x${string}`,
|
address: viewerAddress as `0x${string}`,
|
||||||
abi: IPartyPoolViewerABI,
|
abi: IPartyPoolViewerABI,
|
||||||
functionName: 'burnSwapAmounts',
|
functionName: 'burnSwapAmounts',
|
||||||
args: [poolAddress, lpAmount, BigInt(inputTokenIndex)],
|
args: [poolAddress, lpAmount, BigInt(inputTokenIndex)],
|
||||||
}) as bigint;
|
}) as readonly [bigint, bigint];
|
||||||
|
|
||||||
setBurnSwapAmounts(result);
|
// Log raw result
|
||||||
|
console.log('📊 burnSwapAmounts RAW RESULT:', {
|
||||||
|
resultArray: result,
|
||||||
|
amountOut: result[0].toString(),
|
||||||
|
outFee: result[1].toString(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const parsedAmounts = {
|
||||||
|
amountOut: result[0],
|
||||||
|
outFee: result[1],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Log parsed result
|
||||||
|
console.log('✅ burnSwapAmounts PARSED:', {
|
||||||
|
amountOut: parsedAmounts.amountOut.toString(),
|
||||||
|
outFee: parsedAmounts.outFee.toString(),
|
||||||
|
});
|
||||||
|
|
||||||
|
setBurnSwapAmounts(parsedAmounts);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error calling burnSwapAmounts:', err);
|
console.error('Error calling burnSwapAmounts:', err);
|
||||||
setError(err instanceof Error ? err.message : 'Failed to fetch burn swap amounts');
|
setError(err instanceof Error ? err.message : 'Failed to fetch burn swap amounts');
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import { useState, useEffect, useCallback } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import { usePublicClient, useWalletClient } from 'wagmi';
|
import { usePublicClient, useWalletClient } from 'wagmi';
|
||||||
|
import { decodeEventLog } from 'viem';
|
||||||
import IPartyPoolABI from '@/contracts/IPartyPoolABI';
|
import IPartyPoolABI from '@/contracts/IPartyPoolABI';
|
||||||
import chainInfo from '../../../lmsr-amm/liqp-deployments.json';
|
import chainInfo from '../../../lmsr-amm/liqp-deployments.json';
|
||||||
import type { AvailableToken } from './usePartyPlanner';
|
import type { AvailableToken } from './usePartyPlanner';
|
||||||
@@ -189,6 +190,27 @@ export interface GasEstimate {
|
|||||||
estimatedCostUsd: string;
|
estimatedCostUsd: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ActualSwapAmounts {
|
||||||
|
amountIn: bigint;
|
||||||
|
amountOut: bigint;
|
||||||
|
lpFee: bigint;
|
||||||
|
protocolFee: bigint;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ActualSwapMintAmounts {
|
||||||
|
amountInUsed: bigint;
|
||||||
|
lpMinted: bigint;
|
||||||
|
lpFee: bigint;
|
||||||
|
protocolFee: bigint;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ActualBurnSwapAmounts {
|
||||||
|
amountIn: bigint;
|
||||||
|
amountOut: bigint;
|
||||||
|
lpFee: bigint;
|
||||||
|
protocolFee: bigint;
|
||||||
|
}
|
||||||
|
|
||||||
export function useSwap() {
|
export function useSwap() {
|
||||||
const { data: walletClient } = useWalletClient();
|
const { data: walletClient } = useWalletClient();
|
||||||
const publicClient = usePublicClient();
|
const publicClient = usePublicClient();
|
||||||
@@ -338,7 +360,46 @@ export function useSwap() {
|
|||||||
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
||||||
console.log('✅ Swap transaction confirmed:', receipt);
|
console.log('✅ Swap transaction confirmed:', receipt);
|
||||||
|
|
||||||
return receipt;
|
// Parse the Swap event from the receipt logs
|
||||||
|
let actualSwapAmounts: ActualSwapAmounts | null = null;
|
||||||
|
for (const log of receipt.logs) {
|
||||||
|
try {
|
||||||
|
const decodedLog = decodeEventLog({
|
||||||
|
abi: IPartyPoolABI,
|
||||||
|
data: log.data,
|
||||||
|
topics: log.topics,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (decodedLog.eventName === 'Swap') {
|
||||||
|
const { amountIn, amountOut, lpFee, protocolFee } = decodedLog.args as {
|
||||||
|
amountIn: bigint;
|
||||||
|
amountOut: bigint;
|
||||||
|
lpFee: bigint;
|
||||||
|
protocolFee: bigint;
|
||||||
|
};
|
||||||
|
|
||||||
|
actualSwapAmounts = {
|
||||||
|
amountIn,
|
||||||
|
amountOut,
|
||||||
|
lpFee,
|
||||||
|
protocolFee,
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('📊 Actual swap amounts from event:', {
|
||||||
|
amountIn: amountIn.toString(),
|
||||||
|
amountOut: amountOut.toString(),
|
||||||
|
lpFee: lpFee.toString(),
|
||||||
|
protocolFee: protocolFee.toString(),
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// Skip logs that don't match our ABI
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { receipt, actualSwapAmounts };
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const errorMessage = err instanceof Error ? err.message : 'Swap failed';
|
const errorMessage = err instanceof Error ? err.message : 'Swap failed';
|
||||||
setSwapError(errorMessage);
|
setSwapError(errorMessage);
|
||||||
@@ -446,7 +507,46 @@ export function useSwapMint() {
|
|||||||
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
||||||
console.log('✅ SwapMint transaction confirmed:', receipt);
|
console.log('✅ SwapMint transaction confirmed:', receipt);
|
||||||
|
|
||||||
return receipt;
|
// Parse the SwapMint event from the receipt logs
|
||||||
|
let actualSwapMintAmounts: ActualSwapMintAmounts | null = null;
|
||||||
|
for (const log of receipt.logs) {
|
||||||
|
try {
|
||||||
|
const decodedLog = decodeEventLog({
|
||||||
|
abi: IPartyPoolABI,
|
||||||
|
data: log.data,
|
||||||
|
topics: log.topics,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (decodedLog.eventName === 'SwapMint') {
|
||||||
|
const { amountIn, amountOut, lpFee, protocolFee } = decodedLog.args as {
|
||||||
|
amountIn: bigint;
|
||||||
|
amountOut: bigint;
|
||||||
|
lpFee: bigint;
|
||||||
|
protocolFee: bigint;
|
||||||
|
};
|
||||||
|
|
||||||
|
actualSwapMintAmounts = {
|
||||||
|
amountInUsed: amountIn,
|
||||||
|
lpMinted: amountOut,
|
||||||
|
lpFee,
|
||||||
|
protocolFee,
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('📊 Actual swap mint amounts from event:', {
|
||||||
|
amountInUsed: amountIn.toString(),
|
||||||
|
lpMinted: amountOut.toString(),
|
||||||
|
lpFee: lpFee.toString(),
|
||||||
|
protocolFee: protocolFee.toString(),
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// Skip logs that don't match our ABI
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { receipt, actualSwapMintAmounts };
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const errorMessage = err instanceof Error ? err.message : 'SwapMint failed';
|
const errorMessage = err instanceof Error ? err.message : 'SwapMint failed';
|
||||||
setSwapMintError(errorMessage);
|
setSwapMintError(errorMessage);
|
||||||
@@ -553,7 +653,46 @@ export function useBurnSwap() {
|
|||||||
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
||||||
console.log('✅ BurnSwap transaction confirmed:', receipt);
|
console.log('✅ BurnSwap transaction confirmed:', receipt);
|
||||||
|
|
||||||
return receipt;
|
// Parse the BurnSwap event from the receipt logs
|
||||||
|
let actualBurnSwapAmounts: ActualBurnSwapAmounts | null = null;
|
||||||
|
for (const log of receipt.logs) {
|
||||||
|
try {
|
||||||
|
const decodedLog = decodeEventLog({
|
||||||
|
abi: IPartyPoolABI,
|
||||||
|
data: log.data,
|
||||||
|
topics: log.topics,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (decodedLog.eventName === 'BurnSwap') {
|
||||||
|
const { amountIn, amountOut, lpFee, protocolFee } = decodedLog.args as {
|
||||||
|
amountIn: bigint;
|
||||||
|
amountOut: bigint;
|
||||||
|
lpFee: bigint;
|
||||||
|
protocolFee: bigint;
|
||||||
|
};
|
||||||
|
|
||||||
|
actualBurnSwapAmounts = {
|
||||||
|
amountIn,
|
||||||
|
amountOut,
|
||||||
|
lpFee,
|
||||||
|
protocolFee,
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log('📊 Actual burn swap amounts from event:', {
|
||||||
|
amountIn: amountIn.toString(),
|
||||||
|
amountOut: amountOut.toString(),
|
||||||
|
lpFee: lpFee.toString(),
|
||||||
|
protocolFee: protocolFee.toString(),
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
// Skip logs that don't match our ABI
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { receipt, actualBurnSwapAmounts };
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const errorMessage = err instanceof Error ? err.message : 'BurnSwap failed';
|
const errorMessage = err instanceof Error ? err.message : 'BurnSwap failed';
|
||||||
setBurnSwapError(errorMessage);
|
setBurnSwapError(errorMessage);
|
||||||
|
|||||||
Reference in New Issue
Block a user