adding redeem only function for killed pools)
This commit is contained in:
@@ -49,6 +49,17 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
|
|||||||
// Fetch all pools using the new hook
|
// Fetch all pools using the new hook
|
||||||
const { poolDetails, loading: poolsLoading } = useGetAllPools();
|
const { poolDetails, loading: poolsLoading } = useGetAllPools();
|
||||||
|
|
||||||
|
// Filter pools based on mode: stake mode shows only working pools, unstake shows all
|
||||||
|
const filteredPools = useMemo(() => {
|
||||||
|
if (!poolDetails) return null;
|
||||||
|
if (mode === 'stake') {
|
||||||
|
// Stake mode: only show working (non-killed) pools
|
||||||
|
return poolDetails.filter(pool => !pool.isKilled);
|
||||||
|
}
|
||||||
|
// Unstake mode: show all pools (working + killed)
|
||||||
|
return poolDetails;
|
||||||
|
}, [poolDetails, mode]);
|
||||||
|
|
||||||
// Get token details for the user
|
// Get token details for the user
|
||||||
const { tokenDetails, loading: tokensLoading } = useTokenDetails(address);
|
const { tokenDetails, loading: tokensLoading } = useTokenDetails(address);
|
||||||
|
|
||||||
@@ -190,6 +201,14 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
|
|||||||
fetchTokenDetails();
|
fetchTokenDetails();
|
||||||
}, [publicClient, selectedPool, mode, redeemAll]);
|
}, [publicClient, selectedPool, mode, redeemAll]);
|
||||||
|
|
||||||
|
// Auto-enable Redeem All for killed pools in unstake mode
|
||||||
|
useEffect(() => {
|
||||||
|
if (mode === 'unstake' && selectedPool?.isKilled) {
|
||||||
|
setRedeemAll(true);
|
||||||
|
setSelectedToken(null); // Clear token selection for killed pools
|
||||||
|
}
|
||||||
|
}, [mode, selectedPool]);
|
||||||
|
|
||||||
// Close dropdowns when clicking outside
|
// Close dropdowns when clicking outside
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleClickOutside = (event: MouseEvent) => {
|
const handleClickOutside = (event: MouseEvent) => {
|
||||||
@@ -329,8 +348,8 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
|
|||||||
</Button>
|
</Button>
|
||||||
{isPoolDropdownOpen && (
|
{isPoolDropdownOpen && (
|
||||||
<div className="absolute z-50 w-full mt-2 bg-popover border rounded-md shadow-lg max-h-[300px] overflow-y-auto">
|
<div className="absolute z-50 w-full mt-2 bg-popover border rounded-md shadow-lg max-h-[300px] overflow-y-auto">
|
||||||
{poolDetails && poolDetails.length > 0 ? (
|
{filteredPools && filteredPools.length > 0 ? (
|
||||||
poolDetails.map((pool) => (
|
filteredPools.map((pool) => (
|
||||||
<button
|
<button
|
||||||
key={pool.address}
|
key={pool.address}
|
||||||
className="w-full px-4 py-3 text-left hover:bg-accent focus:bg-accent focus:outline-none"
|
className="w-full px-4 py-3 text-left hover:bg-accent focus:bg-accent focus:outline-none"
|
||||||
@@ -381,7 +400,14 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
|
|||||||
>
|
>
|
||||||
{selectedPool ? (
|
{selectedPool ? (
|
||||||
<div className="flex flex-col items-start">
|
<div className="flex flex-col items-start">
|
||||||
<span className="font-medium">{selectedPool.symbol}</span>
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="font-medium">{selectedPool.symbol}</span>
|
||||||
|
{selectedPool.isKilled && (
|
||||||
|
<span className="text-xs px-2 py-0.5 bg-orange-500/20 text-orange-600 dark:text-orange-400 border border-orange-500/30 rounded">
|
||||||
|
Redeem Only
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<span className="text-xs text-muted-foreground">{selectedPool.name}</span>
|
<span className="text-xs text-muted-foreground">{selectedPool.name}</span>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@@ -391,8 +417,8 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
|
|||||||
</Button>
|
</Button>
|
||||||
{isPoolDropdownOpen && (
|
{isPoolDropdownOpen && (
|
||||||
<div className="absolute z-50 w-full mt-2 bg-popover border rounded-md shadow-lg max-h-[300px] overflow-y-auto">
|
<div className="absolute z-50 w-full mt-2 bg-popover border rounded-md shadow-lg max-h-[300px] overflow-y-auto">
|
||||||
{poolDetails && poolDetails.length > 0 ? (
|
{filteredPools && filteredPools.length > 0 ? (
|
||||||
poolDetails.map((pool) => (
|
filteredPools.map((pool) => (
|
||||||
<button
|
<button
|
||||||
key={pool.address}
|
key={pool.address}
|
||||||
className="w-full px-4 py-3 text-left hover:bg-accent focus:bg-accent focus:outline-none"
|
className="w-full px-4 py-3 text-left hover:bg-accent focus:bg-accent focus:outline-none"
|
||||||
@@ -402,12 +428,19 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
|
|||||||
setSelectedToken(null);
|
setSelectedToken(null);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="flex justify-between items-center w-full">
|
<div className="flex justify-between items-center w-full gap-2">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col flex-1 min-w-0">
|
||||||
<span className="font-medium">{pool.symbol}</span>
|
<div className="flex items-center gap-2">
|
||||||
|
<span className="font-medium">{pool.symbol}</span>
|
||||||
|
{pool.isKilled && (
|
||||||
|
<span className="text-xs px-2 py-0.5 bg-orange-500/20 text-orange-600 dark:text-orange-400 border border-orange-500/30 rounded whitespace-nowrap">
|
||||||
|
Redeem Only
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<span className="text-xs text-muted-foreground">{pool.name}</span>
|
<span className="text-xs text-muted-foreground">{pool.name}</span>
|
||||||
</div>
|
</div>
|
||||||
{(pool.price || pool.tvl) && (
|
{!pool.isKilled && (pool.price || pool.tvl) && (
|
||||||
<div className="flex flex-col items-end">
|
<div className="flex flex-col items-end">
|
||||||
{pool.price && (
|
{pool.price && (
|
||||||
<span className="text-sm font-medium text-muted-foreground">{pool.price}</span>
|
<span className="text-sm font-medium text-muted-foreground">{pool.price}</span>
|
||||||
@@ -562,13 +595,15 @@ export function StakeForm({ defaultMode = 'stake' }: StakeFormProps) {
|
|||||||
size="sm"
|
size="sm"
|
||||||
className="h-6 px-2 text-xs"
|
className="h-6 px-2 text-xs"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
// Prevent toggling off for killed pools
|
||||||
|
if (selectedPool?.isKilled) return;
|
||||||
setRedeemAll(!redeemAll);
|
setRedeemAll(!redeemAll);
|
||||||
if (!redeemAll && lpBalance !== null) {
|
if (!redeemAll && lpBalance !== null) {
|
||||||
setStakeAmount(formatUnits(lpBalance, 18));
|
setStakeAmount(formatUnits(lpBalance, 18));
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
disabled={!selectedPool}
|
disabled={!selectedPool || selectedPool?.isKilled}
|
||||||
title="Burn entire LP token and receive all underlying tokens"
|
title={selectedPool?.isKilled ? "Killed pools can only use Redeem All mode" : "Burn entire LP token and receive all underlying tokens"}
|
||||||
>
|
>
|
||||||
{redeemAll ? 'Redeem All: ON' : 'Redeem All'}
|
{redeemAll ? 'Redeem All: ON' : 'Redeem All'}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -379,6 +379,7 @@ export interface PoolDetails {
|
|||||||
tokens: readonly `0x${string}`[];
|
tokens: readonly `0x${string}`[];
|
||||||
price?: string; // Formatted price string
|
price?: string; // Formatted price string
|
||||||
tvl?: string; // Formatted TVL string (e.g., "$1.2M")
|
tvl?: string; // Formatted TVL string (e.g., "$1.2M")
|
||||||
|
isKilled: boolean; // Whether the pool has been killed
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useGetAllPools(offset: number = 0, limit: number = 100) {
|
export function useGetAllPools(offset: number = 0, limit: number = 100) {
|
||||||
@@ -457,10 +458,12 @@ export function useGetAllPools(offset: number = 0, limit: number = 100) {
|
|||||||
}).catch(() => false),
|
}).catch(() => false),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Only add pool if it's working
|
// Fetch pool price and TVL (only for working pools)
|
||||||
|
let priceStr: string | undefined;
|
||||||
|
let tvlStr: string | undefined;
|
||||||
|
|
||||||
if (isWorking) {
|
if (isWorking) {
|
||||||
// Fetch pool price (use first token as quote, index 0)
|
// Fetch pool price (use first token as quote, index 0)
|
||||||
let priceStr: string | undefined;
|
|
||||||
try {
|
try {
|
||||||
const priceRaw = await publicClient.readContract({
|
const priceRaw = await publicClient.readContract({
|
||||||
address: partyInfoAddress as `0x${string}`,
|
address: partyInfoAddress as `0x${string}`,
|
||||||
@@ -489,7 +492,6 @@ export function useGetAllPools(offset: number = 0, limit: number = 100) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate TVL (approximate by getting first token balance and doubling it)
|
// Calculate TVL (approximate by getting first token balance and doubling it)
|
||||||
let tvlStr: string | undefined;
|
|
||||||
try {
|
try {
|
||||||
if (tokens && tokens.length > 0) {
|
if (tokens && tokens.length > 0) {
|
||||||
const firstTokenAddress = tokens[0];
|
const firstTokenAddress = tokens[0];
|
||||||
@@ -519,16 +521,18 @@ export function useGetAllPools(offset: number = 0, limit: number = 100) {
|
|||||||
console.error(`Error fetching TVL for ${poolAddress}:`, err);
|
console.error(`Error fetching TVL for ${poolAddress}:`, err);
|
||||||
tvlStr = undefined;
|
tvlStr = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
details.push({
|
|
||||||
address: poolAddress,
|
|
||||||
name: name as string,
|
|
||||||
symbol: symbol as string,
|
|
||||||
tokens: tokens as readonly `0x${string}`[],
|
|
||||||
price: priceStr,
|
|
||||||
tvl: tvlStr,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add all pools (both working and killed)
|
||||||
|
details.push({
|
||||||
|
address: poolAddress,
|
||||||
|
name: name as string,
|
||||||
|
symbol: symbol as string,
|
||||||
|
tokens: tokens as readonly `0x${string}`[],
|
||||||
|
price: priceStr,
|
||||||
|
tvl: tvlStr,
|
||||||
|
isKilled: !isWorking,
|
||||||
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error fetching pool details for', poolAddress, err);
|
console.error('Error fetching pool details for', poolAddress, err);
|
||||||
// Skip pools that fail to load
|
// Skip pools that fail to load
|
||||||
|
|||||||
Reference in New Issue
Block a user