diff --git a/.changelog/2399.bugfix.md b/.changelog/2399.bugfix.md new file mode 100644 index 0000000000..d5d155d246 --- /dev/null +++ b/.changelog/2399.bugfix.md @@ -0,0 +1 @@ +Prepare Explorer for incoming breaking changes in Nexus API diff --git a/src/app/components/LabeledProgress/index.tsx b/src/app/components/LabeledProgress/index.tsx index 9536cef1e5..3fea963990 100644 --- a/src/app/components/LabeledProgress/index.tsx +++ b/src/app/components/LabeledProgress/index.tsx @@ -1,20 +1,23 @@ import { FC, ReactNode } from 'react' import { Progress } from '@oasisprotocol/ui-library/src/components/progress' +import { calculatePercentage } from '../../utils/number-utils' type LabeledProgresssProps = { - value?: number - max?: number + value?: number | string + max?: number | string label: ReactNode } export const LabeledProgress: FC = ({ value, max, label }) => { - if (!value || !max) { + const percentage = calculatePercentage(value, max) + + if (percentage === null) { return null } return (
- + {label} diff --git a/src/app/components/PercentageValue/index.tsx b/src/app/components/PercentageValue/index.tsx index 3d87497059..312def4edc 100644 --- a/src/app/components/PercentageValue/index.tsx +++ b/src/app/components/PercentageValue/index.tsx @@ -1,10 +1,11 @@ import { FC } from 'react' import { useTranslation } from 'react-i18next' +import { calculatePercentage } from '../../utils/number-utils' type PercentageValueProps = { adaptMaximumFractionDigits?: boolean - total?: number - value: number | undefined + total?: number | string + value: number | string | undefined maximumFractionDigits?: number } @@ -16,12 +17,12 @@ export const PercentageValue: FC = ({ }) => { const { t } = useTranslation() - if (typeof value !== 'number' || typeof total !== 'number' || total <= 0) { + const percentageValue = calculatePercentage(value, total, false) + + if (percentageValue === null) { return null } - const percentageValue = value / total - return ( <> {t('common.valuePair', { diff --git a/src/app/components/Validators/ValidatorCumulativeVoting.tsx b/src/app/components/Validators/ValidatorCumulativeVoting.tsx index 888f3e1a44..654a1b9f4b 100644 --- a/src/app/components/Validators/ValidatorCumulativeVoting.tsx +++ b/src/app/components/Validators/ValidatorCumulativeVoting.tsx @@ -1,10 +1,11 @@ import { FC } from 'react' import { PercentageValue } from '../PercentageValue' +import { calculatePercentage } from '../../utils/number-utils' type ValidatorCumulativeVotingProps = { containerMarginThemeSpacing: number - value: number | undefined - total: number | undefined + value: number | string | undefined + total: number | string | undefined } export const ValidatorCumulativeVoting: FC = ({ @@ -12,12 +13,12 @@ export const ValidatorCumulativeVoting: FC = ({ value, total, }) => { - if (typeof value !== 'number' || typeof total !== 'number' || total <= 0) { + const percentage = calculatePercentage(value, total) + + if (percentage === null) { return null } - const percentage = (value / total) * 100 - return (
= ({ validator, stats }) ({validator?.voting_power.toLocaleString()}) + validator?.voting_power !== undefined && ( + ({new BigNumber(validator?.voting_power).toFormat()}) ) } withContentPadding={false} > - {typeof validator?.voting_power === 'number' && stats?.total_voting_power && ( + {validator?.voting_power !== undefined && stats?.total_voting_power && ( <> {t('validator.votingPowerOverall')} diff --git a/src/app/pages/ValidatorDetailsPage/index.tsx b/src/app/pages/ValidatorDetailsPage/index.tsx index 852fe64c37..2cbcb1960e 100644 --- a/src/app/pages/ValidatorDetailsPage/index.tsx +++ b/src/app/pages/ValidatorDetailsPage/index.tsx @@ -2,6 +2,7 @@ import { FC } from 'react' import { useTranslation } from 'react-i18next' import { useHref, useLoaderData } from 'react-router-dom' import { Card, CardContent } from '@oasisprotocol/ui-library/src/components/cards' +import BigNumber from 'bignumber.js' import { Validator, ValidatorAggStats, @@ -229,17 +230,17 @@ export const ValidatorDetailsView: FC<{
{formattedTime}
)} - {typeof validator.voting_power === 'number' && ( + {validator.voting_power !== undefined && ( <>
{t('validator.votingPower')}
{stats?.total_voting_power ? ( <> -   ({validator.voting_power.toLocaleString()}) +   ({new BigNumber(validator.voting_power).toFormat()}) ) : ( - validator.voting_power.toLocaleString() + new BigNumber(validator.voting_power).toFormat() )}
diff --git a/src/app/utils/number-utils.ts b/src/app/utils/number-utils.ts index 66a13cbfdc..fb22202d83 100644 --- a/src/app/utils/number-utils.ts +++ b/src/app/utils/number-utils.ts @@ -17,3 +17,23 @@ export const getGasPrice = ({ fee = '', gasUsed = '' }): string | null => { } export const convertToNano = (value: string): string => fromBaseUnits(value, -9) + +export const calculatePercentage = ( + value: number | string | undefined, + total: number | string | undefined, + asPercentage: boolean = true, +): number | null => { + if (value === undefined || value === null || total === undefined || total === null) { + return null + } + + const valueBN = new BigNumber(value) + const totalBN = new BigNumber(total) + + if (!valueBN || !totalBN || totalBN.lte(0)) { + return null + } + + const result = valueBN.div(totalBN) + return asPercentage ? result.multipliedBy(100).toNumber() : result.toNumber() +} diff --git a/src/oasis-nexus/generated/api.ts b/src/oasis-nexus/generated/api.ts index 81aab94686..41a36d067f 100644 --- a/src/oasis-nexus/generated/api.ts +++ b/src/oasis-nexus/generated/api.ts @@ -643,7 +643,7 @@ export type ValidatorList = List & ValidatorListAllOf; export interface ValidatorAggStats { /** The total voting power across all validators. */ - total_voting_power: number; + total_voting_power: TextBigInt; /** The total number of delegators in the network. */ total_delegators: number; /** The total amount of token staked to validators. */ @@ -686,9 +686,9 @@ export interface Validator { /** The escrow account data for this validator. */ escrow: Escrow; /** The voting power of this validator. */ - voting_power: number; + voting_power: TextBigInt; /** The cumulative voting power of this validator and all other validators ranked higher than itself. */ - voting_power_cumulative?: number; + voting_power_cumulative?: TextBigInt; /** Whether the entity has a node that is registered for being a validator, node is up to date, and has successfully registered itself. It may or may not be part of validator set. */ active: boolean; /** The second-granular consensus time. */