Adjust useCall options (#3430)
* Adjust useCall options * Extract useCall options * typo * Apply suggestions from code review * Adjust param creation in calls
This commit is contained in:
parent
47bd6d319d
commit
ebad8635f7
@ -66,7 +66,7 @@ function Status ({ optionsAll }: Props): React.ReactElement<Props> {
|
||||
const { api, isApiReady } = useApi();
|
||||
const { allAccounts } = useAccounts();
|
||||
const { t } = useTranslation();
|
||||
const events = useCall<EventRecord[]>(isApiReady && api.query.system?.events, []);
|
||||
const events = useCall<EventRecord[]>(isApiReady && api.query.system?.events);
|
||||
|
||||
useEffect((): void => {
|
||||
const filtered = filterEvents(allAccounts, t, optionsAll, events);
|
||||
|
||||
@ -21,7 +21,7 @@ interface Props {
|
||||
function ChainInfo ({ className = '', isToggled, onClick }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const runtimeVersion = useCall<RuntimeVersion>(api.rpc.state.subscribeRuntimeVersion, []);
|
||||
const runtimeVersion = useCall<RuntimeVersion>(api.rpc.state.subscribeRuntimeVersion);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@ -59,7 +59,7 @@ function checkVisible (name: string, { api, isApiConnected, isApiReady }: ApiPro
|
||||
function Item ({ isCollapsed, onClick, route }: Props): React.ReactElement<Props> | null {
|
||||
const { allAccounts, hasAccounts } = useAccounts();
|
||||
const apiProps = useApi();
|
||||
const sudoKey = useCall<AccountId>(apiProps.isApiReady && apiProps.api.query.sudo?.key, []);
|
||||
const sudoKey = useCall<AccountId>(apiProps.isApiReady && apiProps.api.query.sudo?.key);
|
||||
const [hasSudo, setHasSudo] = useState(false);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const count = (route.useCounter || DUMMY_COUNTER)();
|
||||
|
||||
@ -7,15 +7,14 @@ import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
function WarmUp (): React.ReactElement {
|
||||
const { api, isApiReady } = useApi();
|
||||
const indexes = useCall<unknown>(isApiReady && api.derive.accounts?.indexes, []);
|
||||
const registrars = useCall<unknown>(isApiReady && api.query.identity?.registrars, []);
|
||||
const staking = null; // useCall<unknown>(isApiReady && api.derive.staking?.overview, []);
|
||||
const issuance = useCall<unknown>(isApiReady && api.query.balances?.totalIssuance, []);
|
||||
const historyDepth = useCall<unknown>(api.query.staking?.historyDepth, []);
|
||||
const indexes = useCall<unknown>(isApiReady && api.derive.accounts?.indexes);
|
||||
const registrars = useCall<unknown>(isApiReady && api.query.identity?.registrars);
|
||||
const issuance = useCall<unknown>(isApiReady && api.query.balances?.totalIssuance);
|
||||
const historyDepth = useCall<unknown>(api.query.staking?.historyDepth);
|
||||
const [hasValues, setHasValues] = useState(false);
|
||||
|
||||
useEffect((): void => {
|
||||
setHasValues(!!historyDepth || !!indexes || !!issuance || !!registrars || !!staking);
|
||||
setHasValues(!!historyDepth || !!indexes || !!issuance || !!registrars);
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
|
||||
@ -73,16 +73,18 @@ function createClearDemocracyTx (api: ApiPromise, address: string, unlockableIds
|
||||
);
|
||||
}
|
||||
|
||||
const transformRecovery = {
|
||||
transform: (opt: Option<RecoveryConfig>) => opt.unwrapOr(null)
|
||||
};
|
||||
|
||||
function Account ({ account: { address, meta }, className = '', delegation, filter, isFavorite, proxy, setBalance, toggleFavorite }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { queueExtrinsic } = useContext(StatusContext);
|
||||
const api = useApi();
|
||||
const bestNumber = useCall<BN>(api.api.derive.chain.bestNumber, []);
|
||||
const bestNumber = useCall<BN>(api.api.derive.chain.bestNumber);
|
||||
const balancesAll = useCall<DeriveBalancesAll>(api.api.derive.balances.all, [address]);
|
||||
const democracyLocks = useCall<DeriveDemocracyLock[]>(api.api.derive.democracy?.locks, [address]);
|
||||
const recoveryInfo = useCall<RecoveryConfig | null>(api.api.query.recovery?.recoverable, [address], {
|
||||
transform: (opt: Option<RecoveryConfig>) => opt.unwrapOr(null)
|
||||
});
|
||||
const recoveryInfo = useCall<RecoveryConfig | null>(api.api.query.recovery?.recoverable, [address], transformRecovery);
|
||||
const multiInfos = useMultisigApprovals(address);
|
||||
const proxyInfo = useProxies(address);
|
||||
const { flags: { isDevelopment, isExternal, isHardware, isInjected, isMultisig, isProxied }, genesisHash, identity, name: accName, onSetGenesisHash, tags } = useAccountInfo(address);
|
||||
|
||||
@ -79,14 +79,18 @@ function IdentitySub ({ address, index, name, setAddress, setName, t }: SubProps
|
||||
|
||||
const IdentitySubMemo = React.memo(IdentitySub);
|
||||
|
||||
const transformIds = {
|
||||
transform: ([, ids]: ITuple<[Balance, Vec<AccountId>]>) => ids.map((a) => a.toString())
|
||||
};
|
||||
|
||||
const transformInfo = { withParams: true };
|
||||
|
||||
function IdentitySubModal ({ address, className, onClose }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const { allAccounts } = useAccounts();
|
||||
const queryIds = useCall<string[]>(api.query.identity.subsOf, [address], {
|
||||
transform: ([, ids]: ITuple<[Balance, Vec<AccountId>]>) => ids.map((a) => a.toString())
|
||||
});
|
||||
const queryInfos = useCall<[[string[]], Option<ITuple<[AccountId, Data]>>[]]>(queryIds && queryIds.length !== 0 && api.query.identity.superOf.multi, [queryIds], { withParams: true });
|
||||
const queryIds = useCall<string[]>(api.query.identity.subsOf, [address], transformIds);
|
||||
const queryInfos = useCall<[[string[]], Option<ITuple<[AccountId, Data]>>[]]>(queryIds && queryIds.length !== 0 && api.query.identity.superOf.multi, [queryIds], transformInfo);
|
||||
const [infos, setInfos] = useState<[string, string][] | undefined>();
|
||||
|
||||
useEffect((): void => {
|
||||
|
||||
@ -68,6 +68,10 @@ const Signature = styled.textarea`
|
||||
}
|
||||
`;
|
||||
|
||||
const transformStatement = {
|
||||
transform: (option: Option<StatementKind>) => option.unwrapOr(null)
|
||||
};
|
||||
|
||||
function ClaimsApp (): React.ReactElement {
|
||||
const [didCopy, setDidCopy] = useState(false);
|
||||
const [ethereumAddress, setEthereumAddress] = useState<string | undefined | null>(null);
|
||||
@ -165,9 +169,7 @@ function ClaimsApp (): React.ReactElement {
|
||||
|
||||
// If it's 1/ not preclaimed and 2/ not the old claiming process, fetch the
|
||||
// statement kind to sign.
|
||||
const statementKind = useCall<StatementKind | null>(!isPreclaimed && !isOldClaimProcess && !!ethereumAddress && api.query.claims.signing, [ethereumAddress], {
|
||||
transform: (option: Option<StatementKind>) => option.unwrapOr(null)
|
||||
});
|
||||
const statementKind = useCall<StatementKind | null>(!isPreclaimed && !isOldClaimProcess && !!ethereumAddress && api.query.claims.signing, [ethereumAddress], transformStatement);
|
||||
|
||||
const statementSentence = getStatement(systemChain, statementKind)?.sentence || '';
|
||||
|
||||
|
||||
@ -20,29 +20,29 @@ interface Props {
|
||||
prime: AccountId | null;
|
||||
}
|
||||
|
||||
function transformVotes (entries: DeriveCouncilVotes): Record<string, AccountId[]> {
|
||||
return entries.reduce((result: Record<string, AccountId[]>, [voter, { votes }]): Record<string, AccountId[]> => {
|
||||
votes.forEach((candidate): void => {
|
||||
const address = candidate.toString();
|
||||
const transformVotes = {
|
||||
transform: (entries: DeriveCouncilVotes): Record<string, AccountId[]> => {
|
||||
return entries.reduce((result: Record<string, AccountId[]>, [voter, { votes }]): Record<string, AccountId[]> => {
|
||||
votes.forEach((candidate): void => {
|
||||
const address = candidate.toString();
|
||||
|
||||
if (!result[address]) {
|
||||
result[address] = [];
|
||||
}
|
||||
if (!result[address]) {
|
||||
result[address] = [];
|
||||
}
|
||||
|
||||
result[address].push(voter);
|
||||
});
|
||||
result[address].push(voter);
|
||||
});
|
||||
|
||||
return result;
|
||||
}, {});
|
||||
}
|
||||
return result;
|
||||
}, {});
|
||||
}
|
||||
};
|
||||
|
||||
function Overview ({ className = '', prime }: Props): React.ReactElement<Props> {
|
||||
const { api } = useApi();
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);
|
||||
const electionsInfo = useCall<DeriveElectionsInfo>(api.derive.elections.info, []);
|
||||
const allVotes = useCall<Record<string, AccountId[]>>(api.derive.council.votes, [], {
|
||||
transform: transformVotes
|
||||
});
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber);
|
||||
const electionsInfo = useCall<DeriveElectionsInfo>(api.derive.elections.info);
|
||||
const allVotes = useCall<Record<string, AccountId[]>>(api.derive.council.votes, undefined, transformVotes);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
|
||||
@ -25,14 +25,16 @@ interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const transformPrime = {
|
||||
transform: (result: Option<AccountId>): AccountId | null => result.unwrapOr(null)
|
||||
};
|
||||
|
||||
function CouncilApp ({ basePath, className }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const { pathname } = useLocation();
|
||||
const numMotions = useCounter();
|
||||
const prime = useCall<AccountId | null>(api.query.council.prime, [], {
|
||||
transform: (result: Option<AccountId>): AccountId | null => result.unwrapOr(null)
|
||||
}) || null;
|
||||
const prime = useCall<AccountId | null>(api.query.council.prime, undefined, transformPrime) || null;
|
||||
const motions = useCall<DeriveCollectiveProposals>(api.derive.council.proposals);
|
||||
|
||||
const items = useMemo(() => [
|
||||
|
||||
@ -6,16 +6,14 @@ import { DeriveCollectiveProposals } from '@polkadot/api-derive/types';
|
||||
|
||||
import { useAccounts, useApi, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
function transform (motions: DeriveCollectiveProposals): number {
|
||||
return motions.filter(({ votes }): boolean => !!votes).length;
|
||||
}
|
||||
const transformCounter = {
|
||||
transform: (motions: DeriveCollectiveProposals) => motions.filter(({ votes }): boolean => !!votes).length
|
||||
};
|
||||
|
||||
export default function useCounter (): number {
|
||||
const { hasAccounts } = useAccounts();
|
||||
const { api, isApiReady } = useApi();
|
||||
const counter = useCall<number>(isApiReady && hasAccounts && api.derive.council?.proposals, [], {
|
||||
transform
|
||||
}) || 0;
|
||||
const counter = useCall<number>(isApiReady && hasAccounts && api.derive.council?.proposals, undefined, transformCounter) || 0;
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@ import React from 'react';
|
||||
import { LinkExternal } from '@polkadot/react-components';
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
import { BlockToTime } from '@polkadot/react-query';
|
||||
import { BN_ZERO, formatNumber } from '@polkadot/util';
|
||||
import { formatNumber } from '@polkadot/util';
|
||||
|
||||
import ProposalCell from './ProposalCell';
|
||||
import PreImageButton from './PreImageButton';
|
||||
@ -20,7 +20,7 @@ interface Props {
|
||||
|
||||
function DispatchEntry ({ value: { at, image, imageHash, index } }: Props): React.ReactElement<Props> {
|
||||
const { api } = useApi();
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []) || BN_ZERO;
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber);
|
||||
|
||||
return (
|
||||
<tr>
|
||||
|
||||
@ -18,7 +18,7 @@ interface Props {
|
||||
function DispatchQueue ({ className }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const queued = useCall<DeriveDispatch[]>(api.derive.democracy.dispatchQueue, []);
|
||||
const queued = useCall<DeriveDispatch[]>(api.derive.democracy.dispatchQueue);
|
||||
|
||||
const headerRef = useRef([
|
||||
[t('dispatch queue'), 'start', 2],
|
||||
|
||||
@ -18,7 +18,7 @@ interface Props {
|
||||
function Externals ({ className }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const external = useCall<DeriveProposalExternal | null>(api.derive.democracy.nextExternal, []);
|
||||
const external = useCall<DeriveProposalExternal | null>(api.derive.democracy.nextExternal);
|
||||
|
||||
const headerRef = useRef([
|
||||
[t('external'), 'start'],
|
||||
|
||||
@ -18,7 +18,7 @@ interface Props {
|
||||
function Proposals ({ className }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const proposals = useCall<DeriveProposal[]>(api.derive.democracy.proposals, []);
|
||||
const proposals = useCall<DeriveProposal[]>(api.derive.democracy.proposals);
|
||||
|
||||
const headerRef = useRef([
|
||||
[t('proposals'), 'start', 2],
|
||||
|
||||
@ -40,8 +40,8 @@ function Referendum ({ className = '', value: { allAye, allNay, image, imageHash
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const { allAccounts } = useAccounts();
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);
|
||||
const totalIssuance = useCall<Balance>(api.query.balances.totalIssuance, []);
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber);
|
||||
const totalIssuance = useCall<Balance>(api.query.balances.totalIssuance);
|
||||
const [percentages, setPercentages] = useState<Percentages | null>(null);
|
||||
const [{ hasVoted, hasVotedAye }, setHasVoted] = useState<VoteType>({ hasVoted: false, hasVotedAye: false });
|
||||
const { changeAye, changeNay } = useChangeCalc(status.threshold, votedAye, votedNay, votedTotal);
|
||||
|
||||
@ -18,7 +18,8 @@ interface Props {
|
||||
|
||||
function Scheduled ({ className = '', value: { blockNumber, call, maybePeriodic } }: Props): React.ReactElement<Props> {
|
||||
const { api } = useApi();
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber);
|
||||
|
||||
const period = maybePeriodic.unwrapOr(null);
|
||||
|
||||
return (
|
||||
|
||||
@ -17,29 +17,29 @@ interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function transformEntries (entries: [{ args: [BlockNumber] }, Option<Scheduled>[]][]): ScheduledExt[] {
|
||||
return entries
|
||||
.filter(([, vecSchedOpt]) => vecSchedOpt.some((schedOpt) => schedOpt.isSome))
|
||||
.reduce((items: ScheduledExt[], [key, vecSchedOpt]): ScheduledExt[] => {
|
||||
const blockNumber = key.args[0];
|
||||
const transformEntries = {
|
||||
transform: (entries: [{ args: [BlockNumber] }, Option<Scheduled>[]][]): ScheduledExt[] => {
|
||||
return entries
|
||||
.filter(([, vecSchedOpt]) => vecSchedOpt.some((schedOpt) => schedOpt.isSome))
|
||||
.reduce((items: ScheduledExt[], [key, vecSchedOpt]): ScheduledExt[] => {
|
||||
const blockNumber = key.args[0];
|
||||
|
||||
return vecSchedOpt
|
||||
.filter((schedOpt) => schedOpt.isSome)
|
||||
.map((schedOpt) => schedOpt.unwrap())
|
||||
.reduce((items: ScheduledExt[], { call, maybeId, maybePeriodic, priority }, index) => {
|
||||
items.push({ blockNumber, call, key: `${blockNumber.toString()}-${index}`, maybeId, maybePeriodic, priority });
|
||||
return vecSchedOpt
|
||||
.filter((schedOpt) => schedOpt.isSome)
|
||||
.map((schedOpt) => schedOpt.unwrap())
|
||||
.reduce((items: ScheduledExt[], { call, maybeId, maybePeriodic, priority }, index) => {
|
||||
items.push({ blockNumber, call, key: `${blockNumber.toString()}-${index}`, maybeId, maybePeriodic, priority });
|
||||
|
||||
return items;
|
||||
}, items);
|
||||
}, []);
|
||||
}
|
||||
return items;
|
||||
}, items);
|
||||
}, []);
|
||||
}
|
||||
};
|
||||
|
||||
function Schedule ({ className = '' }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const items = useCall<ScheduledExt[]>(api.query.scheduler.agenda.entries as any, [], {
|
||||
transform: transformEntries
|
||||
});
|
||||
const items = useCall<ScheduledExt[]>(api.query.scheduler.agenda.entries as any, undefined, transformEntries);
|
||||
|
||||
const headerRef = useRef([
|
||||
[t('scheduled'), 'start'],
|
||||
|
||||
@ -17,10 +17,10 @@ interface Props {
|
||||
function Summary ({ referendumCount }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const activeProposals = useCall<any[]>(api.derive.democracy.proposals, []);
|
||||
const bestNumber = useCall<BN>(api.derive.chain.bestNumber, []);
|
||||
const publicPropCount = useCall<BN>(api.query.democracy.publicPropCount, []);
|
||||
const referendumTotal = useCall<BN>(api.query.democracy.referendumCount, []);
|
||||
const activeProposals = useCall<unknown[]>(api.derive.democracy.proposals);
|
||||
const bestNumber = useCall<BN>(api.derive.chain.bestNumber);
|
||||
const publicPropCount = useCall<BN>(api.query.democracy.publicPropCount);
|
||||
const referendumTotal = useCall<BN>(api.query.democracy.referendumCount);
|
||||
|
||||
return (
|
||||
<SummaryBox>
|
||||
|
||||
@ -30,12 +30,14 @@ interface ParamState {
|
||||
values: Value[];
|
||||
}
|
||||
|
||||
const transformProposal = {
|
||||
transform: (optProp: Option<TreasuryProposal>) => optProp.unwrapOr(null)
|
||||
};
|
||||
|
||||
function TreasuryCell ({ className = '', value }: Props): React.ReactElement<Props> | null {
|
||||
const { api } = useApi();
|
||||
const [proposalId] = useState(value.unwrap());
|
||||
const proposal = useCall<TreasuryProposal | null>(api.query.treasury.proposals, [proposalId], {
|
||||
transform: (optProp: Option<TreasuryProposal>) => optProp.unwrapOr(null)
|
||||
});
|
||||
const proposal = useCall<TreasuryProposal | null>(api.query.treasury.proposals, [proposalId], transformProposal);
|
||||
const [{ params, values }, setExtracted] = useState<ParamState>({ params: [], values: [] });
|
||||
|
||||
useEffect((): void => {
|
||||
|
||||
@ -28,7 +28,7 @@ function Overview ({ className }: Props): React.ReactElement<Props> {
|
||||
const { api } = useApi();
|
||||
const [isPreimageOpen, togglePreimage] = useToggle();
|
||||
const [isProposeOpen, togglePropose] = useToggle();
|
||||
const referendums = useCall<DeriveReferendumExt[]>(api.derive.democracy.referendums, []);
|
||||
const referendums = useCall<DeriveReferendumExt[]>(api.derive.democracy.referendums);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
|
||||
@ -18,7 +18,7 @@ interface Result {
|
||||
|
||||
export default function useChangeCalc (threshold: VoteThreshold, votedAye: BN, votedNay: BN, votedTotal: BN): Result {
|
||||
const { api } = useApi();
|
||||
const sqrtElectorate = useCall<BN>(api.derive.democracy.sqrtElectorate, []);
|
||||
const sqrtElectorate = useCall<BN>(api.derive.democracy.sqrtElectorate);
|
||||
const [result, setResult] = useState<Result>({ changeAye: BN_ZERO, changeNay: BN_ZERO });
|
||||
|
||||
useEffect((): void => {
|
||||
|
||||
@ -9,8 +9,8 @@ export default function useCounter (): number {
|
||||
const { hasAccounts } = useAccounts();
|
||||
const { api, isApiReady } = useApi();
|
||||
const mountedRef = useIsMountedRef();
|
||||
const proposals = useCall<any[]>(isApiReady && hasAccounts && api.derive.democracy?.proposals, []);
|
||||
const referenda = useCall<any[]>(isApiReady && hasAccounts && api.derive.democracy?.referendumsActive, []);
|
||||
const proposals = useCall<unknown[]>(isApiReady && hasAccounts && api.derive.democracy?.proposals);
|
||||
const referenda = useCall<unknown[]>(isApiReady && hasAccounts && api.derive.democracy?.referendumsActive);
|
||||
const [counter, setCounter] = useState(0);
|
||||
|
||||
useEffect((): void => {
|
||||
|
||||
@ -14,7 +14,7 @@ interface Props {
|
||||
|
||||
function BestHash ({ className = '', label }: Props): React.ReactElement<Props> {
|
||||
const { api } = useApi();
|
||||
const newHead = useCall<Header>(api.rpc.chain.subscribeNewHeads, []);
|
||||
const newHead = useCall<Header>(api.rpc.chain.subscribeNewHeads);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
|
||||
@ -22,18 +22,20 @@ interface Props {
|
||||
value: string;
|
||||
}
|
||||
|
||||
const transformEvents = {
|
||||
isSingle: true,
|
||||
transform: (events: EventRecord[]): KeyedEvent[] =>
|
||||
events.map((record, index) => ({
|
||||
indexes: [index],
|
||||
key: `${Date.now()}-${index}-${record.hash.toHex()}`,
|
||||
record
|
||||
}))
|
||||
};
|
||||
|
||||
function BlockByHash ({ className = '', value }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const events = useCall<KeyedEvent[]>(api.query.system.events.at, [value], {
|
||||
isSingle: true,
|
||||
transform: (events: EventRecord[]): KeyedEvent[] =>
|
||||
events.map((record, index) => ({
|
||||
indexes: [index],
|
||||
key: `${Date.now()}-${index}-${record.hash.toHex()}`,
|
||||
record
|
||||
}))
|
||||
});
|
||||
const events = useCall<KeyedEvent[]>(api.query.system.events.at, [value], transformEvents);
|
||||
const getBlock = useCall<SignedBlock>(api.rpc.chain.getBlock, [value], { isSingle: true });
|
||||
const getHeader = useCall<HeaderExtended>(api.derive.chain.getHeader, [value]);
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@ import BlockByNumber from './ByNumber';
|
||||
|
||||
function Entry (): React.ReactElement | null {
|
||||
const { api } = useApi();
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber);
|
||||
const { value } = useParams<{ value: string }>();
|
||||
const [stateValue, setStateValue] = useState<string | undefined>(value);
|
||||
|
||||
|
||||
@ -20,8 +20,8 @@ interface Props {
|
||||
function SummarySession ({ withEra = true, withSession = true }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const sessionInfo = useCall<DeriveSessionProgress>(api.query.staking && api.derive.session?.progress, []);
|
||||
const forcing = useCall<Forcing>(api.query.staking?.forceEra, []);
|
||||
const sessionInfo = useCall<DeriveSessionProgress>(api.query.staking && api.derive.session?.progress);
|
||||
const forcing = useCall<Forcing>(api.query.staking?.forceEra);
|
||||
|
||||
const eraLabel = t<string>('era');
|
||||
const sessionLabel = sessionInfo?.isEpoch
|
||||
|
||||
@ -21,20 +21,22 @@ interface Props {
|
||||
parachain: DeriveParachain;
|
||||
}
|
||||
|
||||
const transformHead = {
|
||||
transform: (headData: Option<HeadData>): string | null => {
|
||||
if (headData.isSome) {
|
||||
const hex = headData.unwrap().toHex();
|
||||
|
||||
return `${hex.slice(0, 10)}…${hex.slice(-8)}`;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
function Parachain ({ className = '', parachain: { didUpdate, id, info, pendingSwapId, relayDispatchQueueSize = 0 } }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const headHex = useCall<string | null>(api.query.parachains.heads, [id], {
|
||||
transform: (headData: Option<HeadData>): string | null => {
|
||||
if (headData.isSome) {
|
||||
const hex = headData.unwrap().toHex();
|
||||
|
||||
return `${hex.slice(0, 10)}…${hex.slice(-8)}`;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
const headHex = useCall<string | null>(api.query.parachains.heads, [id], transformHead);
|
||||
const history = useHistory();
|
||||
|
||||
const _onClick = useCallback(
|
||||
|
||||
@ -30,9 +30,9 @@ const DIV = new BN(1_000_000);
|
||||
function PollApp ({ className }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const totals = useCall<ITuple<[Balance, Balance, Balance, Balance]>>(api.query.poll.totals, []);
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);
|
||||
const totalIssuance = useCall<Balance>(api.query.balances.totalIssuance, []);
|
||||
const totals = useCall<ITuple<[Balance, Balance, Balance, Balance]>>(api.query.poll.totals);
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber);
|
||||
const totalIssuance = useCall<Balance>(api.query.balances.totalIssuance);
|
||||
const [accountId, setAccountId] = useState<string | null>(null);
|
||||
const [turnout, setTurnout] = useState<Turnout | null>(null);
|
||||
const [opt10m, setOpt10m] = useState(false);
|
||||
|
||||
@ -18,7 +18,7 @@ interface Props {
|
||||
function Bids ({ className }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const bids = useCall<Bid[]>(api.query.society.bids, []);
|
||||
const bids = useCall<Bid[]>(api.query.society.bids);
|
||||
|
||||
const headerRef = useRef([
|
||||
[t('bids'), 'start'],
|
||||
|
||||
@ -21,7 +21,7 @@ interface Props {
|
||||
function Candidates ({ allMembers, className = '', isMember, ownMembers }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const candidates = useCall<DeriveSocietyCandidate[]>(api.derive.society.candidates, []);
|
||||
const candidates = useCall<DeriveSocietyCandidate[]>(api.derive.society.candidates);
|
||||
|
||||
const headerRef = useRef([
|
||||
[t('candidates'), 'start'],
|
||||
|
||||
@ -21,18 +21,18 @@ interface Props {
|
||||
ownMembers: string[];
|
||||
}
|
||||
|
||||
function transformVotes (members: DeriveSocietyMember[]): VoteType[] {
|
||||
return members
|
||||
.filter(({ vote }): boolean => !!vote)
|
||||
.map(({ accountId, vote }): VoteType => [accountId.toString(), vote as SocietyVote]);
|
||||
}
|
||||
const transformVotes = {
|
||||
transform: (members: DeriveSocietyMember[]): VoteType[] => {
|
||||
return members
|
||||
.filter(({ vote }): boolean => !!vote)
|
||||
.map(({ accountId, vote }): VoteType => [accountId.toString(), vote as SocietyVote]);
|
||||
}
|
||||
};
|
||||
|
||||
function Defender ({ className = '', info, isMember, ownMembers }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const votes = useCall<VoteType[]>(api.derive.society.members, [], {
|
||||
transform: transformVotes
|
||||
});
|
||||
const votes = useCall<VoteType[]>(api.derive.society.members, undefined, transformVotes);
|
||||
|
||||
const headerRef = useRef([
|
||||
[t('defender'), 'start'],
|
||||
|
||||
@ -19,7 +19,7 @@ interface Props {
|
||||
function Members ({ className = '', info }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const members = useCall<DeriveSocietyMember[]>(api.derive.society.members, []);
|
||||
const members = useCall<DeriveSocietyMember[]>(api.derive.society.members);
|
||||
|
||||
const headerRef = useRef([
|
||||
[t('members'), 'start', 3],
|
||||
|
||||
@ -21,8 +21,8 @@ interface Props {
|
||||
function Summary ({ className = '', info }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const members = useCall<any[]>(api.derive.society.members, []);
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);
|
||||
const members = useCall<unknown[]>(api.derive.society.members);
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber);
|
||||
|
||||
const pot = useMemo((): string | null => {
|
||||
return info && info.pot.gtn(0)
|
||||
|
||||
@ -26,7 +26,7 @@ interface Props {
|
||||
function Overview ({ className }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const info = useCall<DeriveSociety>(api.derive.society.info, []);
|
||||
const info = useCall<DeriveSociety>(api.derive.society.info);
|
||||
const { allMembers, isMember, ownMembers } = useMembers();
|
||||
const [isBidOpen, toggleBidOpen] = useToggle();
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
export default function useCounter (): number {
|
||||
const { api } = useApi();
|
||||
const bids = useCall<Bid[]>(api.query.society?.bids, []);
|
||||
const bids = useCall<Bid[]>(api.query.society?.bids);
|
||||
|
||||
return bids?.length || 0;
|
||||
}
|
||||
|
||||
@ -22,7 +22,7 @@ export default function useMembers (): OwnMembers {
|
||||
const { api } = useApi();
|
||||
const { allAccounts } = useAccounts();
|
||||
const [state, setState] = useState<OwnMembers>({ allMembers: [], isMember: false, ownMembers: [] });
|
||||
const members = useCall<DeriveSocietyMember[]>(api.derive.society?.members, []);
|
||||
const members = useCall<DeriveSocietyMember[]>(api.derive.society?.members);
|
||||
|
||||
useEffect((): void => {
|
||||
allAccounts && members && setState(
|
||||
|
||||
@ -23,21 +23,25 @@ interface ErrorState {
|
||||
isFatal: boolean;
|
||||
}
|
||||
|
||||
const transformBonded = {
|
||||
transform: (value: Option<AccountId>): string | null =>
|
||||
value.isSome
|
||||
? value.unwrap().toString()
|
||||
: null
|
||||
};
|
||||
|
||||
const transformStash = {
|
||||
transform: (value: Option<StakingLedger>): string | null =>
|
||||
value.isSome
|
||||
? value.unwrap().stash.toString()
|
||||
: null
|
||||
};
|
||||
|
||||
function ValidateController ({ accountId, controllerId, defaultController, onError }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const bondedId = useCall<string | null>(controllerId ? api.query.staking.bonded : null, [controllerId], {
|
||||
transform: (value: Option<AccountId>): string | null =>
|
||||
value.isSome
|
||||
? value.unwrap().toString()
|
||||
: null
|
||||
});
|
||||
const stashId = useCall<string | null>(controllerId ? api.query.staking.ledger : null, [controllerId], {
|
||||
transform: (value: Option<StakingLedger>): string | null =>
|
||||
value.isSome
|
||||
? value.unwrap().stash.toString()
|
||||
: null
|
||||
});
|
||||
const bondedId = useCall<string | null>(controllerId ? api.query.staking.bonded : null, [controllerId], transformBonded);
|
||||
const stashId = useCall<string | null>(controllerId ? api.query.staking.ledger : null, [controllerId], transformStash);
|
||||
const allBalances = useCall<DeriveBalancesAll>(controllerId ? api.derive.balances.all : null, [controllerId]);
|
||||
const [{ error, isFatal }, setError] = useState<ErrorState>({ error: null, isFatal: false });
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ import { Slash } from '../types';
|
||||
import BN from 'bn.js';
|
||||
import React, { useCallback, useContext, useMemo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { ApiPromise } from '@polkadot/api';
|
||||
import { AddressInfo, AddressMini, AddressSmall, Badge, Button, Menu, Popup, StakingBonded, StakingRedeemable, StakingUnbonding, StatusContext, TxButton } from '@polkadot/react-components';
|
||||
import { useApi, useCall, useToggle } from '@polkadot/react-hooks';
|
||||
import { Option } from '@polkadot/types';
|
||||
@ -49,18 +50,26 @@ function extractSlashes (stashId: string, allSlashes: [BN, UnappliedSlash[]][] =
|
||||
.filter(({ slashes }) => slashes.length);
|
||||
}
|
||||
|
||||
const transformSpan = {
|
||||
transform: (optSpans: Option<SlashingSpans>): number =>
|
||||
optSpans.isNone
|
||||
? 0
|
||||
: optSpans.unwrap().prior.length + 1
|
||||
};
|
||||
|
||||
function useStashCalls (api: ApiPromise, stashId: string) {
|
||||
const params = useMemo(() => [stashId], [stashId]);
|
||||
const balancesAll = useCall<DeriveBalancesAll>(api.derive.balances.all, params);
|
||||
const spanCount = useCall<number>(api.query.staking.slashingSpans, params, transformSpan);
|
||||
const stakingAccount = useCall<DeriveStakingAccount>(api.derive.staking.account, params);
|
||||
|
||||
return { balancesAll, spanCount, stakingAccount };
|
||||
}
|
||||
|
||||
function Account ({ allSlashes, className = '', info: { controllerId, destination, destinationId, hexSessionIdNext, hexSessionIdQueue, isLoading, isOwnController, isOwnStash, isStashNominating, isStashValidating, nominating, sessionIds, stakingLedger, stashId }, isDisabled, targets }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const { queueExtrinsic } = useContext(StatusContext);
|
||||
const balancesAll = useCall<DeriveBalancesAll>(api.derive.balances.all, [stashId]);
|
||||
const stakingAccount = useCall<DeriveStakingAccount>(api.derive.staking.account, [stashId]);
|
||||
const spanCount = useCall<number>(api.query.staking.slashingSpans, [stashId], {
|
||||
transform: (optSpans: Option<SlashingSpans>): number =>
|
||||
optSpans.isNone
|
||||
? 0
|
||||
: optSpans.unwrap().prior.length + 1
|
||||
});
|
||||
const [isBondExtraOpen, toggleBondExtra] = useToggle();
|
||||
const [isInjectOpen, toggleInject] = useToggle();
|
||||
const [isNominateOpen, toggleNominate] = useToggle();
|
||||
@ -70,6 +79,7 @@ function Account ({ allSlashes, className = '', info: { controllerId, destinatio
|
||||
const [isSettingsOpen, toggleSettings] = useToggle();
|
||||
const [isUnbondOpen, toggleUnbond] = useToggle();
|
||||
const [isValidateOpen, toggleValidate] = useToggle();
|
||||
const { balancesAll, spanCount, stakingAccount } = useStashCalls(api, stashId);
|
||||
|
||||
const slashes = useMemo(
|
||||
() => extractSlashes(stashId, allSlashes),
|
||||
|
||||
@ -65,7 +65,7 @@ export default function useInactives (stashId: string, nominees?: string[]): Ina
|
||||
const { api } = useApi();
|
||||
const mountedRef = useIsMountedRef();
|
||||
const [state, setState] = useState<Inactives>({});
|
||||
const indexes = useCall<DeriveSessionIndexes>(api.derive.session.indexes, []);
|
||||
const indexes = useCall<DeriveSessionIndexes>(api.derive.session.indexes);
|
||||
|
||||
useEffect((): () => void => {
|
||||
let unsub: (() => void) | undefined;
|
||||
|
||||
@ -11,7 +11,7 @@ import { BN_ONE } from '@polkadot/util';
|
||||
|
||||
export default function useUnbondDuration (): BN | undefined {
|
||||
const { api } = useApi();
|
||||
const sessionInfo = useCall<DeriveSessionInfo>(api.derive.session.info, []);
|
||||
const sessionInfo = useCall<DeriveSessionInfo>(api.derive.session.info);
|
||||
|
||||
return useMemo(
|
||||
() => (sessionInfo && sessionInfo.sessionLength.gt(BN_ONE))
|
||||
|
||||
@ -7,6 +7,7 @@ import { DeriveAccountInfo, DeriveStakingQuery } from '@polkadot/api-derive/type
|
||||
|
||||
import BN from 'bn.js';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import { ApiPromise } from '@polkadot/api';
|
||||
import { AddressSmall, Icon, LinkExternal } from '@polkadot/react-components';
|
||||
import { checkVisibility } from '@polkadot/react-components/util';
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
@ -71,13 +72,22 @@ function expandInfo ({ exposure, validatorPrefs }: DeriveStakingQuery): StakingS
|
||||
};
|
||||
}
|
||||
|
||||
const transformSlashes = {
|
||||
transform: (opt: Option<SlashingSpans>) => opt.unwrapOr(null)
|
||||
};
|
||||
|
||||
function useAddressCalls (api: ApiPromise, address: string, isMain?: boolean) {
|
||||
const params = useMemo(() => [address], [address]);
|
||||
const accountInfo = useCall<DeriveAccountInfo>(api.derive.accounts.info, params);
|
||||
const slashingSpans = useCall<SlashingSpans | null>(!isMain && api.query.staking.slashingSpans, params, transformSlashes);
|
||||
const stakingInfo = useCall<DeriveStakingQuery>(api.derive.staking.query, params);
|
||||
|
||||
return { accountInfo, slashingSpans, stakingInfo };
|
||||
}
|
||||
|
||||
function Address ({ address, className = '', filterName, hasQueries, isElected, isFavorite, isMain, lastBlock, nominatedBy, onlineCount, onlineMessage, points, toggleFavorite, withIdentity }: Props): React.ReactElement<Props> | null {
|
||||
const { api } = useApi();
|
||||
const accountInfo = useCall<DeriveAccountInfo>(api.derive.accounts.info, [address]);
|
||||
const stakingInfo = useCall<DeriveStakingQuery>(api.derive.staking.query, [address]);
|
||||
const slashingSpans = useCall<SlashingSpans | null>(!isMain && api.query.staking.slashingSpans, [address], {
|
||||
transform: (opt: Option<SlashingSpans>) => opt.unwrapOr(null)
|
||||
});
|
||||
const { accountInfo, slashingSpans, stakingInfo } = useAddressCalls(api, address, isMain);
|
||||
|
||||
const { commission, nominators, stakeOther, stakeOwn } = useMemo(
|
||||
() => stakingInfo ? expandInfo(stakingInfo) : { nominators: [] },
|
||||
|
||||
@ -95,8 +95,8 @@ function CurrentList ({ favorites, hasQueries, isIntentions, next, stakingOvervi
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const { byAuthor, eraPoints } = useContext(isIntentions ? EmptyAuthorsContext : BlockAuthorsContext);
|
||||
const recentlyOnline = useCall<DeriveHeartbeats>(!isIntentions && api.derive.imOnline?.receivedHeartbeats, []);
|
||||
const nominators = useCall<[StorageKey, Option<Nominations>][]>(isIntentions && api.query.staking.nominators.entries as any, []);
|
||||
const recentlyOnline = useCall<DeriveHeartbeats>(!isIntentions && api.derive.imOnline?.receivedHeartbeats);
|
||||
const nominators = useCall<[StorageKey, Option<Nominations>][]>(isIntentions && api.query.staking.nominators.entries as any);
|
||||
const [nameFilter, setNameFilter] = useState<string>('');
|
||||
const [withIdentity, setWithIdentity] = useState(false);
|
||||
|
||||
|
||||
@ -157,8 +157,8 @@ function Payouts ({ className = '', isInElection, ownValidators }: Props): React
|
||||
const [hasOwnValidators] = useState(ownValidators.length !== 0);
|
||||
const [myStashesIndex, setMyStashesIndex] = useState((api.tx.staking.payoutStakers && hasOwnValidators) ? 0 : 1);
|
||||
const [eraSelectionIndex, setEraSelectionIndex] = useState(0);
|
||||
const eraLength = useCall<BN>(api.derive.session.eraLength, []);
|
||||
const historyDepth = useCall<BN>(api.query.staking.historyDepth, []);
|
||||
const eraLength = useCall<BN>(api.derive.session.eraLength);
|
||||
const historyDepth = useCall<BN>(api.query.staking.historyDepth);
|
||||
const stakerPayoutsAfter = useStakerPayouts();
|
||||
const isDisabled = isInElection || !isFunction(api.tx.utility?.batch);
|
||||
|
||||
|
||||
@ -12,9 +12,9 @@ import { BN_ONE } from '@polkadot/util';
|
||||
|
||||
export default function useEraBlocks (era?: BN): BN | undefined {
|
||||
const { api } = useApi();
|
||||
const depth = useCall<BN>(api.query.staking.historyDepth, []);
|
||||
const progress = useCall<DeriveSessionProgress>(api.derive.session.progress, []);
|
||||
const forcing = useCall<Forcing>(api.query.staking.forceEra, []);
|
||||
const depth = useCall<BN>(api.query.staking.historyDepth);
|
||||
const progress = useCall<DeriveSessionProgress>(api.derive.session.progress);
|
||||
const forcing = useCall<Forcing>(api.query.staking.forceEra);
|
||||
|
||||
return useMemo(
|
||||
() => (depth && era && forcing && progress && progress.sessionLength.gt(BN_ONE))
|
||||
|
||||
@ -12,7 +12,7 @@ import { isFunction } from '@polkadot/util';
|
||||
|
||||
export default function useStakerPayouts (): BN {
|
||||
const { api } = useApi();
|
||||
const migrateEraOpt = useCall<Option<EraIndex>>(api.query.staking?.migrateEra, []);
|
||||
const migrateEraOpt = useCall<Option<EraIndex>>(api.query.staking?.migrateEra);
|
||||
|
||||
return useMemo(
|
||||
() => (migrateEraOpt && migrateEraOpt.isSome && migrateEraOpt.unwrap()) || (
|
||||
|
||||
@ -56,7 +56,7 @@ function ChartRewards ({ validatorId }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const ownSlashes = useCall<DeriveOwnSlashes[]>(api.derive.staking.ownSlashes, [validatorId, true]);
|
||||
const erasRewards = useCall<DeriveEraRewards[]>(api.derive.staking.erasRewards, []);
|
||||
const erasRewards = useCall<DeriveEraRewards[]>(api.derive.staking.erasRewards);
|
||||
const stakerPoints = useCall<DeriveStakerPoints[]>(api.derive.staking.stakerPoints, [validatorId, true]);
|
||||
|
||||
const { currency, divisor } = useMemo((): { currency: string; divisor: BN } => ({
|
||||
|
||||
@ -13,7 +13,7 @@ import { isFunction } from '@polkadot/util';
|
||||
export default function useBlockCounts (accountId: string, sessionRewards: SessionRewards[]): u32[] {
|
||||
const { api } = useApi();
|
||||
const mountedRef = useIsMountedRef();
|
||||
const indexes = useCall<DeriveSessionIndexes>(api.derive.session?.indexes, []);
|
||||
const indexes = useCall<DeriveSessionIndexes>(api.derive.session?.indexes);
|
||||
const current = useCall<u32>(api.query.imOnline?.authoredBlocks, [indexes?.currentIndex, accountId]);
|
||||
const [counts, setCounts] = useState<u32[]>([]);
|
||||
const [historic, setHistoric] = useState<u32[]>([]);
|
||||
|
||||
@ -21,7 +21,7 @@ interface Props {
|
||||
function Header ({ slash: { era, nominators, reporters, total, validators } }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const sessionInfo = useCall<DeriveSessionProgress>(api.derive.session?.progress, []);
|
||||
const sessionInfo = useCall<DeriveSessionProgress>(api.derive.session?.progress);
|
||||
|
||||
const [blockProgress, blockEnd] = useMemo(
|
||||
() => sessionInfo
|
||||
|
||||
@ -24,7 +24,7 @@ interface Props {
|
||||
function Summary ({ avgStaked, lastReward, lowStaked, numNominators, numValidators, totalStaked }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const totalIssuance = useCall<Balance>(api.query.balances?.totalIssuance, []);
|
||||
const totalIssuance = useCall<Balance>(api.query.balances?.totalIssuance);
|
||||
|
||||
const progressStake = useMemo(
|
||||
() => totalIssuance && totalStaked && totalStaked.gtn(0)
|
||||
|
||||
@ -30,6 +30,10 @@ import useSortedTargets from './useSortedTargets';
|
||||
const HIDDEN_ACC = ['actions', 'payouts', 'query'];
|
||||
const HIDDEN_QUE = ['returns', 'query'];
|
||||
|
||||
const transformElection = {
|
||||
transform: (status: ElectionStatus) => status.isOpen
|
||||
};
|
||||
|
||||
function StakingApp ({ basePath, className = '' }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
@ -40,10 +44,8 @@ function StakingApp ({ basePath, className = '' }: Props): React.ReactElement<Pr
|
||||
const ownStashes = useOwnStashInfos();
|
||||
const slashes = useAvailableSlashes();
|
||||
const targets = useSortedTargets(favorites);
|
||||
const stakingOverview = useCall<DeriveStakingOverview>(api.derive.staking.overview, []);
|
||||
const isInElection = useCall<boolean>(api.query.staking?.eraElectionStatus, [], {
|
||||
transform: (status: ElectionStatus) => status.isOpen
|
||||
});
|
||||
const stakingOverview = useCall<DeriveStakingOverview>(api.derive.staking.overview);
|
||||
const isInElection = useCall<boolean>(api.query.staking?.eraElectionStatus, undefined, transformElection);
|
||||
|
||||
const hasQueries = useMemo(
|
||||
() => hasAccounts && !!(api.query.imOnline?.authoredBlocks) && !!(api.query.staking.activeEra),
|
||||
|
||||
@ -149,17 +149,21 @@ function extractInfo (allAccounts: string[], amount: BN = baseBalance(), elected
|
||||
return { avgStaked: totalStaked.divn(electedDerive.info.length), lowStaked, nominators, totalStaked, validatorIds, validators };
|
||||
}
|
||||
|
||||
const transformEra = {
|
||||
transform: ({ activeEra }: DeriveSessionIndexes) => activeEra.gtn(0) ? activeEra.subn(1) : BN_ZERO
|
||||
};
|
||||
|
||||
const transformReward = {
|
||||
transform: (optBalance: Option<Balance>) => optBalance.unwrapOrDefault()
|
||||
};
|
||||
|
||||
export default function useSortedTargets (favorites: string[]): SortedTargets {
|
||||
const { api } = useApi();
|
||||
const { allAccounts } = useAccounts();
|
||||
const electedInfo = useCall<DeriveStakingElected>(api.derive.staking.electedInfo, []);
|
||||
const waitingInfo = useCall<DeriveStakingWaiting>(api.derive.staking.waitingInfo, []);
|
||||
const lastEra = useCall<BN>(api.derive.session.indexes, [], {
|
||||
transform: ({ activeEra }: DeriveSessionIndexes) => activeEra.gtn(0) ? activeEra.subn(1) : BN_ZERO
|
||||
});
|
||||
const lastReward = useCall<BN>(lastEra && api.query.staking.erasValidatorReward, [lastEra], {
|
||||
transform: (optBalance: Option<Balance>) => optBalance.unwrapOrDefault()
|
||||
});
|
||||
const electedInfo = useCall<DeriveStakingElected>(api.derive.staking.electedInfo);
|
||||
const waitingInfo = useCall<DeriveStakingWaiting>(api.derive.staking.waitingInfo);
|
||||
const lastEra = useCall<BN>(api.derive.session.indexes, undefined, transformEra);
|
||||
const lastReward = useCall<BN>(lastEra && api.query.staking.erasValidatorReward, [lastEra], transformReward);
|
||||
const [calcWith, setCalcWith] = useState<BN | undefined>(baseBalance());
|
||||
const calcWithDebounce = useDebounce(calcWith);
|
||||
const [state, setState] = useState<SortedTargets>({ setCalcWith });
|
||||
|
||||
@ -15,7 +15,7 @@ import { useTranslation } from '../translate';
|
||||
function Summary ({ className = '', members, proposals }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const proposalCount = useCall<u32>(api.query.technicalCommittee.proposalCount, []);
|
||||
const proposalCount = useCall<u32>(api.query.technicalCommittee.proposalCount);
|
||||
|
||||
return (
|
||||
<SummaryBox className={className}>
|
||||
|
||||
@ -23,14 +23,18 @@ interface Props {
|
||||
prime?: AccountId | null;
|
||||
}
|
||||
|
||||
const transformProposal = {
|
||||
transform: (optProp: Option<ProposalType>) => optProp.unwrapOr(null)
|
||||
};
|
||||
|
||||
const transformVotes = {
|
||||
transform: (optVotes: Option<Votes>) => optVotes.unwrapOr(null)
|
||||
};
|
||||
|
||||
function Proposal ({ className = '', imageHash, isMember, members, prime }: Props): React.ReactElement<Props> | null {
|
||||
const { api } = useApi();
|
||||
const proposal = useCall<ProposalType | null>(api.query.technicalCommittee.proposalOf, [imageHash], {
|
||||
transform: (optProp: Option<ProposalType>) => optProp.unwrapOr(null)
|
||||
});
|
||||
const votes = useCall<Votes | null>(api.query.technicalCommittee.voting, [imageHash], {
|
||||
transform: (optVotes: Option<Votes>) => optVotes.unwrapOr(null)
|
||||
});
|
||||
const proposal = useCall<ProposalType | null>(api.query.technicalCommittee.proposalOf, [imageHash], transformProposal);
|
||||
const votes = useCall<Votes | null>(api.query.technicalCommittee.voting, [imageHash], transformVotes);
|
||||
const { hasFailed, isCloseable, isVoteable, remainingBlocks } = useVotingStatus(votes, members.length, 'technicalCommittee');
|
||||
|
||||
if (!proposal || !votes) {
|
||||
|
||||
@ -21,14 +21,17 @@ interface Props {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const transformPrime = {
|
||||
transform: (result: Option<AccountId>): AccountId | null => result.unwrapOr(null)
|
||||
};
|
||||
|
||||
function TechCommApp ({ basePath, className }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const { isMember, members } = useMembers('technicalCommittee');
|
||||
const prime = useCall<AccountId | null>(api.query.technicalCommittee.prime, [], {
|
||||
transform: (result: Option<AccountId>): AccountId | null => result.unwrapOr(null)
|
||||
}) || null;
|
||||
const prime = useCall<AccountId | null>(api.query.technicalCommittee.prime, undefined, transformPrime) || null;
|
||||
const proposals = useCall<Hash[]>(api.query.technicalCommittee.proposals);
|
||||
|
||||
const items = useMemo(() => [
|
||||
{
|
||||
isRoot: true,
|
||||
|
||||
@ -6,15 +6,13 @@ import { Hash } from '@polkadot/types/interfaces';
|
||||
|
||||
import { useApi, useCall } from '@polkadot/react-hooks';
|
||||
|
||||
function transform (proposals: Hash[]): number {
|
||||
return proposals.length;
|
||||
}
|
||||
const transformCounter = {
|
||||
transform: (proposals: Hash[]) => proposals.length
|
||||
};
|
||||
|
||||
export default function useCounter (): number {
|
||||
const { api, isApiReady } = useApi();
|
||||
const counter = useCall<number>(isApiReady && api.query.technicalCommittee?.proposals, [], {
|
||||
transform
|
||||
}) || 0;
|
||||
const counter = useCall<number>(isApiReady && api.query.technicalCommittee?.proposals, undefined, transformCounter) || 0;
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
@ -24,8 +24,8 @@ interface Props {
|
||||
function Summary ({ approvalCount, proposalCount }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const bestNumber = useCall<Balance>(api.derive.chain.bestNumber, []);
|
||||
const totalProposals = useCall<BN>(api.query.treasury.proposalCount, []);
|
||||
const bestNumber = useCall<Balance>(api.derive.chain.bestNumber);
|
||||
const totalProposals = useCall<BN>(api.query.treasury.proposalCount);
|
||||
const treasuryBalance = useCall<DeriveBalancesAccount>(api.derive.balances.account, [TREASURY_ACCOUNT]);
|
||||
const spendPeriod = api.consts.treasury.spendPeriod;
|
||||
|
||||
|
||||
@ -13,14 +13,16 @@ interface Props {
|
||||
hash: Hash;
|
||||
}
|
||||
|
||||
const transformTip = {
|
||||
transform: (optBytes: Option<Bytes>) =>
|
||||
optBytes.isSome
|
||||
? hexToString(optBytes.unwrap().toHex())
|
||||
: null
|
||||
};
|
||||
|
||||
function TipReason ({ hash }: Props): React.ReactElement<Props> {
|
||||
const { api } = useApi();
|
||||
const reasonText = useCall<string | null>(api.query.treasury.reasons, [hash], {
|
||||
transform: (optBytes: Option<Bytes>) =>
|
||||
optBytes.isSome
|
||||
? hexToString(optBytes.unwrap().toHex())
|
||||
: null
|
||||
});
|
||||
const reasonText = useCall<string | null>(api.query.treasury.reasons, [hash], transformTip);
|
||||
|
||||
return (
|
||||
<td className='start all'>{reasonText || hash.toHex()}</td>
|
||||
|
||||
@ -24,7 +24,7 @@ type Tip = [string, OpenTip | OpenTipTo225];
|
||||
function Tips ({ className = '', hashes, isMember, members }: Props): React.ReactElement<Props> {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber);
|
||||
const [tips, setTips] = useState<Tip[] | undefined>();
|
||||
const optTips = useCall<Option<OpenTip>[]>(hashes && api.query.treasury.tips.multi, [hashes]);
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ function Voting ({ councilProposals, isDisabled, members }: Props): React.ReactE
|
||||
const { t } = useTranslation();
|
||||
const { hasAccounts } = useAccounts();
|
||||
const { api } = useApi();
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber);
|
||||
const [councilOpts, setCouncilOpts] = useState<Option[]>([]);
|
||||
const [councilOptId, setCouncilOptId] = useState<number>(0);
|
||||
const [accountId, setAccountId] = useState<string | null>(null);
|
||||
|
||||
@ -17,7 +17,7 @@ import Tips from './Tips';
|
||||
|
||||
function Overview ({ className }: Props): React.ReactElement<Props> {
|
||||
const { api } = useApi();
|
||||
const info = useCall<DeriveTreasuryProposals>(api.derive.treasury.proposals, []);
|
||||
const info = useCall<DeriveTreasuryProposals>(api.derive.treasury.proposals);
|
||||
const { isMember, members } = useMembers();
|
||||
|
||||
const mountedRef = useIsMountedRef();
|
||||
|
||||
@ -10,7 +10,7 @@ import { useAccounts, useApi, useCall } from '@polkadot/react-hooks';
|
||||
export default function useCounter (): number {
|
||||
const { hasAccounts } = useAccounts();
|
||||
const { api, isApiReady } = useApi();
|
||||
const proposals = useCall<DeriveTreasuryProposals>(isApiReady && hasAccounts && api.derive.treasury?.proposals, []);
|
||||
const proposals = useCall<DeriveTreasuryProposals>(isApiReady && hasAccounts && api.derive.treasury?.proposals);
|
||||
const [counter, setCounter] = useState(0);
|
||||
|
||||
useEffect((): void => {
|
||||
|
||||
@ -85,7 +85,7 @@ function groupLocks (t: TFunction, bestNumber: BN, locks: DeriveDemocracyLock[]
|
||||
function DemocracyLocks ({ className = '', value }: Props): React.ReactElement<Props> | null {
|
||||
const { t } = useTranslation();
|
||||
const { api } = useApi();
|
||||
const bestNumber = useCall<BN>(api.derive.chain.bestNumber, []);
|
||||
const bestNumber = useCall<BN>(api.derive.chain.bestNumber);
|
||||
const [trigger] = useState(`${Date.now()}-democracy-locks-${++id}`);
|
||||
const [{ maxBalance, sorted }, setState] = useState<State>({ maxBalance: BN_ZERO, sorted: [] });
|
||||
|
||||
|
||||
@ -18,16 +18,18 @@ interface Props {
|
||||
stakingInfo?: DeriveStakingAccount;
|
||||
}
|
||||
|
||||
const transformSpan = {
|
||||
transform: (optSpans: Option<SlashingSpans>): number =>
|
||||
optSpans.isNone
|
||||
? 0
|
||||
: optSpans.unwrap().prior.length + 1
|
||||
};
|
||||
|
||||
function StakingRedeemable ({ className = '', stakingInfo }: Props): React.ReactElement<Props> | null {
|
||||
const { api } = useApi();
|
||||
const { allAccounts } = useAccounts();
|
||||
const { t } = useTranslation();
|
||||
const spanCount = useCall<number>(api.query.staking.slashingSpans, [stakingInfo?.stashId], {
|
||||
transform: (optSpans: Option<SlashingSpans>): number =>
|
||||
optSpans.isNone
|
||||
? 0
|
||||
: optSpans.unwrap().prior.length + 1
|
||||
});
|
||||
const spanCount = useCall<number>(api.query.staking.slashingSpans, [stakingInfo?.stashId], transformSpan);
|
||||
|
||||
if (!stakingInfo?.redeemable?.gtn(0)) {
|
||||
return null;
|
||||
|
||||
@ -29,7 +29,7 @@ function remainingBlocks (remainingEras: BN, { eraLength, eraProgress }: DeriveS
|
||||
|
||||
function StakingUnbonding ({ className = '', stakingInfo }: Props): React.ReactElement<Props> | null {
|
||||
const { api } = useApi();
|
||||
const progress = useCall<DeriveSessionProgress>(api.derive.session.progress, []);
|
||||
const progress = useCall<DeriveSessionProgress>(api.derive.session.progress);
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (!stakingInfo?.unlocking || !progress) {
|
||||
|
||||
@ -14,8 +14,8 @@ type Unsub = () => void;
|
||||
|
||||
export default function useAvailableSlashes (): [BN, UnappliedSlash[]][] {
|
||||
const { api } = useApi();
|
||||
const indexes = useCall<DeriveSessionIndexes>(api.derive.session?.indexes, []);
|
||||
const earliestSlash = useCall<Option<EraIndex>>(api.query.staking?.earliestUnappliedSlash, []);
|
||||
const indexes = useCall<DeriveSessionIndexes>(api.derive.session?.indexes);
|
||||
const earliestSlash = useCall<Option<EraIndex>>(api.query.staking?.earliestUnappliedSlash);
|
||||
const mountedRef = useIsMountedRef();
|
||||
const [slashes, setSlashes] = useState<[BN, UnappliedSlash[]][]>([]);
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ function transformIdentity <T> (value: unknown): T {
|
||||
}
|
||||
|
||||
// extract the serialized and mapped params, all ready for use in our call
|
||||
function extractParams (fn: unknown, params: unknown[], paramMap: (params: unknown[]) => CallParams): [string, CallParams | null] {
|
||||
function extractParams <T> (fn: unknown, params: unknown[], { paramMap = transformIdentity }: CallOptions<T> = {}): [string, CallParams | null] {
|
||||
return [
|
||||
JSON.stringify({ f: (fn as { name: string })?.name, p: params }),
|
||||
params.length === 0 || !params.some((param) => isNull(param) || isUndefined(param))
|
||||
@ -58,7 +58,7 @@ function unsubscribe (tracker: TrackerRef): void {
|
||||
}
|
||||
|
||||
// subscribe, trying to play nice with the browser threads
|
||||
function subscribe <T> (mountedRef: MountedRef, tracker: TrackerRef, fn: TrackFn | undefined, params: CallParams, setValue: (value: T) => void, { isSingle, transform = transformIdentity, withParams }: CallOptions<T>): void {
|
||||
function subscribe <T> (mountedRef: MountedRef, tracker: TrackerRef, fn: TrackFn | undefined, params: CallParams, setValue: (value: T) => void, { isSingle, transform = transformIdentity, withParams }: CallOptions<T> = {}): void {
|
||||
const validParams = params.filter((p): boolean => !isUndefined(p));
|
||||
|
||||
unsubscribe(tracker);
|
||||
@ -94,10 +94,10 @@ function subscribe <T> (mountedRef: MountedRef, tracker: TrackerRef, fn: TrackFn
|
||||
// - returns a promise with an unsubscribe function
|
||||
// - has a callback to set the value
|
||||
// FIXME The typings here need some serious TLC
|
||||
export default function useCall <T> (fn: TrackFn | undefined | null | false, params: CallParams = [], options: CallOptions<T> = {}): T | undefined {
|
||||
export default function useCall <T> (fn: TrackFn | undefined | null | false, params?: CallParams, options?: CallOptions<T>): T | undefined {
|
||||
const mountedRef = useIsMountedRef();
|
||||
const tracker = useRef<Tracker>({ count: 0, isActive: false, serialized: null, subscriber: null });
|
||||
const [value, setValue] = useState<T | undefined>(options.defaultValue);
|
||||
const [value, setValue] = useState<T | undefined>((options || {}).defaultValue);
|
||||
|
||||
// initial effect, we need an un-subscription
|
||||
useEffect((): () => void => {
|
||||
@ -108,7 +108,7 @@ export default function useCall <T> (fn: TrackFn | undefined | null | false, par
|
||||
useEffect((): void => {
|
||||
// check if we have a function & that we are mounted
|
||||
if (mountedRef.current && fn) {
|
||||
const [serialized, mappedParams] = extractParams(fn, params, options.paramMap || transformIdentity);
|
||||
const [serialized, mappedParams] = extractParams(fn, params || [], options);
|
||||
|
||||
if (mappedParams && serialized !== tracker.current.serialized) {
|
||||
tracker.current.serialized = serialized;
|
||||
|
||||
@ -12,13 +12,15 @@ interface Result {
|
||||
members: string[];
|
||||
}
|
||||
|
||||
const transformMembers = {
|
||||
transform: (accounts: AccountId[]) =>
|
||||
accounts.map((accountId) => accountId.toString())
|
||||
};
|
||||
|
||||
export default function useMembers (collective: 'council' | 'technicalCommittee' = 'council'): Result {
|
||||
const { api } = useApi();
|
||||
const { allAccounts, hasAccounts } = useAccounts();
|
||||
const retrieved = useCall<string[]>(hasAccounts && api.query[collective]?.members, [], {
|
||||
transform: (accounts: AccountId[]) =>
|
||||
accounts.map((accountId) => accountId.toString())
|
||||
});
|
||||
const retrieved = useCall<string[]>(hasAccounts && api.query[collective]?.members, undefined, transformMembers);
|
||||
|
||||
return useMemo(
|
||||
() => ({
|
||||
|
||||
@ -92,7 +92,7 @@ export default function useOwnEraRewards (maxEras?: number, ownValidators?: Stak
|
||||
const { api } = useApi();
|
||||
const mountedRef = useIsMountedRef();
|
||||
const stashIds = useOwnStashIds();
|
||||
const allEras = useCall<EraIndex[]>(api.derive.staking?.erasHistoric, []);
|
||||
const allEras = useCall<EraIndex[]>(api.derive.staking?.erasHistoric);
|
||||
const [{ filteredEras, validatorEras }, setFiltered] = useState<Filtered>({ filteredEras: [], validatorEras: [] });
|
||||
const [state, setState] = useState<OwnRewards>({ isLoadingRewards: true, rewardCount: 0 });
|
||||
const stakerRewards = useCall<[[string[]], DeriveStakerReward[][]]>(!ownValidators?.length && !!filteredEras.length && stashIds && api.derive.staking?.stakerRewardsMultiEras, [stashIds, filteredEras], { withParams: true });
|
||||
|
||||
@ -30,7 +30,7 @@ interface State {
|
||||
export default function useRegistrars (skipQuery?: boolean): State {
|
||||
const { api } = useApi();
|
||||
const { allAccounts, hasAccounts } = useAccounts();
|
||||
const query = useCall<Option<RegistrarInfo>[]>(!skipQuery && hasAccounts && api.query.identity?.registrars, []);
|
||||
const query = useCall<Option<RegistrarInfo>[]>(!skipQuery && hasAccounts && api.query.identity?.registrars);
|
||||
const [state, setState] = useState<State>({ isRegistrar: false, registrars: [] });
|
||||
|
||||
// determine if we have a registrar or not - registrars are allowed to approve
|
||||
|
||||
@ -7,11 +7,13 @@ import { AccountId } from '@polkadot/types/interfaces';
|
||||
import useApi from './useApi';
|
||||
import useCall from './useCall';
|
||||
|
||||
const transformStashes = {
|
||||
transform: (stashes: AccountId[]) => stashes.map((accountId) => accountId.toString())
|
||||
};
|
||||
|
||||
export default function useStashIds (): string[] | undefined {
|
||||
const { api } = useApi();
|
||||
const allStashes = useCall<string[]>(api.derive.staking.stashes, [], {
|
||||
transform: (stashes: AccountId[]) => stashes.map((accountId) => accountId.toString())
|
||||
});
|
||||
const allStashes = useCall<string[]>(api.derive.staking.stashes, undefined, transformStashes);
|
||||
|
||||
return allStashes;
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { Codec } from '@polkadot/types/types';
|
||||
import { AccountId } from '@polkadot/types/interfaces';
|
||||
import { UseSudo } from './types';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
@ -11,12 +11,14 @@ import useAccounts from './useAccounts';
|
||||
import useApi from './useApi';
|
||||
import useCall from './useCall';
|
||||
|
||||
const transformSudo = {
|
||||
transform: (key: AccountId) => key.toString()
|
||||
};
|
||||
|
||||
export default function useSudo (): UseSudo {
|
||||
const { api } = useApi();
|
||||
const { allAccounts, hasAccounts } = useAccounts();
|
||||
const sudoKey = useCall<string>(hasAccounts && api.query.sudo?.key, [], {
|
||||
transform: (k: Codec) => k.toString()
|
||||
});
|
||||
const sudoKey = useCall<string>(hasAccounts && api.query.sudo?.key, undefined, transformSudo);
|
||||
const [isMine, setIsMine] = useState(false);
|
||||
|
||||
useEffect((): void => {
|
||||
|
||||
@ -49,7 +49,7 @@ function getStatus (api: ApiPromise, bestNumber: BlockNumber, votes: Votes, numM
|
||||
|
||||
export default function useVotingStatus (votes: Votes | null | undefined, numMembers: number, section: 'council' | 'technicalCommittee'): State {
|
||||
const { api } = useApi();
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber, []);
|
||||
const bestNumber = useCall<BlockNumber>(api.derive.chain.bestNumber);
|
||||
const [state, setState] = useState<State>({ hasFailed: false, hasPassed: false, isCloseable: false, isVoteable: false, remainingBlocks: null });
|
||||
|
||||
useEffect((): void => {
|
||||
|
||||
@ -16,7 +16,7 @@ interface Props {
|
||||
|
||||
function BestFinalized ({ children, className = '', label }: Props): React.ReactElement<Props> {
|
||||
const { api } = useApi();
|
||||
const bestNumberFinalized = useCall<BlockNumber>(api.derive.chain.bestNumberFinalized, []);
|
||||
const bestNumberFinalized = useCall<BlockNumber>(api.derive.chain.bestNumberFinalized);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
|
||||
@ -17,7 +17,7 @@ interface Props {
|
||||
|
||||
function BestNumber ({ children, className = '', label, withPound }: Props): React.ReactElement<Props> {
|
||||
const { api, isApiReady } = useApi();
|
||||
const bestNumber = useCall<BlockNumber>(isApiReady && api.derive.chain.bestNumber, []);
|
||||
const bestNumber = useCall<BlockNumber>(isApiReady && api.derive.chain.bestNumber);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
|
||||
@ -31,7 +31,7 @@ const ValidatorsContext: React.Context<string[]> = React.createContext<string[]>
|
||||
|
||||
function BlockAuthorsBase ({ children }: Props): React.ReactElement<Props> {
|
||||
const { api, isApiReady } = useApi();
|
||||
const queryPoints = useCall<EraRewardPoints>(isApiReady && api.derive.staking?.currentPoints, []);
|
||||
const queryPoints = useCall<EraRewardPoints>(isApiReady && api.derive.staking?.currentPoints);
|
||||
const [state, setState] = useState<Authors>({ byAuthor, eraPoints, lastBlockAuthors: [], lastHeaders: [] });
|
||||
const [validators, setValidators] = useState<string[]>([]);
|
||||
|
||||
|
||||
@ -17,14 +17,18 @@ interface Props {
|
||||
label?: React.ReactNode;
|
||||
}
|
||||
|
||||
const transformController = {
|
||||
transform: (value: Option<AccountId>) => value.unwrapOr(null)
|
||||
};
|
||||
|
||||
const transformLedger = {
|
||||
transform: (value: Option<StakingLedger>) => value.unwrapOr(null)
|
||||
};
|
||||
|
||||
function BondedDisplay ({ children, className = '', label, params }: Props): React.ReactElement<Props> {
|
||||
const { api } = useApi();
|
||||
const controllerId = useCall<AccountId | null>(api.query.staking?.bonded, [params], {
|
||||
transform: (value: Option<AccountId>) => value.unwrapOr(null)
|
||||
});
|
||||
const stakingLedger = useCall<StakingLedger | null>(controllerId && api.query.staking?.ledger, [controllerId], {
|
||||
transform: (value: Option<StakingLedger>) => value.unwrapOr(null)
|
||||
});
|
||||
const controllerId = useCall<AccountId | null>(api.query.staking?.bonded, [params], transformController);
|
||||
const stakingLedger = useCall<StakingLedger | null>(controllerId && api.query.staking?.ledger, [controllerId], transformLedger);
|
||||
|
||||
return (
|
||||
<FormatBalance
|
||||
|
||||
@ -18,7 +18,7 @@ interface Props {
|
||||
|
||||
function TimeNow ({ children, className = '', label }: Props): React.ReactElement<Props> {
|
||||
const { api, isSubstrateV2 } = useApi();
|
||||
const timestamp = useCall<Moment>(api.query.timestamp.now, []);
|
||||
const timestamp = useCall<Moment>(api.query.timestamp.now);
|
||||
const [now, setNow] = useState<BN | undefined>();
|
||||
|
||||
useEffect((): void => {
|
||||
|
||||
@ -14,7 +14,7 @@ interface Props {
|
||||
|
||||
function TotalIssuance ({ children, className = '', label }: Props): React.ReactElement<Props> {
|
||||
const { api } = useApi();
|
||||
const totalIssuance = useCall<string>(api.query.balances?.totalIssuance, []);
|
||||
const totalIssuance = useCall<string>(api.query.balances?.totalIssuance);
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user