Files
pezkuwi-apps/packages/page-staking2/src/Validators/useExposure.ts
T
Kurdistan Tech MinistryandClaude Opus 4.5 7a4bbeac25 fix: update extension packages and fix type compatibility for pezkuwi-sdk
- Update @pezkuwi/extension-inject to ^0.62.13 with proper /types exports
- Update @pezkuwi/extension-dapp to ^0.62.13
- Update @pezkuwi/extension-compat-metamask to ^0.62.13
- Fix IconTheme type to include 'bizinikiwi' and 'pezkuwi' themes
- Fix endpoint array issues (getTeleports -> direct array references)
- Add type assertions for external package compatibility (acala, moonbeam, parallel)
- Fix subspace.ts dynamic class typing
- Fix conviction type in page-referenda
- Update Pallet type names to Pezpallet prefix across codebase
- Define InjectedExtension types locally for module resolution
- Add styled-components DefaultTheme augmentation
- Add react-copy-to-clipboard type declaration for React 18

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 16:24:19 +03:00

67 lines
1.9 KiB
TypeScript

// Copyright 2017-2026 @pezkuwi/app-staking authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { PezspStakingExposure } from '@pezkuwi/types/lookup';
import type { SessionInfo, Validator } from '../types.js';
import type { UseExposure, UseExposureExposure } from './types.js';
import { useMemo } from 'react';
import { createNamedHook, useApi, useCall } from '@pezkuwi/react-hooks';
import { BN } from '@pezkuwi/util';
import { useCacheMap } from '../useCache.js';
const OPT_EXPOSURE = {
transform: ({ others, own, total }: PezspStakingExposure): UseExposureExposure => ({
others: others
.map(({ value, who }) => ({
value: value.unwrap(),
who: who.toString()
}))
.sort((a, b) => (b.value as BN).cmp(a.value)),
own: own.unwrap(),
total: total.unwrap()
})
};
function getResult (exposure: UseExposureExposure, clipped: UseExposureExposure): UseExposure {
let waiting: UseExposure['waiting'];
const others = exposure.others.filter(({ who }) =>
!clipped.others.find((c) =>
who === c.who
)
);
if (others.length) {
waiting = {
others,
total: others.reduce((total, { value }) => total.iadd(value), new BN(0))
};
}
return { clipped, exposure, waiting };
}
function useExposureImpl ({ stashId }: Validator, { activeEra }: SessionInfo): UseExposure | undefined {
const { api } = useApi();
const params = useMemo(
() => activeEra && [activeEra, stashId],
[activeEra, stashId]
);
const fullExposure = useCall(params && api.query.staking.erasStakers, params, OPT_EXPOSURE);
const clipExposure = useCall(params && api.query.staking.erasStakersClipped, params, OPT_EXPOSURE);
const result = useMemo(
() => fullExposure && clipExposure && getResult(fullExposure, clipExposure),
[clipExposure, fullExposure]
);
return useCacheMap('useExposure', stashId, result);
}
export default createNamedHook('useExposure', useExposureImpl);