// Copyright 2017-2026 @pezkuwi/app-staking authors & contributors // SPDX-License-Identifier: Apache-2.0 import type { u32 } from '@pezkuwi/types'; import type { NominatorValue } from './types.js'; import React, { useMemo } from 'react'; import { AddressMini, ExpanderScroll } from '@pezkuwi/react-components'; import { useApi } from '@pezkuwi/react-hooks'; import { FormatBalance } from '@pezkuwi/react-query'; import { BN, BN_ZERO } from '@pezkuwi/util'; interface Props { stakeOther?: BN; nominators?: NominatorValue[]; } function extractFunction (all: NominatorValue[]): null | [number, () => React.ReactNode[]] { return [ all.length, () => all.map(({ nominatorId, value }): React.ReactNode => ) ]; } function sumValue (all: { value: BN }[]): BN { const total = new BN(0); for (let i = 0, count = all.length; i < count; i++) { total.iadd(all[i].value); } return total; } function extractTotals (maxPaid: BN | undefined, nominators?: NominatorValue[], stakeOther?: BN): [null | [number, () => React.ReactNode[]], BN, null | [number, () => React.ReactNode[]], BN] { if (!nominators) { return [null, BN_ZERO, null, BN_ZERO]; } const sorted = nominators.sort((a, b) => b.value.cmp(a.value)); if (!maxPaid || maxPaid.gtn(sorted.length)) { return [extractFunction(sorted), stakeOther || BN_ZERO, null, BN_ZERO]; } const max = maxPaid.toNumber(); const rewarded = sorted.slice(0, max); const rewardedTotal = sumValue(rewarded); const unrewarded = sorted.slice(max); const unrewardedTotal = sumValue(unrewarded); return [extractFunction(rewarded), rewardedTotal, extractFunction(unrewarded), unrewardedTotal]; } function StakeOther ({ nominators, stakeOther }: Props): React.ReactElement { const { api } = useApi(); const [rewarded, rewardedTotal, unrewarded, unrewardedTotal] = useMemo( () => extractTotals(api.consts.staking?.maxNominatorRewardedPerValidator as u32, nominators, stakeOther), [api, nominators, stakeOther] ); return ( {(!rewarded || rewarded[0] !== 0) && ( } /> )} {unrewarded && ( } /> )} ); } export default React.memo(StakeOther);