diff --git a/ui/src/components/StakingTable.tsx b/ui/src/components/StakingTable.tsx index 40b4c84a..710f96f0 100644 --- a/ui/src/components/StakingTable.tsx +++ b/ui/src/components/StakingTable.tsx @@ -1,4 +1,4 @@ -import { useQuery, useQueryClient } from '@tanstack/react-query' +import { useQueryClient } from '@tanstack/react-query' import { useRouter } from '@tanstack/react-router' import { ColumnDef, @@ -15,7 +15,6 @@ import { useWallet } from '@txnlab/use-wallet-react' import dayjs from 'dayjs' import { FlaskConical, MoreHorizontal } from 'lucide-react' import * as React from 'react' -import { constraintsQueryOptions } from '@/api/queries' import { AddStakeModal } from '@/components/AddStakeModal' import { AlgoDisplayAmount } from '@/components/AlgoDisplayAmount' import { DataTableColumnHeader } from '@/components/DataTableColumnHeader' @@ -38,7 +37,7 @@ import { } from '@/components/ui/table' import { UnstakeModal } from '@/components/UnstakeModal' import { StakerValidatorData } from '@/interfaces/staking' -import { Validator } from '@/interfaces/validator' +import { Constraints, Validator } from '@/interfaces/validator' import { canManageValidator, isStakingDisabled, isUnstakingDisabled } from '@/utils/contracts' import { simulateEpoch } from '@/utils/development' import { cn } from '@/utils/ui' @@ -47,9 +46,15 @@ interface StakingTableProps { validators: Validator[] stakesByValidator: StakerValidatorData[] isLoading: boolean + constraints: Constraints } -export function StakingTable({ validators, stakesByValidator, isLoading }: StakingTableProps) { +export function StakingTable({ + validators, + stakesByValidator, + isLoading, + constraints, +}: StakingTableProps) { const [sorting, setSorting] = React.useState([]) const [columnFilters, setColumnFilters] = React.useState([]) const [columnVisibility, setColumnVisibility] = React.useState({}) @@ -60,8 +65,6 @@ export function StakingTable({ validators, stakesByValidator, isLoading }: Staki const { transactionSigner, activeAddress } = useWallet() - const { data: constraints } = useQuery(constraintsQueryOptions) - const router = useRouter() const queryClient = useQueryClient() diff --git a/ui/src/components/ValidatorTable.tsx b/ui/src/components/ValidatorTable.tsx index 85bf0278..ab7c74df 100644 --- a/ui/src/components/ValidatorTable.tsx +++ b/ui/src/components/ValidatorTable.tsx @@ -1,5 +1,4 @@ import { AlgoAmount } from '@algorandfoundation/algokit-utils/types/amount' -import { useQuery } from '@tanstack/react-query' import { Link } from '@tanstack/react-router' import { ColumnDef, @@ -15,7 +14,6 @@ import { import { useWallet } from '@txnlab/use-wallet-react' import { FlaskConical, MoreHorizontal } from 'lucide-react' import * as React from 'react' -import { constraintsQueryOptions } from '@/api/queries' import { AddPoolModal } from '@/components/AddPoolModal' import { AddStakeModal } from '@/components/AddStakeModal' import { AlgoDisplayAmount } from '@/components/AlgoDisplayAmount' @@ -42,7 +40,7 @@ import { } from '@/components/ui/table' import { UnstakeModal } from '@/components/UnstakeModal' import { StakerValidatorData } from '@/interfaces/staking' -import { Validator } from '@/interfaces/validator' +import { Constraints, Validator } from '@/interfaces/validator' import { calculateMaxStake, calculateMaxStakers, @@ -59,9 +57,14 @@ import { cn } from '@/utils/ui' interface ValidatorTableProps { validators: Validator[] stakesByValidator: StakerValidatorData[] + constraints: Constraints } -export function ValidatorTable({ validators, stakesByValidator }: ValidatorTableProps) { +export function ValidatorTable({ + validators, + stakesByValidator, + constraints, +}: ValidatorTableProps) { const [sorting, setSorting] = React.useState([]) const [columnFilters, setColumnFilters] = React.useState([]) const [columnVisibility, setColumnVisibility] = React.useState({}) @@ -73,8 +76,6 @@ export function ValidatorTable({ validators, stakesByValidator }: ValidatorTable const { transactionSigner, activeAddress } = useWallet() - const { data: constraints } = useQuery(constraintsQueryOptions) - const columns: ColumnDef[] = [ { accessorKey: 'id', @@ -138,7 +139,7 @@ export function ValidatorTable({ validators, stakesByValidator }: ValidatorTable if (validator.state.numPools == 0) return '--' const totalStakers = validator.state.totalStakers - const maxStakers = calculateMaxStakers(validator) + const maxStakers = calculateMaxStakers(validator, constraints) return ( @@ -173,7 +174,7 @@ export function ValidatorTable({ validators, stakesByValidator }: ValidatorTable const validator = row.original const stakingDisabled = isStakingDisabled(activeAddress, validator, constraints) const unstakingDisabled = isUnstakingDisabled(activeAddress, validator, stakesByValidator) - const addingPoolDisabled = isAddingPoolDisabled(activeAddress, validator) + const addingPoolDisabled = isAddingPoolDisabled(activeAddress, validator, constraints) const canManage = canManageValidator(activeAddress, validator) const isDevelopment = process.env.NODE_ENV === 'development' @@ -313,7 +314,7 @@ export function ValidatorTable({ validators, stakesByValidator }: ValidatorTable ))} - {table.getRowModel().rows?.length ? ( + {table.getRowModel().rows.length ? ( table.getRowModel().rows.map((row) => ( {row.getVisibleCells().map((cell) => ( diff --git a/ui/src/routes/index.tsx b/ui/src/routes/index.tsx index c3c2f820..3094f9d1 100644 --- a/ui/src/routes/index.tsx +++ b/ui/src/routes/index.tsx @@ -2,7 +2,7 @@ import { useQuery, useSuspenseQuery } from '@tanstack/react-query' import { createFileRoute } from '@tanstack/react-router' import { useWallet } from '@txnlab/use-wallet-react' import { fetchStakerValidatorData } from '@/api/contracts' -import { validatorsQueryOptions } from '@/api/queries' +import { constraintsQueryOptions, validatorsQueryOptions } from '@/api/queries' import { Meta } from '@/components/Meta' import { PageHeader } from '@/components/PageHeader' import { PageMain } from '@/components/PageMain' @@ -11,7 +11,16 @@ import { ValidatorTable } from '@/components/ValidatorTable' import { StakerValidatorData } from '@/interfaces/staking' export const Route = createFileRoute('/')({ - loader: ({ context: { queryClient } }) => queryClient.ensureQueryData(validatorsQueryOptions), + beforeLoad: () => { + return { + validatorsQueryOptions, + constraintsQueryOptions, + } + }, + loader: async ({ context: { queryClient, validatorsQueryOptions, constraintsQueryOptions } }) => { + queryClient.ensureQueryData(validatorsQueryOptions) + queryClient.ensureQueryData(constraintsQueryOptions) + }, component: Dashboard, pendingComponent: () =>
Loading...
, errorComponent: ({ error }) => { @@ -26,6 +35,9 @@ function Dashboard() { const validatorsQuery = useSuspenseQuery(validatorsQueryOptions) const validators = validatorsQuery.data + const constraintsQuery = useSuspenseQuery(constraintsQueryOptions) + const constraints = constraintsQuery.data + const { activeAddress } = useWallet() const stakesQuery = useQuery({ @@ -47,8 +59,13 @@ function Dashboard() { validators={validators || []} stakesByValidator={stakesByValidator} isLoading={stakesQuery.isLoading} + constraints={constraints} + /> + - diff --git a/ui/src/utils/contracts.ts b/ui/src/utils/contracts.ts index 550a497d..7dffddf5 100644 --- a/ui/src/utils/contracts.ts +++ b/ui/src/utils/contracts.ts @@ -405,9 +405,8 @@ export function calculateMaxStake( return maxStake } -export function calculateMaxStakers(validator: Validator): number { - // @todo: fetch max stakers from contract - const maxStakersPerPool = 200 +export function calculateMaxStakers(validator: Validator, constraints?: Constraints): number { + const maxStakersPerPool = constraints?.maxStakersPerPool || 0 const maxStakers = maxStakersPerPool * validator.state.numPools return maxStakers @@ -428,8 +427,7 @@ export function isStakingDisabled( maxAlgoPerPool = constraints.maxAlgoPerPool } - // @todo: fetch max stakers from contract - const maxStakersPerPool = 200 + const maxStakersPerPool = constraints?.maxStakersPerPool || 0 const maxStakers = maxStakersPerPool * numPools const maxStake = Number(maxAlgoPerPool) * numPools @@ -455,16 +453,19 @@ export function isUnstakingDisabled( return noPools || !validatorHasStake } -export function isAddingPoolDisabled(activeAddress: string | null, validator: Validator): boolean { - if (!activeAddress) { +export function isAddingPoolDisabled( + activeAddress: string | null, + validator: Validator, + constraints?: Constraints, +): boolean { + if (!activeAddress || !constraints) { return true } - // @todo: define totalNodes as global constant or fetch from protocol constraints - const totalNodes = 4 + const maxNodes = constraints.maxNodes const { numPools } = validator.state const { poolsPerNode } = validator.config - const hasAvailableSlots = numPools < poolsPerNode * totalNodes + const hasAvailableSlots = numPools < poolsPerNode * maxNodes return !hasAvailableSlots }