@polkadot/types/interfaces#ActiveEraInfo TypeScript Examples
The following examples show how to use
@polkadot/types/interfaces#ActiveEraInfo.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Guaranteeable.tsx From crust-apps with Apache License 2.0 | 6 votes |
function GuaranteeableDisplay ({ params }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const stakeLimit = useCall<Option<Balance>>(api.query.staking.stakeLimit, [params]);
const activeEraInfo = useCall<ActiveEraInfo>(api.query.staking.activeEra);
const activeEra = activeEraInfo && (JSON.parse(JSON.stringify(activeEraInfo)).index);
const accountIdBonded = useCall<string | null>(api.query.staking.bonded, [params], transformBonded);
const controllerActive = useCall<Balance | null>(api.query.staking.ledger, [accountIdBonded], transformLedger);
const erasStakersStashExposure = useCall<Option<Exposure>>(api.query.staking.erasStakers, [activeEra, params]);
const erasStakersStash = erasStakersStashExposure && (parseObj(erasStakersStashExposure).others.map((e: { who: any; }) => e.who));
const stakersGuarantees = useCall<Guarantee[]>(api.query.staking.guarantors.multi, [erasStakersStash]);
let totalStaked = new BN(Number(controllerActive).toString());
if (stakersGuarantees) {
for (const stakersGuarantee of stakersGuarantees) {
if (parseObj(stakersGuarantee)) {
for (const target of parseObj(stakersGuarantee)?.targets) {
if (target.who.toString() == params?.toString()) {
totalStaked = totalStaked?.add(new BN(Number(target.value).toString()));
}
}
}
}
}
return (
<>
<span className='highlight'>{t<string>('total stakes')} {formatBalance(totalStaked, { withUnit: true })} / {t<string>('stake limit')} { formatBalance(new BN(Number(stakeLimit).toString()))}</span>
</>
);
}
Example #2
Source File: index.tsx From crust-apps with Apache License 2.0 | 6 votes |
function useAddressCalls (api: ApiPromise, address: string, isMain?: boolean) {
const params = useMemo(() => [address], [address]);
const stakeLimit = useCall<BN>(api.query.staking.stakeLimit, params);
const accountInfo = useCall<DeriveAccountInfo>(api.derive.accounts.info, params);
const slashingSpans = useCall<SlashingSpans | null>(!isMain && api.query.staking.slashingSpans, params, transformSlashes);
const activeEraInfo = useCall<ActiveEraInfo>(api.query.staking.activeEra);
const activeEra = activeEraInfo && (JSON.parse(JSON.stringify(activeEraInfo)).index);
const erasStakersStashExposure = useCall<Exposure>(api.query.staking.erasStakers, [activeEra, address]);
const accountIdBonded = useCall<string | null>(api.query.staking.bonded, params, transformBonded);
const controllerActive = useCall<Balance | null>(api.query.staking.ledger, [accountIdBonded], transformLedger);
const erasStakersStash = erasStakersStashExposure && (parseObj(erasStakersStashExposure).others.map((e: { who: any; }) => e.who));
const stakersGuarantees = useCall<Guarantee[]>(api.query.staking.guarantors.multi, [erasStakersStash]);
let totalStaked = new BN(Number(controllerActive).toString());
if (stakersGuarantees) {
for (const stakersGuarantee of stakersGuarantees) {
if (parseObj(stakersGuarantee)) {
for (const target of parseObj(stakersGuarantee)?.targets) {
if (target.who.toString() == address) {
totalStaked = totalStaked?.add(new BN(Number(target.value).toString()));
}
}
}
}
}
return { accountInfo, slashingSpans, totalStaked, stakeLimit, activeEra };
}
Example #3
Source File: BoosterCountDown.tsx From crust-apps with Apache License 2.0 | 5 votes |
function BoosterCountDown({ }: Props): React.ReactElement<Props> {
const { api } = useApi();
const { t } = useTranslation();
const endDate = Date.parse('2021-07-11 14:00');
const activeEraInfo = useCall<ActiveEraInfo>(api.query.staking.activeEra);
const activeEra = activeEraInfo && (JSON.parse(JSON.stringify(activeEraInfo)).index);
const [{ day_ten, day_one,hour_ten, hour_one, minute_ten, minute_one, second_ten, second_one }, setCountdownInfo] = useState<CountDownType>({
day_ten: 1,
day_one: 0,
hour_ten: 0,
hour_one: 0,
minute_ten: 0,
minute_one: 0,
second_ten: 0,
second_one: 0
});
useEffect(() => {
let now_time = new Date().getTime();
var remaining = endDate - now_time;
const timer = setInterval(() => {
if (activeEra >= 756 && remaining > 1000) {
remaining -= 1000;
const day = Math.floor((remaining / 1000 / 3600) / 24)
const hour = Math.floor((remaining / 1000 / 3600) % 24)
const minute = Math.floor((remaining / 1000 / 60) % 60)
const second = Math.floor(remaining / 1000 % 60)
setCountdownInfo({
day_ten: Math.floor(day/10),
day_one: day % 10,
hour_ten: Math.floor(hour/10),
hour_one: hour %10,
minute_ten: Math.floor(minute / 10),
minute_one: minute % 10,
second_ten: Math.floor(second/10),
second_one: second % 10
})
} else {
clearInterval(timer)
}
}, 1000)
}, [activeEra]);
return (
<div style={{display: 'inline-block', 'fontWeight': 'bold', fontSize: '16px', "wordWrap": "break-word", "wordBreak": "break-all"}}>
{t<string>('Activities in progress,End time countdown')}
{day_ten} {day_one} : {hour_ten} {hour_one} : {minute_ten} {minute_one} : {second_ten} {second_one}
</div>
);
}
Example #4
Source File: index.tsx From crust-apps with Apache License 2.0 | 5 votes |
function CsmStakingApp({ basePath, onStatusChange }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api, systemChain } = useApi();
const activeEraInfo = useCall<ActiveEraInfo>(api.query.staking.activeEra);
const activeEra = activeEraInfo && (JSON.parse(JSON.stringify(activeEraInfo)).index);
const increasingFactor = Math.pow(1.02, 80) * Math.pow(1.03, Math.min(activeEra-1224, 40));
const overviewUrl = systemChain == 'Crust Maxwell' ? 'https://pd-api.crust.network/overview/' : 'http://crust-sg1.ownstack.cn:8866/overview/';
const [providers, setProviders] = useState<DataProviderState[]>([]);
const [summaryInfo, setSummaryInfo] = useState<SummaryInfo | null>();
const [isLoading, setIsloading] = useState<boolean>(true);
useEffect(() => {
if (Number(increasingFactor)) {
getOverviewInfo(overviewUrl, api, increasingFactor).then(res => {
setProviders(res.providers)
setSummaryInfo(res.summaryInfo)
setIsloading(false);
}).catch(() => setIsloading(true))
}
}, [api, httpGet, overviewUrl, increasingFactor]);
const itemsRef = useRef([
{
isRoot: true,
name: 'overview',
text: t<string>('Overview')
},
{
name: 'actions',
text: t<string>('Account actions')
},
{
name: 'easterEggsOrders',
text: t<string>('Lucky Orders')
}
]);
return (
<main className='accounts--App'>
<header>
<Tabs
basePath={basePath}
items={itemsRef.current}
/>
</header>
<Switch>
<Route path={`${basePath}/actions`}>
<Actions providers={providers?.map((e) => e.account)} />
</Route>
<Route path={`${basePath}/easterEggsOrders`}>
<EasterEggsOrders />
</Route>
<Route basePath={basePath}
onStatusChange={onStatusChange}>
<Overview isLoading={isLoading}
providers={providers}
summaryInfo={summaryInfo} />
</Route>
</Switch>
</main>
);
}
Example #5
Source File: MainnetRewards.tsx From crust-apps with Apache License 2.0 | 5 votes |
function MainnetReward ({ children, className = '', label }: Props): React.ReactElement<Props> {
const { api } = useApi();
const { t } = useTranslation();
const activeEraInfo = useCall<ActiveEraInfo>(api.query.staking.activeEra);
const activeEra = activeEraInfo && (JSON.parse(JSON.stringify(activeEraInfo)).index);
const marketPayout = useCall<any>(api.query.staking.erasMarketPayout, [activeEra]);
const stakingRewards = new BN(3422.3134898087887).mul(UNIT)
const total = marketPayout && stakingRewards.add(new BN(Number(marketPayout).toString()))
return (
<div className={className}>
{label || ''}
<FormatBalance
value={total}
withSi
label={
<Icon
icon='info-circle'
tooltip={`mainnet-reward-trigger`}
/>
}
>
<Tooltip
text={
<>
<div>
<div className='faded'>{t('staking payout: {{stakingRewards}}', {
replace: {
stakingRewards: formatBalance(stakingRewards)
}
})}</div>
<div className='faded'>{t('market payout: {{marketPayout}}', {
replace: {
marketPayout: marketPayout && formatBalance(new BN(Number(marketPayout).toString()))
}
})}</div>
</div>
</>
}
trigger={`mainnet-reward-trigger`}
/>
</FormatBalance>
{children}
</div>
);
}
Example #6
Source File: index.tsx From crust-apps with Apache License 2.0 | 4 votes |
function Overview({ providers, isLoading, summaryInfo }: Props): React.ReactElement<Props> {
const { t, i18n } = useTranslation();
const { api } = useApi();
// we have a very large list, so we use a loading delay
// const [nameFilter, setNameFilter] = useState<string>('');
const [, setProviders] = useState<DataProviderState[]>([]);
const [toggles, setToggle] = useSavedFlags('csmStaking:overview', { withIdentity: false });
const [favorites, toggleFavorite] = useFavorites(CSM_FAVS);
const [{ sortBy, sortFromMax }, setSortBy] = useState<SortState>({ sortBy: 'storage', sortFromMax: false });
const [sorted, setSorted] = useState<DataProviderState[] | undefined>();
const [{ isQueryFiltered, nameFilter }, setNameFilter] = useState({ isQueryFiltered: false, nameFilter: '' });
const endTime = Date.parse('2021-07-11 14:00');
const [remaining, setRemaing] = useState<number>(endTime - new Date().getTime());
const activeEraInfo = useCall<ActiveEraInfo>(api.query.staking.activeEra);
const activeEra = activeEraInfo && (JSON.parse(JSON.stringify(activeEraInfo)).index);
const labelsRef = useRef({
storage: t<string>('data power'),
csmLimit: t<string>('CSM stake limit'),
effectiveCSM: t<string>('effective stakes'),
stakedCSM: t<string>('total stakes'),
guaranteeFee: t<string>('guarantee fee')
});
useEffect(() => {
// let now_time = new Date().getTime();
// var remaining = endTime - now_time;
const timer = setInterval(() => {
if (remaining > 1000) {
setRemaing(remaining-1000)
} else {
clearInterval(timer)
}
}, 1000)
}, [activeEra]);
const filtered = useMemo(
() => providers && applyFilter(providers),
[providers]
);
useEffect((): void => {
const sortedProviders = sortProviders(providers, favorites);
setProviders(sortedProviders)
}, [providers, favorites]);
const _sort = useCallback(
(newSortBy: ProviderSortBy) => setSortBy(({ sortBy, sortFromMax }) => ({
sortBy: newSortBy,
sortFromMax: newSortBy === sortBy
? !sortFromMax
: true
})),
[]
);
useEffect((): void => {
filtered && setSorted(
sort(sortBy, sortFromMax, filtered)
);
}, [filtered, sortBy, sortFromMax]);
const _renderRows = useCallback(
(addresses?: DataProviderState[]): React.ReactNode[] =>
(addresses || []).map((info): React.ReactNode => (
<DataProvider
key={info.account}
info={info}
filterName={nameFilter}
withIdentity={toggles.withIdentity}
toggleFavorite={toggleFavorite}
isFavorite={info.isFavorite}
/>
)),
[nameFilter, setToggle, toggles, toggleFavorite]
);
const _setNameFilter = useCallback(
(nameFilter: string, isQueryFiltered: boolean) => setNameFilter({ isQueryFiltered, nameFilter }),
[]
);
const header = useMemo(() => [
[t('providers'), 'start', 2],
...(SORT_KEYS as (keyof typeof labelsRef.current)[]).map((header) => [
<>{labelsRef.current[header]}<Icon icon={sortBy === header ? (sortFromMax ? 'chevron-down' : 'chevron-up') : 'minus'} /></>,
`${sorted ? `isClickable ${sortBy === header ? 'highlight--border' : ''} number` : 'number'} ${CLASSES[header] || ''}`,
1,
() => _sort(header as 'storage')
]),
], [_sort, labelsRef, sortBy, sorted, sortFromMax, t])
const filter = useMemo(() => (
<Filtering
nameFilter={nameFilter}
setNameFilter={_setNameFilter}
setWithIdentity={setToggle.withIdentity}
withIdentity={toggles.withIdentity}
>
</Filtering>
), [nameFilter, _setNameFilter, setToggle, t, toggles]);
const displayList = isQueryFiltered
? providers
: sorted;
return (<>
<h3 style={{ "textAlign": 'center' }}>
<span style={{ "wordWrap": "break-word", "wordBreak": "break-all", float: "left", 'display': 'inline-block' }}><span style={{ 'fontWeight': 'bold', fontSize: '16px' }}>
<a href={i18n.language == 'zh' ? 'https://mp.weixin.qq.com/s/vLnuyU5gJCRcOSv_PrLAsw' : 'https://medium.com/crustnetwork/profit-data-activity-rules-3ef2c9b364c4'} target="_blank">
{t<string>(`Learn more about "Profit Data" >>`)}</a>
</span>
</span>
{remaining > 1000 ? (<section style={{'display': 'inline-block', "wordWrap": "break-word", "wordBreak": "break-all"}}>
<span style={{"marginRight": "5px", 'fontWeight': 'bold', fontSize: '16px'}}><a href={i18n.language == 'zh' ? 'https://mp.weixin.qq.com/s/P3kCjhPNg9UUH8eLXpvvZg' : 'https://crustnetwork.medium.com/10x-for-10-days-data-power-boost-is-launched-fd6e05b44115'} target="_blank">{t<string>('Data Power Booster ? >>')}</a></span>
<BoosterCountDown />
</section>) : null}
<span style={{ "wordWrap": "break-word", "wordBreak": "break-all", float: "right", 'display': 'inline-block' }}><span style={{ 'fontWeight': 'bold', fontSize: '16px' }}>
<a href={i18n.language == 'zh' ? 'https://mp.weixin.qq.com/s/pp74MQMODwID_gkrbMdHug' : 'https://medium.com/crustnetwork/profit-data-data-power-rules-adjustments-and-upgrades-9fa406c6fc34'} target="_blank">
{t<string>(`About "Data Power" >>`)}</a>
</span>
</span>
</h3>
{isLoading ? <Spinner noLabel /> : <Summary isLoading={isLoading} info={summaryInfo} />}
<Table
empty={!isLoading && t<string>('No funds staked yet. Bond funds to validate or nominate a validator')}
header={header}
filter={filter}
>
{isLoading ? undefined : _renderRows(displayList)}
</Table>
</>
);
}
Example #7
Source File: index.tsx From crust-apps with Apache License 2.0 | 4 votes |
function Account ({ allSlashes, className = '', info: { controllerId, destination, hexSessionIdNext, hexSessionIdQueue, isLoading, isOwnController, isOwnStash, isStashNominating, isStashValidating, nominating, sessionIds, stakingLedger, stashId }, isDisabled, targets }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api, systemChain } = useApi();
const { queueExtrinsic } = useContext(StatusContext);
const [isBondExtraOpen, toggleBondExtra] = useToggle();
const [isInjectOpen, toggleInject] = useToggle();
const [isKickOpen, toggleKick] = useToggle();
const [isNominateOpen, toggleNominate] = useToggle();
const [isCutGuaranteeOpen, toggleCutGuarantee] = useToggle();
const [isRewardDestinationOpen, toggleRewardDestination] = useToggle();
const [isSetControllerOpen, toggleSetController] = useToggle();
const [isSetSessionOpen, toggleSetSession] = useToggle();
const [isSettingsOpen, toggleSettings] = useToggle();
const [isUnbondOpen, toggleUnbond] = useToggle();
const [isRebondOpen, toggleRebond] = useToggle();
const [isValidateOpen, toggleValidate] = useToggle();
const { balancesAll, spanCount, stakingAccount } = useStashCalls(api, stashId);
const activeEraInfo = useCall<ActiveEraInfo>(api.query.staking.activeEra);
const activeEra = activeEraInfo && (JSON.parse(JSON.stringify(activeEraInfo)).index);
const guarantors = useCall<Guarantee>(api.query.staking.guarantors, [stashId]);
const [guaranteeTargets, setGuaranteeTargets] = useState<IndividualExposure[]>([]);
const [stakeValue, setStakeValue] = useState<BN>(BN_ZERO);
const guarantorInfo = guarantors && JSON.parse(JSON.stringify(guarantors));
const validators = useCall<ValidatorId[]>(api.query.session.validators);
const isMaxwell = systemChain === 'Crust Maxwell';
const [role, setRole] = useState<string>('Bonded');
useEffect(() => {
const isGuarantor = guarantorInfo && guarantorInfo.targets.length != 0;
const isValidator = validators && (validators.map(e => e.toString())?.indexOf(stashId) != -1);
const isCandidate = targets && (targets.waitingIds?.indexOf(stashId) != -1);
if (isGuarantor) {
setRole('Guarantor');
} else if (isCandidate) {
setRole('Candidate');
} else if (isValidator) {
setRole('Validator');
} else {
setRole('Bonded');
}
}, [guarantorInfo, validators, activeEra, targets]);
useEffect(() => {
if (guarantorInfo != null) {
setGuaranteeTargets(guarantorInfo.targets);
}
}, [guarantors, validators, activeEra]);
useEffect(() => {
setStakeValue(guaranteeTargets.reduce((total: BN, { value }) => { return total.add(new BN(Number(value).toString())); }, BN_ZERO));
}, [guaranteeTargets, activeEra])
const slashes = useMemo(
() => extractSlashes(stashId, allSlashes),
[allSlashes, stashId]
);
const withdrawFunds = useCallback(
() => {
queueExtrinsic({
accountId: controllerId,
extrinsic: api.tx.staking.withdrawUnbonded.meta.args.length === 1
? api.tx.staking.withdrawUnbonded(spanCount || 0)
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore (We are doing toHex here since we have a Vec<u8> input)
: api.tx.staking.withdrawUnbonded()
});
},
[api, controllerId, queueExtrinsic, spanCount]
);
const hasBonded = !!stakingAccount?.stakingLedger && !stakingAccount.stakingLedger.active.isEmpty;
return (
<tr className={className}>
<td className='badge together'>
{slashes.length !== 0 && (
<Badge
color='red'
hover={t<string>('Slashed in era {{eras}}', {
replace: {
eras: slashes.map(({ era }) => formatNumber(era)).join(', ')
}
})}
icon='skull-crossbones'
/>
)}
</td>
<td className='address'>
<AddressSmall value={stashId} />
{isBondExtraOpen && (
<BondExtra
controllerId={controllerId}
onClose={toggleBondExtra}
stakingInfo={stakingAccount}
stashId={stashId}
/>
)}
{isInjectOpen && (
<InjectKeys onClose={toggleInject} />
)}
{isKickOpen && controllerId && (
<KickNominees
controllerId={controllerId}
onClose={toggleKick}
stashId={stashId}
/>
)}
{isNominateOpen && controllerId && (
<Nominate
controllerId={controllerId}
nominating={nominating}
onClose={toggleNominate}
stashId={stashId}
targets={targets}
/>
)}
{isCutGuaranteeOpen && controllerId && (
<CutGuarantee
controllerId={controllerId}
nominating={nominating}
onClose={toggleCutGuarantee}
stashId={stashId}
targets={targets}
/>
)}
{isSetControllerOpen && controllerId && (
<SetControllerAccount
defaultControllerId={controllerId}
onClose={toggleSetController}
stashId={stashId}
/>
)}
{isRewardDestinationOpen && controllerId && (
<SetRewardDestination
controllerId={controllerId}
defaultDestination={destination}
onClose={toggleRewardDestination}
stashId={stashId}
/>
)}
{isSetSessionOpen && controllerId && (
<SetSessionKey
controllerId={controllerId}
onClose={toggleSetSession}
stashId={stashId}
/>
)}
{isUnbondOpen && (
<Unbond
controllerId={controllerId}
onClose={toggleUnbond}
stakingLedger={stakingLedger}
stashId={stashId}
/>
)}
{isRebondOpen && (
<Rebond
controllerId={controllerId}
onClose={toggleRebond}
stakingLedger={stakingLedger}
stashId={stashId}
/>
)}
{isValidateOpen && controllerId && (
<Validate
controllerId={controllerId}
onClose={toggleValidate}
stashId={stashId}
/>
)}
</td>
<td className='address'>
<AddressMini value={controllerId} />
</td>
<td className='start media--1200'>
{destination?.isAccount
? <AddressMini value={destination.asAccount} />
: destination?.toString()
}
</td>
<td className='number'>
<StakingBonded stakingInfo={stakingAccount} />
<StakingUnbonding stakingInfo={stakingAccount} />
<StakingRedeemable stakingInfo={stakingAccount} />
</td>
{activeEra && (role !== 'Validator' && role !== 'Candidate')
? <EffectiveGuaranteed
activeEra = {activeEra}
stakeValue = {stakeValue}
stashId= {stashId}
validators = {guaranteeTargets}
/>
: activeEra && (
<EffectiveStake
activeEra={activeEra}
stashId={stashId}
/>
)
}
<td className='number ui--media-1200'>{t<string>('{{role}}', { replace: { role: role } })}</td>
{isStashValidating
? (
<td className='all'>
<AddressInfo
address={stashId}
withBalance={false}
withHexSessionId={hexSessionIdNext !== '0x' && [hexSessionIdQueue, hexSessionIdNext]}
withValidatorPrefs
/>
</td>
)
: (
<td className='all expand left'>
{isStashNominating && (
<ListNominees
nominating={nominating}
stashId={stashId}
/>
)}
</td>
)
}
<td className='button'>
{!isLoading && (
<>
{(isStashNominating || isStashValidating)
? (
<TxButton
accountId={controllerId}
icon='stop'
isDisabled={!isOwnController || isDisabled}
key='stop'
label={t<string>('Stop')}
tx={api.tx.staking.chill}
/>
)
: (
<Button.Group>
{(!sessionIds.length || hexSessionIdNext === '0x')
? (
<Button
icon='sign-in-alt'
isDisabled={!isOwnController || isDisabled}
key='set'
label={t<string>('Session Key')}
onClick={toggleSetSession}
/>
)
: (
<Button
icon='certificate'
isDisabled={!isOwnController || isDisabled || !hasBonded}
key='validate'
label={t<string>('Validate')}
onClick={toggleValidate}
/>
)
}
<Button
icon='hand-paper'
isDisabled={!isOwnController || isDisabled || !hasBonded}
key='nominate'
label={t<string>('Guarantee')}
onClick={toggleNominate}
/>
</Button.Group>
)
}
<Popup
isOpen={isSettingsOpen}
key='settings'
onClose={toggleSettings}
trigger={
<Button
icon='ellipsis-v'
isDisabled={isDisabled}
onClick={toggleSettings}
/>
}
>
<Menu
onClick={toggleSettings}
text
vertical
>
Bond
<Menu.Item
disabled={!isOwnStash || !balancesAll?.freeBalance.gtn(0)}
onClick={toggleBondExtra}
>
{t<string>('Bond more funds')}
</Menu.Item>
<Menu.Item
disabled={!isOwnController || !stakingAccount || !stakingAccount.stakingLedger || stakingAccount.stakingLedger.active.isEmpty}
onClick={toggleUnbond}
>
{t<string>('Unbond funds')}
</Menu.Item>
<Menu.Item
disabled={!isOwnController || !stakingAccount || !stakingAccount.stakingLedger }
onClick={toggleRebond}
>
{t<string>('Rebond funds')}
</Menu.Item>
<Menu.Item
disabled={!isOwnController || !stakingAccount || !stakingAccount.redeemable || !stakingAccount.redeemable.gtn(0)}
onClick={withdrawFunds}
>
{t<string>('Withdraw unbonded funds')}
</Menu.Item>
<Menu.Item
disabled={!isOwnStash}
onClick={toggleSetController}
>
{t<string>('Change controller account')}
</Menu.Item>
{isMaxwell && (<Menu.Item
disabled={!isOwnController}
onClick={toggleRewardDestination}
>
{t<string>('Change reward destination')}
</Menu.Item>)}
<Menu.Divider />
{
(role !== 'Bonded' && role != 'Guarantor' ) ? <>
{ 'Validate' }
{isStashValidating && (
<>
<Menu.Item
disabled={!isOwnController}
onClick={toggleValidate}
>
{t<string>('Change validator preferences')}
</Menu.Item>
{isFunction(api.tx.staking.kick) && (
<Menu.Item
disabled={!isOwnController}
onClick={toggleKick}
>
{t<string>('Remove nominees')}
</Menu.Item>
)}
</>
)}
{
<Menu.Item
disabled={!isOwnController}
onClick={toggleSetSession}
>
{t<string>('Change session keys')}
</Menu.Item>
}
{
<Menu.Item onClick={toggleInject}>
{t<string>('Inject session keys (advanced)')}
</Menu.Item>
}
</> : null
}
{(role !== 'Validator' && role != 'Candidate' ) ? <>
<Menu.Divider />
{ 'Guarantee' }
{
<Menu.Item
disabled={!isOwnController || !targets.validators?.length}
onClick={toggleNominate}
>
{t<string>('Guarantee')}
</Menu.Item>
}
{
<Menu.Item
disabled={!isOwnController || !targets.validators?.length}
onClick={toggleCutGuarantee}
>
{t<string>('Cut guarantee')}
</Menu.Item>
}
</> : null
}
</Menu>
</Popup>
</>
)}
</td>
</tr>
);
}