Skip to content

Commit

Permalink
Merge branch 'v2' into am/bex-create-pool-polish
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulMcInnis committed Dec 23, 2024
2 parents a78c1d9 + d67be32 commit 6327b8a
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 79 deletions.
71 changes: 32 additions & 39 deletions apps/hub/src/app/validators/components/GeneralSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,41 +18,26 @@ import { Address, isAddress, zeroAddress } from "viem";

export const GeneralSettings = ({
validatorPublicKey,
isQueuedOperatorWallet,
isValidatorWallet,
}: {
validatorPublicKey: Address;
isQueuedOperatorWallet: boolean;
isValidatorWallet: boolean;
}) => {
const [confirmed, setConfirmed] = useState(false);
const { account } = useBeraJs();
const {
data: operatorAddress,
isLoading: isOperatorAddressLoading,
refresh: refreshOperatorAddress,
} = useValidatorOperatorAddress(validatorPublicKey);
const {
data: queuedOperatorAddress,
isLoading: isQueuedOperatorAddressLoading,
refresh: refreshQueuedOperatorAddress,
} = useValidatorQueuedOperatorAddress(validatorPublicKey);
const { data: operatorAddress, refresh: refreshOperatorAddress } =
useValidatorOperatorAddress(validatorPublicKey);
const { data: queuedOperatorAddress, refresh: refreshQueuedOperatorAddress } =
useValidatorQueuedOperatorAddress(validatorPublicKey);
const [operatorInput, setOperatorInput] = useState<string>("");

const isQueuedOperatorAddress = useMemo(() => {
if (
!queuedOperatorAddress ||
!operatorAddress ||
isQueuedOperatorAddressLoading ||
isOperatorAddressLoading
)
return true;
const isQueuedOperator = useMemo(() => {
return (
queuedOperatorAddress[1] !== operatorAddress &&
queuedOperatorAddress[1] !== zeroAddress
queuedOperatorAddress?.[1] && queuedOperatorAddress?.[1] !== zeroAddress
);
}, [
queuedOperatorAddress,
operatorAddress,
isQueuedOperatorAddressLoading,
isOperatorAddressLoading,
]);
}, [queuedOperatorAddress]);

const timeRemaining = useMemo(() => {
if (!queuedOperatorAddress) return 0;
Expand All @@ -61,12 +46,7 @@ export const GeneralSettings = ({
return currentBlockTimestamp + twentyFourHoursInMs;
}, [queuedOperatorAddress]);

const canQueueOperatorChange = useMemo(() => {
if (!queuedOperatorAddress) return false;
return (
queuedOperatorAddress[1] !== operatorAddress && Date.now() > timeRemaining
);
}, [queuedOperatorAddress, operatorAddress, timeRemaining]);
const canQueueOperatorChange = Date.now() > timeRemaining;

const {
write,
Expand Down Expand Up @@ -118,7 +98,7 @@ export const GeneralSettings = ({

return (
<div className="flex flex-col gap-6">
{isQueuedOperatorAddress && (
{isQueuedOperator && (
<Card className="flex flex-col gap-1">
<CardContent className="flex flex-col items-center justify-between pb-4 pt-2 md:flex-row">
<div className="flex flex-col gap-1">
Expand All @@ -130,7 +110,7 @@ export const GeneralSettings = ({
</div>
<div>
<span className="text-sm text-muted-foreground">
Operator Address is currently queued to change to{" "}
Operator Address is queued to change to{" "}
<a
href={`${blockExplorerUrl}/address/${queuedOperatorAddress?.[1]}`}
target="_blank"
Expand All @@ -139,18 +119,18 @@ export const GeneralSettings = ({
>
{queuedOperatorAddress?.[1]}
</a>
. You'll be able to apply the change at{" "}
. The queued operator will be able to apply the change at{" "}
{new Date(timeRemaining).toLocaleString()}
</span>
</div>
</div>
<div className="mt-4 flex gap-2 self-end md:self-auto">
<div className="mt-4 ml-1 flex gap-2 self-end md:self-auto">
<Button
size="sm"
variant="outline"
onClick={handleConfirmQueuedOperatorChange}
className="flex border-border px-4 py-2"
disabled={!canQueueOperatorChange}
disabled={!(canQueueOperatorChange && isQueuedOperatorWallet)}
>
Confirm
</Button>
Expand All @@ -159,6 +139,7 @@ export const GeneralSettings = ({
variant="outline"
onClick={handleCancelQueuedOperatorChange}
className="flex border-border px-4 py-2"
disabled={!isValidatorWallet} // TODO: check if queued Operator can cancel queued operator
>
Cancel
</Button>
Expand All @@ -179,7 +160,14 @@ export const GeneralSettings = ({
placeholder={truncateHash("0x00000000000000")}
onChange={(e) => setOperatorInput(e.target.value)}
className="w-[300px]"
error={!isValidAddress ? "Please enter a valid address" : undefined}
disabled={isQueuedOperatorWallet}
error={
!isValidAddress && !(operatorInput === "")
? "Please enter a valid address"
: isQueuedOperatorWallet
? "Unable to change address as the current queued operator"
: undefined
}
/>
</CardContent>
<CardFooter className="flex w-full justify-between border-t border-border pt-6">
Expand All @@ -188,11 +176,16 @@ export const GeneralSettings = ({
className="mr-1"
id="confirm"
checked={confirmed}
disabled={isQueuedOperatorWallet}
onCheckedChange={() => setConfirmed(!confirmed)}
/>
<span
className="mr-2 cursor-pointer text-sm text-muted-foreground"
onClick={() => setConfirmed(!confirmed)}
onClick={() =>
isQueuedOperatorWallet
? setConfirmed(false)
: setConfirmed(!confirmed)
}
>
I understand that changing operator address is equivalent to
handing over ownership rights to the validator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,11 @@ const USER_BLOCK_DELAY = 100n;

export const RewardAllocationConfiguration = ({
validatorPublicKey,
}: { validatorPublicKey: Address }) => {
isQueuedOperatorWallet,
}: {
validatorPublicKey: Address;
isQueuedOperatorWallet: boolean;
}) => {
const [vaults, setVaults] = useState<
{ address: string; distribution: number; id: string }[]
>([{ address: "", distribution: 0, id: uuidv4() }]);
Expand Down Expand Up @@ -273,7 +277,9 @@ export const RewardAllocationConfiguration = ({
}
value={vaults[index].address}
selectedItems={vaults.map((vault) => vault.address)}
disabled={isQueuedRewardAllocation}
disabled={
isQueuedRewardAllocation || isQueuedOperatorWallet
}
onSelect={(selectedValue) =>
handleVaultChange(index, "address", selectedValue)
}
Expand All @@ -285,7 +291,9 @@ export const RewardAllocationConfiguration = ({
<Input
type="number"
value={vault.distribution}
disabled={isQueuedRewardAllocation}
disabled={
isQueuedRewardAllocation || isQueuedOperatorWallet
}
onChange={(e) => {
let value = e.target.value;
if (value.includes(".")) {
Expand Down Expand Up @@ -323,7 +331,11 @@ export const RewardAllocationConfiguration = ({
size={"sm"}
variant={"outline"}
onClick={() => handleDeleteVault(index)}
disabled={vaults.length === 1 || isQueuedRewardAllocation}
disabled={
vaults.length === 1 ||
isQueuedRewardAllocation ||
isQueuedOperatorWallet
}
>
<Icons.close className="h-6 w-6" />
</Button>
Expand All @@ -334,7 +346,11 @@ export const RewardAllocationConfiguration = ({
<Button
className="flex border border-border p-2 font-semibold text-foreground"
size={"sm"}
disabled={vaults.length >= 10 || isQueuedRewardAllocation}
disabled={
vaults.length >= 10 ||
isQueuedRewardAllocation ||
isQueuedOperatorWallet
}
variant={"outline"}
onClick={handleAddVault}
>
Expand All @@ -346,7 +362,7 @@ export const RewardAllocationConfiguration = ({
size={"sm"}
variant={"outline"}
title="Distribute Vaults"
disabled={isQueuedRewardAllocation}
disabled={isQueuedRewardAllocation || isQueuedOperatorWallet}
onClick={handleDistributeVaults}
>
{<Icons.squareEqual className="h-4 w-4" />}
Expand Down Expand Up @@ -382,17 +398,21 @@ export const RewardAllocationConfiguration = ({
</div>
</CardContent>
<CardFooter className="flex w-full justify-between border-t border-border pt-6">
{isQueuedRewardAllocation && (
{isQueuedOperatorWallet ? (
<span className="mr-2 text-sm text-muted-foreground">
Unable to be modified as the current queued operator
</span>
) : isQueuedRewardAllocation ? (
<span className="mr-2 text-sm text-muted-foreground">
Unable to be modified when there is a current queued reward
allocation
</span>
)}
) : null}
<Button
variant="outline"
size="sm"
className="ml-auto border-border mr-2 flex min-w-36 px-4 py-2"
disabled={isQueuedRewardAllocation}
className="ml-auto mr-2 flex min-w-36 border-border px-4 py-2"
disabled={isQueuedRewardAllocation || isQueuedOperatorWallet}
onClick={handleResetToDefault}
>
Reset to Default
Expand All @@ -403,7 +423,8 @@ export const RewardAllocationConfiguration = ({
disabled={
!!error ||
isQueuedRewardAllocation ||
isApplyingQueuedRewardAllocation
isApplyingQueuedRewardAllocation ||
isQueuedOperatorWallet
}
onClick={handleQueue}
>
Expand Down
31 changes: 22 additions & 9 deletions apps/hub/src/app/validators/components/ValidatorTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { useEffect, useState } from "react";
import {
useBeraJs,
useValidatorByOperator,
type Validator,
useValidatorQueuedOperatorAddress,
} from "@bera/berajs";
import { ApiValidatorFragment } from "@bera/graphql/pol/api";
import {
Select,
SelectContent,
Expand All @@ -12,32 +13,42 @@ import {
SelectValue,
} from "@bera/ui/select";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@bera/ui/tabs";
import { Address } from "viem";

import { ValidatorOverview } from "../validator/components/ValidatorOverview";
import { ValidatorPolData } from "../validator/components/ValidatorPolData";
import { ValidatorAnalytics } from "./validator-analytics";
import { ValidatorConfiguration } from "./validator-configuration";
import { ApiValidatorFragment } from "@bera/graphql/pol/api";
import { Address } from "viem";

// import { ValidatorEvents } from "./validator-events";

type ValidatorTabValue = "overview" | "configuration" | "analytics" | "events";

export const ValidatorTabs = ({
validator,
}: { validator: ApiValidatorFragment }) => {
}: {
validator: ApiValidatorFragment;
}) => {
const { account } = useBeraJs();
const { data } = useValidatorByOperator(account ?? "0x");
const { data: validatorByOperator } = useValidatorByOperator(account ?? "0x");
const { data: queuedOperator } = useValidatorQueuedOperatorAddress(
validator.pubkey as Address,
);

const isQueuedOperatorWallet =
queuedOperator && queuedOperator[1] === account;
const isValidatorWallet =
data?.validators[0]?.publicKey?.toLowerCase() ===
validatorByOperator?.validators[0]?.publicKey?.toLowerCase() ===
validator.pubkey.toLowerCase();

const [dayRange, setDayRange] = useState("30");
const [activeTab, setActiveTab] = useState<ValidatorTabValue>("overview");

useEffect(() => {
if (activeTab === "configuration" && !isValidatorWallet) {
if (
activeTab === "configuration" &&
!(isValidatorWallet || isQueuedOperatorWallet)
) {
setActiveTab("overview");
}
}, [isValidatorWallet, activeTab]);
Expand All @@ -54,7 +65,7 @@ export const ValidatorTabs = ({
<div className="mb-6 flex w-full flex-col justify-between gap-6 sm:flex-row">
<TabsList variant="ghost">
<TabsTrigger value="overview">Overview</TabsTrigger>
{isValidatorWallet && (
{(isValidatorWallet || isQueuedOperatorWallet) && (
<TabsTrigger value="configuration">Configuration</TabsTrigger>
)}
<TabsTrigger value="analytics">Analytics</TabsTrigger>
Expand Down Expand Up @@ -97,7 +108,9 @@ export const ValidatorTabs = ({
</TabsContent>
<TabsContent value="configuration">
<ValidatorConfiguration
validatorPublicKey={data?.validators[0]?.publicKey ?? "0x"}
isQueuedOperatorWallet={isQueuedOperatorWallet ?? false}
isValidatorWallet={isValidatorWallet ?? false}
validatorPublicKey={validator.pubkey as Address}
/>
</TabsContent>
<TabsContent value="analytics">
Expand Down
17 changes: 14 additions & 3 deletions apps/hub/src/app/validators/components/validator-configuration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ import { Icons } from "@bera/ui/icons";
import { Address } from "viem";

import { GeneralSettings } from "./GeneralSettings";
import { QueuedRewardAllocationConfiguration } from "./queued-reward-allocation-configuration";
import { RewardAllocationConfiguration } from "./RewardAllocationConfiguration";
import { QueuedRewardAllocationConfiguration } from "./queued-reward-allocation-configuration";

export const ValidatorConfiguration = ({
validatorPublicKey,
isQueuedOperatorWallet,
isValidatorWallet,
}: {
validatorPublicKey: Address;
isQueuedOperatorWallet: boolean;
isValidatorWallet: boolean;
}) => {
const handleUpdateMetadata = useCallback(() => {
console.log("updating metadata", validatorPublicKey);
Expand All @@ -22,8 +26,15 @@ export const ValidatorConfiguration = ({
<QueuedRewardAllocationConfiguration
validatorPublicKey={validatorPublicKey}
/>
<RewardAllocationConfiguration validatorPublicKey={validatorPublicKey} />
<GeneralSettings validatorPublicKey={validatorPublicKey} />
<RewardAllocationConfiguration
validatorPublicKey={validatorPublicKey}
isQueuedOperatorWallet={isQueuedOperatorWallet}
/>
<GeneralSettings
validatorPublicKey={validatorPublicKey}
isQueuedOperatorWallet={isQueuedOperatorWallet}
isValidatorWallet={isValidatorWallet}
/>
<Link href={"https://github.com/berachain/default-lists"}>
<Card className="flex flex-col gap-1 p-4">
<div className="flex-center flex">
Expand Down
Loading

0 comments on commit 6327b8a

Please sign in to comment.