Skip to content

Commit

Permalink
Merge pull request #163 from berachain/story/implement-vp-in-hub-v2
Browse files Browse the repository at this point in the history
Story/implement vp in hub v2
  • Loading branch information
bearpong authored Nov 4, 2024
2 parents 2d94038 + b756eac commit d6e87a4
Show file tree
Hide file tree
Showing 110 changed files with 9,814 additions and 1,604 deletions.
6 changes: 3 additions & 3 deletions .env.bartio
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ NEXT_PUBLIC_RPC_CROC_INDEXER_ENDPOINT="https://bartio-bex-indexer.berachain.com/
# HUB Addresses ===================================================================
NEXT_PUBLIC_BGT_ADDRESS="0xbDa130737BDd9618301681329bF2e46A016ff9Ad"
NEXT_PUBLIC_BGT_STAKER="0x791fb53432eED7e2fbE4cf8526ab6feeA604Eb6d"
NEXT_PUBLIC_BGT_ENDPOINT="https://bartio-pol-indexer.berachain.com/berachain/v1alpha1/beacon"
NEXT_PUBLIC_POL_ENDPOINT="https://bartio-pol-indexer.berachain.com/berachain/v1alpha1/beacon"
NEXT_PUBLIC_BGT_VAULT_BLACKLIST="0x2E8410239bB4b099EE2d5683e3EF9d6f04E321CC"
NEXT_PUBLIC_BERA_CHEF_ADDRESS="0xfb81E39E3970076ab2693fA5C45A07Cc724C93c2"
NEXT_PUBLIC_GOVERNANCE_TIMELOCK_ADDRESS="0xcB364028856f2328148Bb32f9D6E7a1F86451b1c"
Expand All @@ -146,8 +146,8 @@ NEXT_PUBLIC_CHAIN_BLOCKS_SUBGRAPH_URL="https://api.goldsky.com/api/public/projec
NEXT_PUBLIC_BEND_SUBGRAPH_URL="https://api.goldsky.com/api/public/project_clq1h5ct0g4a201x18tfte5iv/subgraphs/bend-subgraph/v1/gn"
NEXT_PUBLIC_HONEY_SUBGRAPH_URL="https://api.goldsky.com/api/public/project_clq1h5ct0g4a201x18tfte5iv/subgraphs/honey-subgraph/v1/gn"
NEXT_PUBLIC_BGT_SUBGRAPH_URL="https://api.goldsky.com/api/public/project_clq1h5ct0g4a201x18tfte5iv/subgraphs/pol-subgraph/v0.1.4/gn"
NEXT_PUBLIC_BGT_STAKER_SUBGRAPH_URL="https://api.goldsky.com/api/public/project_clq1h5ct0g4a201x18tfte5iv/subgraphs/bgt-staker-subgraph/v1/gn"

NEXT_PUBLIC_RPC_CROC_SUBGRAPH="https://api.goldsky.com/api/public/project_clq1h5ct0g4a201x18tfte5iv/subgraphs/pol-subgraph/v0.1.4/gn"
NEXT_PUBLIC_POL_SUBGRAPH_URL="https://api.goldsky.com/api/public/project_clq1h5ct0g4a201x18tfte5iv/subgraphs/pol-subgraph/v0.1.4/gn"

