Rename staking validators page to Validators (#7378)
* Rename staking validators page to Validators * Adjust * Dedupe summary * Cleanups
This commit is contained in:
parent
8770164425
commit
ba90464cb3
@ -45,8 +45,8 @@ To start off, this repo (along with others in the [@polkadot](https://github.com
|
|||||||
To get started -
|
To get started -
|
||||||
|
|
||||||
1. Clone the repo locally, via `git clone https://github.com/polkadot-js/apps <optional local path>`
|
1. Clone the repo locally, via `git clone https://github.com/polkadot-js/apps <optional local path>`
|
||||||
2. Ensure that you have a recent LTS version of Node.js, for development purposes [Node >=10.13.0](https://nodejs.org/en/) is recommended.
|
2. Ensure that you have a recent LTS version of Node.js, for development purposes [Node >= 16](https://nodejs.org/en/) is recommended.
|
||||||
3. Ensure that you have a recent version of Yarn, for development purposes [Yarn >=1.10.1](https://yarnpkg.com/docs/install) is required.
|
3. Ensure that you have a recent version of Yarn, for development purposes [Yarn >= 1.22](https://yarnpkg.com/docs/install) is required.
|
||||||
4. Install the dependencies by running `yarn`
|
4. Install the dependencies by running `yarn`
|
||||||
5. Ready! Now you can launch the UI (assuming you have a local Polkadot Node running), via `yarn run start`
|
5. Ready! Now you can launch the UI (assuming you have a local Polkadot Node running), via `yarn run start`
|
||||||
6. Access the UI via [http://localhost:3000](http://localhost:3000)
|
6. Access the UI via [http://localhost:3000](http://localhost:3000)
|
||||||
|
|||||||
@ -11,6 +11,9 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/polkadot-js/apps.git"
|
"url": "https://github.com/polkadot-js/apps.git"
|
||||||
},
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.0.0"
|
||||||
|
},
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"version": "0.112.2-15",
|
"version": "0.112.2-15",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
// Copyright 2017-2022 @polkadot/app-staking authors & contributors
|
// Copyright 2017-2022 @polkadot/app-staking authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import type { DeriveSessionIndexes } from '@polkadot/api-derive/types';
|
|
||||||
import type { Option } from '@polkadot/types';
|
import type { Option } from '@polkadot/types';
|
||||||
import type { Balance } from '@polkadot/types/interfaces';
|
import type { Balance } from '@polkadot/types/interfaces';
|
||||||
import type { BN } from '@polkadot/util';
|
import type { BN } from '@polkadot/util';
|
||||||
@ -11,12 +10,13 @@ import React, { useMemo } from 'react';
|
|||||||
import { CardSummary, SummaryBox } from '@polkadot/react-components';
|
import { CardSummary, SummaryBox } from '@polkadot/react-components';
|
||||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||||
import { FormatBalance } from '@polkadot/react-query';
|
import { FormatBalance } from '@polkadot/react-query';
|
||||||
import { BN_ONE, BN_ZERO } from '@polkadot/util';
|
import { BN_ZERO } from '@polkadot/util';
|
||||||
|
|
||||||
import { useTranslation } from '../translate';
|
import { useTranslation } from '../translate';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
avgStaked?: BN;
|
avgStaked?: BN;
|
||||||
|
lastEra?: BN;
|
||||||
lowStaked?: BN;
|
lowStaked?: BN;
|
||||||
minNominated?: BN;
|
minNominated?: BN;
|
||||||
minNominatorBond?: BN;
|
minNominatorBond?: BN;
|
||||||
@ -27,46 +27,46 @@ interface Props {
|
|||||||
totalStaked?: BN;
|
totalStaked?: BN;
|
||||||
}
|
}
|
||||||
|
|
||||||
const transformReward = {
|
interface ProgressInfo {
|
||||||
transform: (optBalance: Option<Balance>) => optBalance.unwrapOrDefault()
|
hideValue: true;
|
||||||
|
total: BN;
|
||||||
|
value: BN;
|
||||||
|
}
|
||||||
|
|
||||||
|
const OPT_REWARD = {
|
||||||
|
transform: (optBalance: Option<Balance>) =>
|
||||||
|
optBalance.unwrapOrDefault()
|
||||||
};
|
};
|
||||||
|
|
||||||
const transformEra = {
|
function getProgressInfo (value?: BN, total?: BN): ProgressInfo | undefined {
|
||||||
transform: ({ activeEra }: DeriveSessionIndexes) => activeEra.gt(BN_ZERO) ? activeEra.sub(BN_ONE) : undefined
|
return value && total && !total.isZero()
|
||||||
};
|
? {
|
||||||
|
hideValue: true,
|
||||||
|
total,
|
||||||
|
value
|
||||||
|
}
|
||||||
|
: undefined;
|
||||||
|
}
|
||||||
|
|
||||||
function Summary ({ avgStaked, lowStaked, minNominated, minNominatorBond, stakedReturn, totalIssuance, totalStaked }: Props): React.ReactElement<Props> {
|
function Summary ({ avgStaked, lastEra, lowStaked, minNominated, minNominatorBond, stakedReturn, totalIssuance, totalStaked }: Props): React.ReactElement<Props> {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { api } = useApi();
|
const { api } = useApi();
|
||||||
const lastEra = useCall<BN | undefined>(api.derive.session.indexes, undefined, transformEra);
|
const lastReward = useCall<BN>(lastEra && api.query.staking.erasValidatorReward, [lastEra], OPT_REWARD);
|
||||||
const lastReward = useCall<BN>(lastEra && api.query.staking.erasValidatorReward, [lastEra], transformReward);
|
|
||||||
|
|
||||||
const progressStake = useMemo(
|
const progressStake = useMemo(
|
||||||
() => totalIssuance && totalStaked && totalStaked.gtn(0)
|
() => getProgressInfo(totalStaked, totalIssuance),
|
||||||
? {
|
|
||||||
hideValue: true,
|
|
||||||
total: totalIssuance,
|
|
||||||
value: totalStaked
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
[totalIssuance, totalStaked]
|
[totalIssuance, totalStaked]
|
||||||
);
|
);
|
||||||
|
|
||||||
const progressAvg = useMemo(
|
const progressAvg = useMemo(
|
||||||
() => avgStaked && lowStaked && avgStaked.gtn(0)
|
() => getProgressInfo(lowStaked, avgStaked),
|
||||||
? {
|
|
||||||
hideValue: true,
|
|
||||||
total: avgStaked,
|
|
||||||
value: lowStaked
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
[avgStaked, lowStaked]
|
[avgStaked, lowStaked]
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SummaryBox>
|
<SummaryBox>
|
||||||
<section className='media--800'>
|
<section className='media--800'>
|
||||||
{totalIssuance && totalStaked?.gt(BN_ZERO) && (
|
{progressStake && (
|
||||||
<CardSummary
|
<CardSummary
|
||||||
label={t<string>('total staked')}
|
label={t<string>('total staked')}
|
||||||
progress={progressStake}
|
progress={progressStake}
|
||||||
@ -86,7 +86,7 @@ function Summary ({ avgStaked, lowStaked, minNominated, minNominatorBond, staked
|
|||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
<section className='media--1000'>
|
<section className='media--1000'>
|
||||||
{avgStaked?.gtn(0) && lowStaked?.gtn(0) && (
|
{progressAvg && (
|
||||||
<CardSummary
|
<CardSummary
|
||||||
label={`${t<string>('lowest / avg staked')}`}
|
label={`${t<string>('lowest / avg staked')}`}
|
||||||
progress={progressAvg}
|
progress={progressAvg}
|
||||||
@ -131,7 +131,7 @@ function Summary ({ avgStaked, lowStaked, minNominated, minNominatorBond, staked
|
|||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
{lastReward?.gtn(0) && (
|
{lastReward?.gt(BN_ZERO) && (
|
||||||
<CardSummary label={t<string>('last reward')}>
|
<CardSummary label={t<string>('last reward')}>
|
||||||
<FormatBalance
|
<FormatBalance
|
||||||
value={lastReward}
|
value={lastReward}
|
||||||
|
|||||||
@ -14,8 +14,8 @@ import { FormatBalance } from '@polkadot/react-query';
|
|||||||
import { formatNumber } from '@polkadot/util';
|
import { formatNumber } from '@polkadot/util';
|
||||||
|
|
||||||
import MaxBadge from '../MaxBadge';
|
import MaxBadge from '../MaxBadge';
|
||||||
import Favorite from '../Overview/Address/Favorite';
|
|
||||||
import { useTranslation } from '../translate';
|
import { useTranslation } from '../translate';
|
||||||
|
import Favorite from '../Validators/Address/Favorite';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
allSlashes?: [BN, UnappliedSlash[]][];
|
allSlashes?: [BN, UnappliedSlash[]][];
|
||||||
|
|||||||
@ -192,7 +192,7 @@ const DEFAULT_NAME = { isQueryFiltered: false, nameFilter: '' };
|
|||||||
|
|
||||||
const DEFAULT_SORT: SortState = { sortBy: 'rankOverall', sortFromMax: true };
|
const DEFAULT_SORT: SortState = { sortBy: 'rankOverall', sortFromMax: true };
|
||||||
|
|
||||||
function Targets ({ className = '', isInElection, nominatedBy, ownStashes, targets: { avgStaked, inflation: { stakedReturn }, lowStaked, medianComm, minNominated, minNominatorBond, nominators, totalIssuance, totalStaked, validatorIds, validators }, toggleFavorite, toggleLedger, toggleNominatedBy }: Props): React.ReactElement<Props> {
|
function Targets ({ className = '', isInElection, nominatedBy, ownStashes, targets: { avgStaked, inflation: { stakedReturn }, lastEra, lowStaked, medianComm, minNominated, minNominatorBond, nominators, totalIssuance, totalStaked, validatorIds, validators }, toggleFavorite, toggleLedger, toggleNominatedBy }: Props): React.ReactElement<Props> {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { api } = useApi();
|
const { api } = useApi();
|
||||||
const allSlashes = useAvailableSlashes();
|
const allSlashes = useAvailableSlashes();
|
||||||
@ -362,6 +362,7 @@ function Targets ({ className = '', isInElection, nominatedBy, ownStashes, targe
|
|||||||
<div className={className}>
|
<div className={className}>
|
||||||
<Summary
|
<Summary
|
||||||
avgStaked={avgStaked}
|
avgStaked={avgStaked}
|
||||||
|
lastEra={lastEra}
|
||||||
lowStaked={lowStaked}
|
lowStaked={lowStaked}
|
||||||
minNominated={minNominated}
|
minNominated={minNominated}
|
||||||
minNominatorBond={minNominatorBond}
|
minNominatorBond={minNominatorBond}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import React from 'react';
|
|||||||
|
|
||||||
import { MarkWarning } from '@polkadot/react-components';
|
import { MarkWarning } from '@polkadot/react-components';
|
||||||
|
|
||||||
import { useTranslation } from './translate';
|
import { useTranslation } from '../translate';
|
||||||
|
|
||||||
function ActionsBanner (): React.ReactElement<null> | null {
|
function ActionsBanner (): React.ReactElement<null> | null {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
@ -15,17 +15,16 @@ import { useTranslation } from '../translate';
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
||||||
isVisible: boolean;
|
|
||||||
nominators?: string[];
|
nominators?: string[];
|
||||||
stakingOverview?: DeriveStakingOverview;
|
stakingOverview?: DeriveStakingOverview;
|
||||||
targets: SortedTargets;
|
targets: SortedTargets;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Summary ({ className = '', isVisible, stakingOverview, targets: { counterForNominators, inflation: { idealStake, inflation, stakedFraction }, nominators, waitingIds } }: Props): React.ReactElement<Props> {
|
function Summary ({ className = '', stakingOverview, targets: { counterForNominators, inflation: { idealStake, inflation, stakedFraction }, nominators, waitingIds } }: Props): React.ReactElement<Props> {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SummaryBox className={`${className} ${isVisible ? '' : ' --hidden'}`}>
|
<SummaryBox className={className}>
|
||||||
<section>
|
<section>
|
||||||
<CardSummary label={t<string>('validators')}>
|
<CardSummary label={t<string>('validators')}>
|
||||||
{stakingOverview
|
{stakingOverview
|
||||||
@ -12,11 +12,14 @@ import { Button, ToggleGroup } from '@polkadot/react-components';
|
|||||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||||
|
|
||||||
import { useTranslation } from '../translate';
|
import { useTranslation } from '../translate';
|
||||||
|
import ActionsBanner from './ActionsBanner';
|
||||||
import CurrentList from './CurrentList';
|
import CurrentList from './CurrentList';
|
||||||
|
import Summary from './Summary';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
||||||
favorites: string[];
|
favorites: string[];
|
||||||
|
hasAccounts: boolean;
|
||||||
hasQueries: boolean;
|
hasQueries: boolean;
|
||||||
minCommission?: BN;
|
minCommission?: BN;
|
||||||
nominatedBy?: NominatedByMap;
|
nominatedBy?: NominatedByMap;
|
||||||
@ -29,7 +32,7 @@ interface Props {
|
|||||||
toggleNominatedBy: () => void;
|
toggleNominatedBy: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Overview ({ className = '', favorites, hasQueries, minCommission, nominatedBy, ownStashes, paraValidators, stakingOverview, targets, toggleFavorite, toggleLedger, toggleNominatedBy }: Props): React.ReactElement<Props> {
|
function Overview ({ className = '', favorites, hasAccounts, hasQueries, minCommission, nominatedBy, ownStashes, paraValidators, stakingOverview, targets, toggleFavorite, toggleLedger, toggleNominatedBy }: Props): React.ReactElement<Props> {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { api } = useApi();
|
const { api } = useApi();
|
||||||
const [intentIndex, _setIntentIndex] = useState(0);
|
const [intentIndex, _setIntentIndex] = useState(0);
|
||||||
@ -67,6 +70,13 @@ function Overview ({ className = '', favorites, hasQueries, minCommission, nomin
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={`staking--Overview ${className}`}>
|
<div className={`staking--Overview ${className}`}>
|
||||||
|
<Summary
|
||||||
|
stakingOverview={stakingOverview}
|
||||||
|
targets={targets}
|
||||||
|
/>
|
||||||
|
{hasAccounts && (ownStashes?.length === 0) && (
|
||||||
|
<ActionsBanner />
|
||||||
|
)}
|
||||||
<Button.Group>
|
<Button.Group>
|
||||||
<ToggleGroup
|
<ToggleGroup
|
||||||
onChange={setTypeIndex}
|
onChange={setTypeIndex}
|
||||||
@ -16,12 +16,9 @@ import { useAccounts, useApi, useAvailableSlashes, useCall, useCallMulti, useFav
|
|||||||
import { isFunction } from '@polkadot/util';
|
import { isFunction } from '@polkadot/util';
|
||||||
|
|
||||||
import basicMd from './md/basic.md';
|
import basicMd from './md/basic.md';
|
||||||
import Summary from './Overview/Summary';
|
|
||||||
import Actions from './Actions';
|
import Actions from './Actions';
|
||||||
import ActionsBanner from './ActionsBanner';
|
|
||||||
import Bags from './Bags';
|
import Bags from './Bags';
|
||||||
import { STORE_FAVS_BASE } from './constants';
|
import { STORE_FAVS_BASE } from './constants';
|
||||||
import Overview from './Overview';
|
|
||||||
import Payouts from './Payouts';
|
import Payouts from './Payouts';
|
||||||
import Pools from './Pools';
|
import Pools from './Pools';
|
||||||
import Query from './Query';
|
import Query from './Query';
|
||||||
@ -30,10 +27,11 @@ import Targets from './Targets';
|
|||||||
import { useTranslation } from './translate';
|
import { useTranslation } from './translate';
|
||||||
import useNominations from './useNominations';
|
import useNominations from './useNominations';
|
||||||
import useSortedTargets from './useSortedTargets';
|
import useSortedTargets from './useSortedTargets';
|
||||||
|
import Validators from './Validators';
|
||||||
|
|
||||||
const HIDDEN_ACC = ['actions', 'payout'];
|
const HIDDEN_ACC = ['actions', 'payout'];
|
||||||
|
|
||||||
const optionsParaValidators = {
|
const OPT_MULTI = {
|
||||||
defaultValue: [false, undefined, {}] as [boolean, BN | undefined, Record<string, boolean>],
|
defaultValue: [false, undefined, {}] as [boolean, BN | undefined, Record<string, boolean>],
|
||||||
transform: ([eraElectionStatus, minValidatorBond, validators, activeValidatorIndices]: [ElectionStatus | null, BN | undefined, ValidatorId[] | null, ParaValidatorIndex[] | null]): [boolean, BN | undefined, Record<string, boolean>] => [
|
transform: ([eraElectionStatus, minValidatorBond, validators, activeValidatorIndices]: [ElectionStatus | null, BN | undefined, ValidatorId[] | null, ParaValidatorIndex[] | null]): [boolean, BN | undefined, Record<string, boolean>] => [
|
||||||
!!eraElectionStatus && eraElectionStatus.isOpen,
|
!!eraElectionStatus && eraElectionStatus.isOpen,
|
||||||
@ -61,7 +59,7 @@ function StakingApp ({ basePath, className = '' }: Props): React.ReactElement<Pr
|
|||||||
api.query.staking.minCommission,
|
api.query.staking.minCommission,
|
||||||
api.query.session.validators,
|
api.query.session.validators,
|
||||||
(api.query.parasShared || api.query.shared)?.activeValidatorIndices
|
(api.query.parasShared || api.query.shared)?.activeValidatorIndices
|
||||||
], optionsParaValidators);
|
], OPT_MULTI);
|
||||||
const ownStashes = useOwnStashInfos();
|
const ownStashes = useOwnStashInfos();
|
||||||
const slashes = useAvailableSlashes();
|
const slashes = useAvailableSlashes();
|
||||||
const targets = useSortedTargets(favorites, withLedger);
|
const targets = useSortedTargets(favorites, withLedger);
|
||||||
@ -142,11 +140,6 @@ function StakingApp ({ basePath, className = '' }: Props): React.ReactElement<Pr
|
|||||||
}
|
}
|
||||||
items={items}
|
items={items}
|
||||||
/>
|
/>
|
||||||
<Summary
|
|
||||||
isVisible={pathname === basePath}
|
|
||||||
stakingOverview={stakingOverview}
|
|
||||||
targets={targets}
|
|
||||||
/>
|
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path={`${basePath}/bags`}>
|
<Route path={`${basePath}/bags`}>
|
||||||
<Bags ownStashes={ownStashes} />
|
<Bags ownStashes={ownStashes} />
|
||||||
@ -189,12 +182,10 @@ function StakingApp ({ basePath, className = '' }: Props): React.ReactElement<Pr
|
|||||||
ownStashes={ownStashes}
|
ownStashes={ownStashes}
|
||||||
targets={targets}
|
targets={targets}
|
||||||
/>
|
/>
|
||||||
{basePath === pathname && hasAccounts && (ownStashes?.length === 0) && (
|
<Validators
|
||||||
<ActionsBanner />
|
|
||||||
)}
|
|
||||||
<Overview
|
|
||||||
className={basePath === pathname ? '' : '--hidden'}
|
className={basePath === pathname ? '' : '--hidden'}
|
||||||
favorites={favorites}
|
favorites={favorites}
|
||||||
|
hasAccounts={hasAccounts}
|
||||||
hasQueries={hasQueries}
|
hasQueries={hasQueries}
|
||||||
minCommission={minCommission}
|
minCommission={minCommission}
|
||||||
nominatedBy={nominatedBy}
|
nominatedBy={nominatedBy}
|
||||||
|
|||||||
@ -78,6 +78,7 @@ export interface SortedTargets {
|
|||||||
counterForValidators?: BN;
|
counterForValidators?: BN;
|
||||||
electedIds?: string[];
|
electedIds?: string[];
|
||||||
inflation: Inflation;
|
inflation: Inflation;
|
||||||
|
lastEra?: BN;
|
||||||
lowStaked?: BN;
|
lowStaked?: BN;
|
||||||
medianComm: number;
|
medianComm: number;
|
||||||
maxNominatorsCount?: BN;
|
maxNominatorsCount?: BN;
|
||||||
|
|||||||
@ -5,19 +5,22 @@ import type { DeriveHasIdentity } from '@polkadot/api-derive/types';
|
|||||||
|
|
||||||
import { createNamedHook, useApi, useCall } from '@polkadot/react-hooks';
|
import { createNamedHook, useApi, useCall } from '@polkadot/react-hooks';
|
||||||
|
|
||||||
function transformIdentity ([[validatorIds], hasIdentities]: [[string[]], DeriveHasIdentity[]]): Record<string, DeriveHasIdentity> {
|
|
||||||
return validatorIds.reduce((result: Record<string, DeriveHasIdentity>, validatorId, index): Record<string, DeriveHasIdentity> => {
|
|
||||||
result[validatorId] = hasIdentities[index];
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
type Result = Record<string, DeriveHasIdentity>;
|
type Result = Record<string, DeriveHasIdentity>;
|
||||||
|
|
||||||
|
const OPT_CALL = {
|
||||||
|
transform: ([[validatorIds], hasIdentities]: [[string[]], DeriveHasIdentity[]]): Record<string, DeriveHasIdentity> => {
|
||||||
|
return validatorIds.reduce((result: Record<string, DeriveHasIdentity>, validatorId, index): Record<string, DeriveHasIdentity> => {
|
||||||
|
result[validatorId] = hasIdentities[index];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}, {});
|
||||||
|
},
|
||||||
|
withParamsTransform: true
|
||||||
|
};
|
||||||
|
|
||||||
function useIdentitiesImpl (validatorIds: string[] = []): Result | undefined {
|
function useIdentitiesImpl (validatorIds: string[] = []): Result | undefined {
|
||||||
const { api } = useApi();
|
const { api } = useApi();
|
||||||
const allIdentity = useCall<Result>(api.derive.accounts.hasIdentityMulti, [validatorIds], { transform: transformIdentity, withParamsTransform: true });
|
const allIdentity = useCall<Result>(api.derive.accounts.hasIdentityMulti, [validatorIds], OPT_CALL);
|
||||||
|
|
||||||
return allIdentity;
|
return allIdentity;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -231,6 +231,7 @@ function extractBaseInfo (api: ApiPromise, allAccounts: string[], electedDerive:
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
avgStaked,
|
avgStaked,
|
||||||
|
lastEra: lastEraInfo.lastEra,
|
||||||
lowStaked: activeTotals[0] || BN_ZERO,
|
lowStaked: activeTotals[0] || BN_ZERO,
|
||||||
medianComm,
|
medianComm,
|
||||||
minNominated,
|
minNominated,
|
||||||
@ -244,16 +245,18 @@ function extractBaseInfo (api: ApiPromise, allAccounts: string[], electedDerive:
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const transformEra = {
|
const OPT_ERA = {
|
||||||
transform: ({ activeEra, eraLength, sessionLength }: DeriveSessionInfo): LastEra => ({
|
transform: ({ activeEra, eraLength, sessionLength }: DeriveSessionInfo): LastEra => ({
|
||||||
activeEra,
|
activeEra,
|
||||||
eraLength,
|
eraLength,
|
||||||
lastEra: activeEra.isZero() ? BN_ZERO : activeEra.subn(1),
|
lastEra: activeEra.isZero()
|
||||||
|
? BN_ZERO
|
||||||
|
: activeEra.sub(BN_ONE),
|
||||||
sessionLength
|
sessionLength
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
const transformMulti = {
|
const OPT_MULTI = {
|
||||||
defaultValue: {},
|
defaultValue: {},
|
||||||
transform: ([historyDepth, counterForNominators, counterForValidators, optMaxNominatorsCount, optMaxValidatorsCount, minNominatorBond, minValidatorBond, totalIssuance]: [BN, BN?, BN?, Option<u32>?, Option<u32>?, BN?, BN?, BN?]): MultiResult => ({
|
transform: ([historyDepth, counterForNominators, counterForValidators, optMaxNominatorsCount, optMaxValidatorsCount, minNominatorBond, minValidatorBond, totalIssuance]: [BN, BN?, BN?, Option<u32>?, Option<u32>?, BN?, BN?, BN?]): MultiResult => ({
|
||||||
counterForNominators,
|
counterForNominators,
|
||||||
@ -283,10 +286,10 @@ function useSortedTargetsImpl (favorites: string[], withLedger: boolean): Sorted
|
|||||||
api.query.staking.minNominatorBond,
|
api.query.staking.minNominatorBond,
|
||||||
api.query.staking.minValidatorBond,
|
api.query.staking.minValidatorBond,
|
||||||
api.query.balances?.totalIssuance
|
api.query.balances?.totalIssuance
|
||||||
], transformMulti);
|
], OPT_MULTI);
|
||||||
const electedInfo = useCall<DeriveStakingElected>(api.derive.staking.electedInfo, [{ ...DEFAULT_FLAGS_ELECTED, withLedger }]);
|
const electedInfo = useCall<DeriveStakingElected>(api.derive.staking.electedInfo, [{ ...DEFAULT_FLAGS_ELECTED, withLedger }]);
|
||||||
const waitingInfo = useCall<DeriveStakingWaiting>(api.derive.staking.waitingInfo, [{ ...DEFAULT_FLAGS_WAITING, withLedger }]);
|
const waitingInfo = useCall<DeriveStakingWaiting>(api.derive.staking.waitingInfo, [{ ...DEFAULT_FLAGS_WAITING, withLedger }]);
|
||||||
const lastEraInfo = useCall<LastEra>(api.derive.session.info, undefined, transformEra);
|
const lastEraInfo = useCall<LastEra>(api.derive.session.info, undefined, OPT_ERA);
|
||||||
|
|
||||||
const baseInfo = useMemo(
|
const baseInfo = useMemo(
|
||||||
() => electedInfo && lastEraInfo && totalIssuance && waitingInfo
|
() => electedInfo && lastEraInfo && totalIssuance && waitingInfo
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user