diff --git a/app/api/user.server.ts b/app/api/user.server.ts index 58e6fd0..f43adf7 100644 --- a/app/api/user.server.ts +++ b/app/api/user.server.ts @@ -185,6 +185,9 @@ export const fetchUserIncentives = async ( const reward = (rewardPerLiquidityDelta * usersLiquidity) / UINT112_MAX; return { ...userIncentive, + isActive: + Number(userIncentive.incentive.endTime) > + Math.floor(Date.now() / 1000), incentive: { ...userIncentive.incentive, rewardToken: rewardToken, diff --git a/app/hooks/useClaimRewards.ts b/app/hooks/useClaimRewards.ts index 214e5e9..9d20349 100644 --- a/app/hooks/useClaimRewards.ts +++ b/app/hooks/useClaimRewards.ts @@ -11,7 +11,7 @@ type Props = { onSuccess?: () => void; }; -export const useClaimRewards = ({ enabled = true, onSuccess }: Props) => { +export const useClaimRewards = (props?: Props) => { const { isConnected } = useAccount(); const stakingContractAddress = useContractAddress("stakingContract"); const claimAllRewards = useWriteStakingContractClaimAllRewards(); @@ -19,7 +19,7 @@ export const useClaimRewards = ({ enabled = true, onSuccess }: Props) => { hash: claimAllRewards.data, }); - const isEnabled = enabled && isConnected; + const isEnabled = isConnected && props?.enabled !== false; const isSuccess = claimAllRewardsReceipt.isSuccess; useToast({ @@ -33,9 +33,9 @@ export const useClaimRewards = ({ enabled = true, onSuccess }: Props) => { useEffect(() => { if (isSuccess) { - onSuccess?.(); + props?.onSuccess?.(); } - }, [isSuccess, onSuccess]); + }, [isSuccess, props?.onSuccess]); return { claimRewards: (incentiveIds: bigint[]) => { diff --git a/app/hooks/useSubscribeToIncentives.ts b/app/hooks/useSubscribeToIncentives.ts index d502310..a0ee6dc 100644 --- a/app/hooks/useSubscribeToIncentives.ts +++ b/app/hooks/useSubscribeToIncentives.ts @@ -1,7 +1,6 @@ -import { useEffect, useState } from "react"; import { useWaitForTransactionReceipt } from "wagmi"; -import type { UserIncentive } from "~/api/user.server"; +import { useEffect } from "react"; import { useAccount } from "~/contexts/account"; import { useWriteStakingContractSubscribeToIncentives } from "~/generated"; import { useContractAddress } from "./useContractAddress"; @@ -9,14 +8,10 @@ import { useToast } from "./useToast"; type Props = { enabled?: boolean; - onSuccess?: (incentiveIds: bigint[]) => void; + onSuccess?: () => void; }; -export const useSubscribeToIncentives = ({ - enabled = true, - onSuccess, -}: Props) => { - const [lastIncentiveIds, setLastIncentiveIds] = useState([]); +export const useSubscribeToIncentives = (props?: Props) => { const { isConnected } = useAccount(); const stakingContractAddress = useContractAddress("stakingContract"); const subscribeToIncentives = useWriteStakingContractSubscribeToIncentives(); @@ -24,11 +19,11 @@ export const useSubscribeToIncentives = ({ hash: subscribeToIncentives.data, }); - const isEnabled = enabled && isConnected; + const isEnabled = isConnected && props?.enabled !== false; const isSuccess = subscribeToIncentivesReceipt.isSuccess; useToast({ - title: "Subscribing to rewards", + title: "Subscribe to rewards", isLoading: subscribeToIncentives.isPending || subscribeToIncentivesReceipt.isLoading, isSuccess, @@ -41,9 +36,9 @@ export const useSubscribeToIncentives = ({ useEffect(() => { if (isSuccess) { - onSuccess?.(lastIncentiveIds); + props?.onSuccess?.(); } - }, [isSuccess, onSuccess, lastIncentiveIds]); + }, [isSuccess, props?.onSuccess]); return { subscribeToIncentives: (incentiveIds: bigint[]) => { @@ -51,8 +46,6 @@ export const useSubscribeToIncentives = ({ return; } - setLastIncentiveIds(incentiveIds); - return subscribeToIncentives.writeContractAsync({ address: stakingContractAddress, args: [incentiveIds], diff --git a/app/hooks/useWithdrawBatch.ts b/app/hooks/useWithdrawBatch.ts index ad599e8..06e4822 100644 --- a/app/hooks/useWithdrawBatch.ts +++ b/app/hooks/useWithdrawBatch.ts @@ -52,7 +52,7 @@ export const useWithdrawBatch = ({ nftVaultApproveReceipt.isLoading; useToast({ - title: "Withdrawing Rewards", + title: "Withdraw rewards", isLoading, isSuccess, isError: diff --git a/app/routes/pools_.$id.tsx b/app/routes/pools_.$id.tsx index 748d02d..deee1f5 100644 --- a/app/routes/pools_.$id.tsx +++ b/app/routes/pools_.$id.tsx @@ -85,7 +85,7 @@ import { formatTokenReserve } from "~/lib/tokens"; import { cn } from "~/lib/utils"; import type { RootLoader } from "~/root"; import { getSession } from "~/sessions"; -import type { Optional, PoolToken } from "~/types"; +import type { Optional, PoolToken, TroveTokenWithQuantity } from "~/types"; import type { TransactionType } from ".graphclient"; type PoolManagementTab = "deposit" | "withdraw" | "stake" | "unstake"; @@ -197,8 +197,7 @@ export default function PoolDetailsPage() { const nftIncentive = userIncentives.find( (userIncentive) => - userIncentive.incentive.rewardToken?.isNFT && - BigInt(userIncentive.reward) > 0, + userIncentive.isActive && userIncentive.incentive.rewardToken?.isNFT, ); const nftIncentiveDecimals = @@ -226,24 +225,8 @@ export default function PoolDetailsPage() { refetchNftIncentiveTokenBalance(); }, [revalidator, refetchNftIncentiveTokenBalance]); - const { subscribeToIncentives } = useSubscribeToIncentives({ - onSuccess: useCallback( - (incentiveIds: bigint[]) => { - // API can be slow to update, so optimistically update the subscribed list - setOptimisticSubscribedIncentiveIds((curr) => - curr.concat(incentiveIds), - ); - refetch(); - }, - [refetch], - ), - }); - - const { claimRewards } = useClaimRewards({ - // Doesn't need optimistic update because data is pulled directly from contract - onSuccess: refetch, - }); - + const { subscribeToIncentives } = useSubscribeToIncentives(); + const { claimRewards } = useClaimRewards(); const { withdrawBatch, isLoading: isLoadingWithdrawBatch } = useWithdrawBatch( { vaultAddress: nftIncentive?.incentive.rewardTokenAddress as @@ -286,6 +269,32 @@ export default function PoolDetailsPage() { const quoteToken = baseToken.id === pool.token1.id ? pool.token0 : pool.token1; + const handleSubscribeToAll = async () => { + const incentiveIds = [...unsubscribedIncentiveIds]; + await subscribeToIncentives(incentiveIds); + // API can be slow to update, so optimistically update the subscribed list + setOptimisticSubscribedIncentiveIds((curr) => curr.concat(incentiveIds)); + refetch(); + }; + + const handleClaimRewards = async () => { + await claimRewards(subscribedIncentiveIds); + // Doesn't need optimistic update because data is pulled directly from contract + refetch(); + }; + + const handleWithdrawRewards = async (tokens: TroveTokenWithQuantity[]) => { + await withdrawBatch( + tokens.map((token) => ({ + id: BigInt(token.tokenId), + amount: BigInt(token.quantity), + collectionId: token.collectionAddr as Address, + })), + ); + setIsWithdrawingFromVault(false); + refetch(); + }; + return (
{lpStaked > 0 && unsubscribedIncentiveIds.length > 0 ? ( - ) : null} @@ -544,10 +548,7 @@ export default function PoolDetailsPage() { {hasStakingRewards ? ( - ) : null} @@ -771,16 +772,7 @@ export default function PoolDetailsPage() { floorBigInt(nftIncentiveTokenBalance, nftIncentiveDecimals), nftIncentiveDecimals, )} - onSubmit={async (tokens) => { - await withdrawBatch( - tokens.map((token) => ({ - id: BigInt(token.tokenId), - amount: BigInt(token.quantity), - collectionId: token.collectionAddr as Address, - })), - ); - setIsWithdrawingFromVault(false); - }} + onSubmit={handleWithdrawRewards} isSubmitDisabled={isLoadingWithdrawBatch} keepOpenOnSubmit />