From 122550a238999bb6d79d25326e5411db4f6cf9ed Mon Sep 17 00:00:00 2001 From: roaring30s Date: Thu, 29 Jan 2026 11:11:43 -0500 Subject: [PATCH 1/2] feat: add useDelegationReview hook --- components/DelegatingWidget/Footer.tsx | 12 +++- components/DelegationReview/index.tsx | 31 +++++++++++ components/Redelegate/index.tsx | 10 +++- .../RedelegateFromUndelegated/index.tsx | 17 +++++- components/StakeTransactions/index.tsx | 14 ++++- components/WithdrawStake/index.tsx | 10 +++- hooks/index.tsx | 1 + hooks/useDelegationReview.tsx | 55 +++++++++++++++++++ 8 files changed, 144 insertions(+), 6 deletions(-) create mode 100644 components/DelegationReview/index.tsx create mode 100644 hooks/useDelegationReview.tsx diff --git a/components/DelegatingWidget/Footer.tsx b/components/DelegatingWidget/Footer.tsx index 7b542a4d..3cafcd5f 100644 --- a/components/DelegatingWidget/Footer.tsx +++ b/components/DelegatingWidget/Footer.tsx @@ -12,13 +12,14 @@ import { useAccountAddress, useAccountBalanceData, usePendingFeesAndStakeData, + useDelegationReview, } from "hooks"; import { useMemo } from "react"; -import { parseEther } from "viem"; - +import DelegationReview from "../DelegationReview"; import Delegate from "./Delegate"; import Footnote from "./Footnote"; import Undelegate from "./Undelegate"; +import { parseEther } from "viem"; type FooterData = { isTransferStake: boolean; @@ -78,6 +79,11 @@ const Footer = ({ () => getDelegatorStatus(delegator, currentRound), [currentRound, delegator] ); + const { warnings } = useDelegationReview({ + action: action || "delegate", + delegator, + currentRound, + }); const stakeWei = useMemo( () => delegatorPendingStakeAndFees?.pendingStake @@ -161,6 +167,7 @@ const Footer = ({ if (action === "delegate") { return ( + + { + if (!warnings || warnings.length === 0) return null; + + return ( + + {warnings.map((warning, i) => ( + + + {warning} + + ))} + + ); +}; + +export default DelegationReview; diff --git a/components/Redelegate/index.tsx b/components/Redelegate/index.tsx index 40945c7f..12e34a1c 100644 --- a/components/Redelegate/index.tsx +++ b/components/Redelegate/index.tsx @@ -2,9 +2,16 @@ import { bondingManager } from "@lib/api/abis/main/BondingManager"; import { Button } from "@livepeer/design-system"; import { useBondingManagerAddress } from "hooks/useContracts"; import { useHandleTransaction } from "hooks/useHandleTransaction"; +import { useDelegationReview } from "hooks/useDelegationReview"; +import DelegationReview from "@components/DelegationReview"; import { useSimulateContract, useWriteContract } from "wagmi"; -const Index = ({ unbondingLockId, newPosPrev, newPosNext }) => { +const Index = ({ unbondingLockId, newPosPrev, newPosNext, delegator, currentRound }) => { + const { warnings } = useDelegationReview({ + action: "transfer", + delegator, + currentRound, + }); const { data: bondingManagerAddress } = useBondingManagerAddress(); const { data: config } = useSimulateContract({ @@ -24,6 +31,7 @@ const Index = ({ unbondingLockId, newPosPrev, newPosNext }) => { return ( <> + + <> + + {delegationWarning && ( + + )} + )} } diff --git a/components/DelegatingWidget/Footer.tsx b/components/DelegatingWidget/Footer.tsx index 3cafcd5f..dd281e5a 100644 --- a/components/DelegatingWidget/Footer.tsx +++ b/components/DelegatingWidget/Footer.tsx @@ -11,15 +11,16 @@ import { StakingAction, useAccountAddress, useAccountBalanceData, - usePendingFeesAndStakeData, useDelegationReview, + usePendingFeesAndStakeData, } from "hooks"; import { useMemo } from "react"; +import { parseEther } from "viem"; + import DelegationReview from "../DelegationReview"; import Delegate from "./Delegate"; import Footnote from "./Footnote"; import Undelegate from "./Undelegate"; -import { parseEther } from "viem"; type FooterData = { isTransferStake: boolean; @@ -70,19 +71,21 @@ const Footer = ({ ); const accountBalance = useAccountBalanceData(accountAddress); - const tokenBalance = useMemo(() => accountBalance?.balance, [accountBalance]); - const transferAllowance = useMemo( - () => accountBalance?.allowance, - [accountBalance] - ); + const tokenBalance = accountBalance?.balance; + const transferAllowance = accountBalance?.allowance; const delegatorStatus = useMemo( () => getDelegatorStatus(delegator, currentRound), [currentRound, delegator] ); - const { warnings } = useDelegationReview({ - action: action || "delegate", + const { delegationWarning } = useDelegationReview({ delegator, currentRound, + action: isTransferStake + ? "moveStake" + : action === "delegate" + ? "delegate" + : "undelegate", + targetOrchestrator: action === "delegate" ? transcoder : undefined, }); const stakeWei = useMemo( () => @@ -167,7 +170,6 @@ const Footer = ({ if (action === "delegate") { return ( - + {delegationWarning && (isTransferStake || amount) && ( + + )} ); } return ( - + )} ); }; diff --git a/components/DelegationReview/index.tsx b/components/DelegationReview/index.tsx index 8145beae..4a632579 100644 --- a/components/DelegationReview/index.tsx +++ b/components/DelegationReview/index.tsx @@ -1,29 +1,32 @@ import { Box, Flex, Text } from "@livepeer/design-system"; import { ExclamationTriangleIcon } from "@radix-ui/react-icons"; -const DelegationReview = ({ warnings }: { warnings: string[] }) => { - if (!warnings || warnings.length === 0) return null; +const DelegationReview = ({ + warning, + css, +}: { + warning?: string | null; + css?: object; +}) => { + if (!warning) return null; return ( - - {warnings.map((warning, i) => ( - - - {warning} - - ))} + + + + {warning} + ); }; diff --git a/components/Redelegate/index.tsx b/components/Redelegate/index.tsx index 12e34a1c..e63723bb 100644 --- a/components/Redelegate/index.tsx +++ b/components/Redelegate/index.tsx @@ -1,16 +1,23 @@ +import { ExplorerTooltip } from "@components/ExplorerTooltip"; import { bondingManager } from "@lib/api/abis/main/BondingManager"; -import { Button } from "@livepeer/design-system"; +import { Box, Button, Flex } from "@livepeer/design-system"; +import { ExclamationTriangleIcon } from "@radix-ui/react-icons"; import { useBondingManagerAddress } from "hooks/useContracts"; -import { useHandleTransaction } from "hooks/useHandleTransaction"; import { useDelegationReview } from "hooks/useDelegationReview"; -import DelegationReview from "@components/DelegationReview"; +import { useHandleTransaction } from "hooks/useHandleTransaction"; import { useSimulateContract, useWriteContract } from "wagmi"; -const Index = ({ unbondingLockId, newPosPrev, newPosNext, delegator, currentRound }) => { - const { warnings } = useDelegationReview({ - action: "transfer", +const Index = ({ + unbondingLockId, + newPosPrev, + newPosNext, + delegator, + currentRound, +}) => { + const { delegationWarning } = useDelegationReview({ delegator, currentRound, + action: "redelegate", }); const { data: bondingManagerAddress } = useBondingManagerAddress(); @@ -30,14 +37,32 @@ const Index = ({ unbondingLockId, newPosPrev, newPosNext, delegator, currentRoun }); return ( - <> - + + {delegationWarning && ( + + + + + + )} - + ); }; diff --git a/components/RedelegateFromUndelegated/index.tsx b/components/RedelegateFromUndelegated/index.tsx index 7dd7ab3f..cbf09bb2 100644 --- a/components/RedelegateFromUndelegated/index.tsx +++ b/components/RedelegateFromUndelegated/index.tsx @@ -1,12 +1,14 @@ import { bondingManager } from "@lib/api/abis/main/BondingManager"; -import { Button } from "@livepeer/design-system"; +import { Box, Button, Flex } from "@livepeer/design-system"; +import { ExclamationTriangleIcon } from "@radix-ui/react-icons"; import { useAccountAddress } from "hooks"; import { useBondingManagerAddress } from "hooks/useContracts"; -import { useHandleTransaction } from "hooks/useHandleTransaction"; import { useDelegationReview } from "hooks/useDelegationReview"; -import DelegationReview from "../DelegationReview"; +import { useHandleTransaction } from "hooks/useHandleTransaction"; import { useSimulateContract, useWriteContract } from "wagmi"; +import { ExplorerTooltip } from "../ExplorerTooltip"; + const Index = ({ unbondingLockId, delegate, @@ -15,10 +17,10 @@ const Index = ({ delegator, currentRound, }) => { - const { warnings } = useDelegationReview({ - action: "transfer", + const { delegationWarning } = useDelegationReview({ delegator, currentRound, + action: "redelegateFromUndelegated", }); const accountAddress = useAccountAddress(); @@ -52,14 +54,20 @@ const Index = ({ } return ( - <> - + - + {delegationWarning && ( + + + + + + )} + ); }; diff --git a/components/StakeTransactions/index.tsx b/components/StakeTransactions/index.tsx index bc4fa498..1d737c7c 100644 --- a/components/StakeTransactions/index.tsx +++ b/components/StakeTransactions/index.tsx @@ -120,19 +120,19 @@ const Index = ({ delegator, transcoders, currentRound, isMyAccount }) => { delegate={lock.delegate.id} newPosPrev={newPosPrev} newPosNext={newPosNext} - delegator={delegator} - currentRound={currentRound} + delegator={delegator} + currentRound={currentRound} /> )} )} { delegate={lock.delegate.id} newPosPrev={newPosPrev} newPosNext={newPosNext} - delegator={delegator} - currentRound={currentRound} + delegator={delegator} + currentRound={currentRound} /> )} - + )} { +const Index = ({ unbondingLockId }) => { const accountAddress = useAccountAddress(); - const { warnings } = useDelegationReview({ - action: "undelegate", - delegator, - currentRound, - }); const { data: bondingManagerAddress } = useBondingManagerAddress(); const { data: config } = useSimulateContract({ @@ -36,7 +29,6 @@ const Index = ({ unbondingLockId, delegator, currentRound }) => { return ( <> -