# in seconds
NEXT_PUBLIC_FALLBACK_BLOCKTIME="1.9"
2 changes: 1 addition & 1 deletion apps/hub/src/app/rewards/my-incentives-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const MyIncentivesTableTable = () => {
<DataTable
columns={user_incentives_columns}
loading={isLoading}
data={data ? data.filter((v: any) => v.userStaked !== "0") : []}
data={data ? data.filter((v: any) => v.amountDelegated !== "0") : []}
className="min-w-[800px] shadow"
/>
</div>
Expand Down
154 changes: 88 additions & 66 deletions apps/hub/src/app/validators/components/all-validator.tsx
Original file line number Diff line number Diff line change
@@ -1,41 +1,39 @@
import { useCallback, useMemo, useState } from "react";
import React, { useCallback, useMemo, useState } from "react";
import {
usePollValidatorInfo,
useUserValidators,
useUserActiveValidators,
type UserValidator,
type Validator,
} from "@bera/berajs";
import { DataTable } from "@bera/shared-ui";
import type { ColumnDef, TableState } from "@tanstack/react-table";
import { SimpleTable, useAsyncTable } from "@bera/shared-ui";
import type {
ColumnDef,
PaginationState,
SortingState,
TableState,
Updater,
} from "@tanstack/react-table";

import {
general_validator_columns,
user_general_validator_columns,
} from "~/columns/general-validator-columns";
import { generalValidatorColumns } from "~/columns/general-validator-columns";

const VALIDATOR_PAGE_SIZE = 10;

export const AllValidator = ({
user = false,
keyword,
isTyping,
onRowClick,
page,
setPage,
}: {
user?: boolean;
keyword?: any;
isTyping?: boolean;
onRowClick?: any;
page: number;
setPage: React.Dispatch<React.SetStateAction<number>>;
}) => {
const [page, setPage] = useState(0);
const [sorting, setSorting] = useState([{ id: "votingpower", desc: true }]);
const handleNewSort = (newSort: any) => {
if (newSort === sorting) return;
setSorting(newSort);
};
const fetchData = useCallback(
(state: TableState) => setPage(state?.pagination?.pageIndex),
[setPage],
);
const [sorting, setSorting] = useState<SortingState>([
{ id: "votingpower", desc: true },
]);

const {
validatorInfoList,
isLoading,
Expand All @@ -53,57 +51,81 @@ export const AllValidator = ({
data = [],
isLoading: isUserLoading,
isValidating: isUserValidating,
} = useUserValidators();
} = useUserActiveValidators();

const validators = useMemo(() => {
if (user) {
return validatorInfoList.map((validator: Validator) => {
const uVali = data.find(
(userValidator: UserValidator) =>
userValidator.coinbase === validator.coinbase,
);
if (uVali) {
return {
...validator,
userStaked: uVali.userStaked,
userQueued: uVali.userQueued,
latestBlock: uVali.latestBlock,
latestBlockTime: uVali.latestBlockTime,
};
}
return {
...validator,
userStaked: "0",
userQueued: "0",
latestBlock: "0",
latestBlockTime: "0",
};
});
}
return validatorInfoList;
return validatorInfoList as UserValidator[];
}, [data, validatorInfoList]);

const fetchData = useCallback(
(state: TableState) => {
setPage(state?.pagination?.pageIndex);
setSorting(state?.sorting);
},
[setPage],
);

const handleSortingChange = useCallback(
(updater: Updater<SortingState>) => {
setSorting((prev: SortingState) => {
return typeof updater === "function" ? updater(prev ?? []) : updater;
});
},
[setSorting],
);

const handlePaginationChange = useCallback(
(updater: Updater<PaginationState>) => {
setPage((prev: number) => {
const newPaginationState =
typeof updater === "function"
? updater({
pageIndex: prev ?? 0,
pageSize: VALIDATOR_PAGE_SIZE,
})
: updater;
return newPaginationState.pageIndex ?? 0;
});
},
[setPage],
);

const allValidatorTable = useAsyncTable({
fetchData: fetchData,
columns: generalValidatorColumns as ColumnDef<UserValidator>[],
data: validators ?? [],
enablePagination: true,
additionalTableProps: {
meta: {
loading: isLoading || isUserLoading,
loadingText: "Loading...",
validating: isValidating || isUserValidating,
},
state: {
pagination: {
pageIndex: page,
pageSize: VALIDATOR_PAGE_SIZE,
},
sorting,
},
manualSorting: true,
manualPagination: true,
autoResetPageIndex: false,
pageCount: Math.ceil(validatorCounts / VALIDATOR_PAGE_SIZE),
onPaginationChange: handlePaginationChange,
onSortingChange: handleSortingChange,
},
});

return (
<DataTable
columns={
(user
? (user_general_validator_columns as ColumnDef<UserValidator>[])
: general_validator_columns) as ColumnDef<Validator>[]
}
data={validators}
className="min-h-[600px] min-w-[1000px]"
fetchData={fetchData}
enablePagination
loading={isLoading || isUserLoading}
validating={isValidating || isUserValidating}
additionalTableProps={{
initialState: { pagination: { pageSize: VALIDATOR_PAGE_SIZE } },
state: { sorting },
pageCount: Math.ceil(validatorCounts / VALIDATOR_PAGE_SIZE),
manualPagination: true,
}}
<SimpleTable
table={allValidatorTable}
className="min-h-[614px]"
flexTable
wrapperClassName="min-h-[614px]"
variant="ghost"
onRowClick={onRowClick}
onCustomSortingChange={(a: any) => handleNewSort(a)}
mutedBackgroundOnHead={false}
/>
);
};
73 changes: 45 additions & 28 deletions apps/hub/src/app/validators/components/boost-queue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@ import { useMemo, useState } from "react";
import {
BGT_ABI,
IContractWrite,
SubgraphUserValidator,
type UserValidator,
TransactionActionType,
truncateHash,
useBgtUnstakedBalance,
useUserValidatorsSubgraph,
useUserActiveValidators,
useValidatorList,
} from "@bera/berajs";
import { bgtTokenAddress } from "@bera/config";
import { FormattedNumber, ValidatorIcon, useTxn } from "@bera/shared-ui";
import {
FormattedNumber,
Spinner,
ValidatorIcon,
useTxn,
} from "@bera/shared-ui";
import { cn } from "@bera/ui";
import { Button } from "@bera/ui/button";
import { Skeleton } from "@bera/ui/skeleton";
Expand All @@ -21,10 +26,14 @@ export const HISTORY_BUFFER = 8192;

export const BoostQueue = ({
selectedValidator,
isValidatorDataLoading,
setIsValidatorDataLoading,
}: {
selectedValidator?: string | undefined;
isValidatorDataLoading?: boolean;
setIsValidatorDataLoading: (loading: boolean) => void;
}) => {
const { data = [], refresh, isLoading } = useUserValidatorsSubgraph();
const { data = [], refresh } = useUserActiveValidators();
const { refresh: refreshBalance } = useBgtUnstakedBalance();

const result = useBlock();
Expand All @@ -34,10 +43,10 @@ export const BoostQueue = ({
return !data || !blockNumber || !data.length
? []
: data
.filter((validator: SubgraphUserValidator) => {
.filter((validator: UserValidator) => {
return parseFloat(validator.amountQueued) !== 0;
})
.map((validator: SubgraphUserValidator) => {
.map((validator: UserValidator) => {
return {
...validator,
canActivate:
Expand All @@ -47,11 +56,11 @@ export const BoostQueue = ({
0,
};
})
.filter((validator: SubgraphUserValidator) => {
.filter((validator: UserValidator) => {
return selectedValidator !== undefined
? validator.coinbase.toLowerCase() ===
selectedValidator.toLowerCase()
: false;
: true;
});
}, [data, blockNumber]);

Expand All @@ -67,10 +76,12 @@ export const BoostQueue = ({
message: "Activating queued BGT to Validator",
actionType: TransactionActionType.DELEGATE,
onSuccess: () => {
setIsValidatorDataLoading(true);
setTimeout(() => {
refresh();
refreshBalance();
setHasSubmittedTxn({} as any);
setIsValidatorDataLoading(false);
}, 5000);
},
});
Expand All @@ -83,10 +94,12 @@ export const BoostQueue = ({
message: "Cancelling queued BGT to Validator",
actionType: TransactionActionType.DELEGATE,
onSuccess: () => {
setIsValidatorDataLoading(true);
setTimeout(() => {
refresh();
refreshBalance();
setHasSubmittedTxn({} as any);
setIsValidatorDataLoading(false);
}, 5000);
},
});
Expand All @@ -108,31 +121,35 @@ export const BoostQueue = ({
<div className="flex flex-col gap-3">
{ActivateModalPortal}
{CancelModalPortal}
<div className="text-lg font-semibold leading-7">Delegation Queue</div>
<div className="flex items-center">
<div className="mr-2 text-lg font-semibold leading-7">
Delegation Queue
</div>
{isValidatorDataLoading && <Spinner size={18} color="white" />}
</div>

{!queuedList ? (
<div>
<Skeleton className="h-28 w-full rounded-md" />
<Skeleton className="h-28 w-full rounded-md" />
</div>
) : (
<>
{queuedList?.map(
(validator: SubgraphUserValidator, index: number) => (
<ConfirmationCard
key={validator.coinbase}
userValidator={validator}
index={index}
hasSubmittedTxn={hasSubmittedTxn[index] ?? false}
blocksLeft={
parseInt(validator.latestBlock) +
HISTORY_BUFFER -
Number(blockNumber)
}
isTxnLoading={isActivationLoading || isCancelLoading}
handleTransaction={handleTransaction}
/>
),
)}
{queuedList?.map((validator: UserValidator, index: number) => (
<ConfirmationCard
key={validator.coinbase}
userValidator={validator}
index={index}
hasSubmittedTxn={hasSubmittedTxn[index] ?? false}
blocksLeft={
parseInt(validator.latestBlock) +
HISTORY_BUFFER -
Number(blockNumber)
}
isTxnLoading={isActivationLoading || isCancelLoading}
handleTransaction={handleTransaction}
/>
))}
{!queuedList?.length && (
<div className="text-muted-foreground">No validators in queue</div>
)}
Expand All @@ -150,7 +167,7 @@ const ConfirmationCard = ({
hasSubmittedTxn,
handleTransaction,
}: {
userValidator: SubgraphUserValidator;
userValidator: UserValidator;
blocksLeft: number;
isTxnLoading: boolean;
index: number;
Expand All @@ -175,7 +192,7 @@ const ConfirmationCard = ({
const validatorInfo = data?.validatorDictionary
? data.validatorDictionary[coinbase]
: undefined;
console.log(validatorInfo, data);

return (
<div className="w-full rounded-md border border-border p-4">
<div className="flex w-full justify-between">
Expand Down
Loading

0 comments on commit d6e87a4

Please sign in to comment.