adding a stake form and approvals in both stake and swap form

This commit is contained in:
2025-10-28 11:27:26 -04:00
parent dbfdfbd4ab
commit 66e28ed08d
6 changed files with 752 additions and 33 deletions

View File

@@ -5,6 +5,7 @@ import { usePublicClient } from 'wagmi';
import chainInfo from '@/contracts/liqp-deployments.json';
import IPartyPlannerABI from '@/contracts/IPartyPlannerABI';
import IPartyPoolABI from '@/contracts/IPartyPoolABI';
import IPartyPoolViewerABI from '@/contracts/IPartyPoolViewerABI';
import { ERC20ABI } from '@/contracts/ERC20ABI';
export function useGetAllTokens(offset: number = 0, limit: number = 100) {
@@ -324,4 +325,201 @@ export function useTokenDetails(userAddress: `0x${string}` | undefined) {
loading,
error,
};
}
export interface PoolDetails {
address: `0x${string}`;
name: string;
symbol: string;
tokens: readonly `0x${string}`[];
}
export function useGetAllPools(offset: number = 0, limit: number = 100) {
const publicClient = usePublicClient();
const [mounted, setMounted] = useState(false);
const [pools, setPools] = useState<readonly `0x${string}`[] | null>(null);
const [poolDetails, setPoolDetails] = useState<PoolDetails[] | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
// Handle hydration for Next.js static export
useEffect(() => {
setMounted(true);
}, []);
useEffect(() => {
if (!mounted) return;
const fetchPools = async () => {
if (!publicClient) {
setLoading(false);
return;
}
try {
setLoading(true);
setError(null);
// Get chain ID and contract address
const chainId = await publicClient.getChainId();
const address = (chainInfo as Record<string, { v1: { PartyPlanner: string; PartyPoolViewer: string } }>)[chainId.toString()]?.v1?.PartyPlanner;
if (!address) {
setError('IPartyPlanner contract not found for current chain');
setPools([]);
setPoolDetails([]);
return;
}
// Call getAllPools function
const result = await publicClient.readContract({
address: address as `0x${string}`,
abi: IPartyPlannerABI,
functionName: 'getAllPools',
args: [BigInt(offset), BigInt(limit)],
});
setPools(result);
// Fetch details for each pool
const details: PoolDetails[] = [];
for (const poolAddress of result) {
try {
const [name, symbol, tokens] = await Promise.all([
publicClient.readContract({
address: poolAddress,
abi: ERC20ABI,
functionName: 'name',
}).catch(() => 'Unknown Pool'),
publicClient.readContract({
address: poolAddress,
abi: ERC20ABI,
functionName: 'symbol',
}).catch(() => 'POOL'),
publicClient.readContract({
address: poolAddress,
abi: IPartyPoolABI,
functionName: 'allTokens',
}).catch(() => [] as readonly `0x${string}`[]),
]);
details.push({
address: poolAddress,
name: name as string,
symbol: symbol as string,
tokens: tokens as readonly `0x${string}`[],
});
} catch (err) {
console.error('Error fetching pool details for', poolAddress, err);
// Add pool with fallback values
details.push({
address: poolAddress,
name: 'Unknown Pool',
symbol: 'POOL',
tokens: [],
});
}
}
setPoolDetails(details);
} catch (err) {
console.error('Error calling getAllPools:', err);
setError(err instanceof Error ? err.message : 'Failed to fetch pools');
} finally {
setLoading(false);
}
};
fetchPools();
}, [publicClient, mounted, offset, limit]);
return {
pools,
poolDetails,
loading,
error,
isReady: mounted,
};
}
export interface SwapMintAmounts {
amountInUsed: bigint;
fee: bigint;
lpMinted: bigint;
}
export function useSwapMintAmounts(
poolAddress: `0x${string}` | undefined,
inputTokenIndex: number | undefined,
maxAmountIn: bigint | undefined
) {
const publicClient = usePublicClient();
const [mounted, setMounted] = useState(false);
const [swapMintAmounts, setSwapMintAmounts] = useState<SwapMintAmounts | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
// Handle hydration for Next.js static export
useEffect(() => {
setMounted(true);
}, []);
useEffect(() => {
if (!mounted || !poolAddress || inputTokenIndex === undefined || !maxAmountIn || maxAmountIn === BigInt(0)) {
setLoading(false);
setSwapMintAmounts(null);
return;
}
const fetchSwapMintAmounts = async () => {
if (!publicClient) {
setLoading(false);
return;
}
try {
setLoading(true);
setError(null);
// Get chain ID and contract address
const chainId = await publicClient.getChainId();
const viewerAddress = (chainInfo as Record<string, { v1: { PartyPlanner: string; PartyPoolViewer: string } }>)[chainId.toString()]?.v1?.PartyPoolViewer;
if (!viewerAddress) {
setError('IPartyPoolViewer contract not found for current chain');
setSwapMintAmounts(null);
return;
}
// Call swapMintAmounts function
const result = await publicClient.readContract({
address: viewerAddress as `0x${string}`,
abi: IPartyPoolViewerABI,
functionName: 'swapMintAmounts',
args: [poolAddress, BigInt(inputTokenIndex), maxAmountIn],
}) as readonly [bigint, bigint, bigint];
setSwapMintAmounts({
amountInUsed: result[0],
fee: result[1],
lpMinted: result[2],
});
} catch (err) {
console.error('Error calling swapMintAmounts:', err);
setError(err instanceof Error ? err.message : 'Failed to fetch swap mint amounts');
setSwapMintAmounts(null);
} finally {
setLoading(false);
}
};
fetchSwapMintAmounts();
}, [publicClient, mounted, poolAddress, inputTokenIndex, maxAmountIn]);
return {
swapMintAmounts,
loading,
error,
isReady: mounted,
};
}