assign correct indexes to validators

Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
Uncle Fatso 2025-12-06 13:42:04 +03:00
parent 5e96d94b85
commit 9fcf929c57
Signed by: f4ts0
GPG Key ID: 565F4F2860226EBB
5 changed files with 61 additions and 8 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "ghost-lite", "name": "ghost-lite",
"version": "0.2.1", "version": "0.2.2",
"description": "Web application for Ghost and Casper chain.", "description": "Web application for Ghost and Casper chain.",
"author": "Uncle f4ts0 <f4ts0@ghostchain.io>", "author": "Uncle f4ts0 <f4ts0@ghostchain.io>",
"maintainers": [ "maintainers": [

View File

@ -28,6 +28,7 @@ import {
usePayee, usePayee,
useSlasingSpans, useSlasingSpans,
useEraRewardPoints, useEraRewardPoints,
useValidators,
useCurrentValidators, useCurrentValidators,
useValidatorsOverview, useValidatorsOverview,
useBondedAddress, useBondedAddress,
@ -201,16 +202,15 @@ export const Nominations = () => {
const chainSpecV1 = useChainSpecV1() const chainSpecV1 = useChainSpecV1()
const eraIndex = useEraIndex() const eraIndex = useEraIndex()
const validators = useValidators()
const nominations = useNominations({ address: account?.address }) const nominations = useNominations({ address: account?.address })
const ledger = useLedger({ address: account?.address }) const ledger = useLedger({ address: account?.address })
const payee = usePayee({ address: account?.address }) const payee = usePayee({ address: account?.address })
const slashingSpans = useSlasingSpans({ address: account?.address }) const slashingSpans = useSlasingSpans({ address: account?.address })
const eraRewardPoints = useEraRewardPoints({ eraIndex: eraIndex?.index }) const rawEraRewardPoints = useEraRewardPoints({ eraIndex: eraIndex?.index })
const currentValidators = useCurrentValidators({ address: interestingValidator }) const currentValidators = useCurrentValidators({ address: interestingValidator })
const validatorOverview = useValidatorsOverview({ eraIndex: eraIndex?.index, address: interestingValidator }) const validatorOverview = useValidatorsOverview({ eraIndex: eraIndex?.index, address: interestingValidator })
console.log(eraRewardPoints)
const tokenDecimals: number = chainSpecV1?.properties?.tokenDecimals ?? 0 const tokenDecimals: number = chainSpecV1?.properties?.tokenDecimals ?? 0
const tokenSymbol: string = chainSpecV1?.properties?.tokenSymbol ?? "" const tokenSymbol: string = chainSpecV1?.properties?.tokenSymbol ?? ""
const ss58Format: number = chainSpecV1?.properties?.ss58Format ?? 1995 const ss58Format: number = chainSpecV1?.properties?.ss58Format ?? 1995
@ -221,6 +221,17 @@ export const Nominations = () => {
: undefined : undefined
}) })
const eraRewardPoints = useMemo(() => {
const lookup = rawEraRewardPoints?.individual?.reduce(
(acc: Record<string, number>, [key, value]: [string, number]) => {
acc[key] = value
return acc
},
{} as Record<string, number>
)
return validators?.map((key: string) => [key, lookup?.[key] ?? 0])
}, [rawEraRewardPoints, validators])
const destinationReceiverIsValid = useMemo(() => { const destinationReceiverIsValid = useMemo(() => {
try { try {
const [, prefix] = ss58Decode(destinationReceiver) const [, prefix] = ss58Decode(destinationReceiver)
@ -354,7 +365,7 @@ export const Nominations = () => {
<div className="bg-muted p-4 rounded flex flex-col gap-4"> <div className="bg-muted p-4 rounded flex flex-col gap-4">
<div className="flex flex-row justify-between items-center gap-2"> <div className="flex flex-row justify-between items-center gap-2">
<HeaderInfo text="Current Era" value={`#${eraIndex?.index.toString() ?? "..."}`} /> <HeaderInfo text="Current Era" value={`#${eraIndex?.index.toString() ?? "..."}`} />
<HeaderInfo text="Total Points" value={eraRewardPoints?.total.toString() ?? "..."} /> <HeaderInfo text="Total Points" value={rawEraRewardPoints?.total.toString() ?? "..."} />
{nominations && ( {nominations && (
<HeaderInfo text="Submitted at" value={`#${nominations?.submitted_in.toString() ?? "..."}`} /> <HeaderInfo text="Submitted at" value={`#${nominations?.submitted_in.toString() ?? "..."}`} />
)} )}
@ -529,7 +540,7 @@ export const Nominations = () => {
</Button> </Button>
)} )}
</div> </div>
{eraRewardPoints?.individual.some((indivial: RewardPoints) => indivial?.at(0) === account?.address) && ( {eraRewardPoints?.some((indivial: RewardPoints) => indivial?.at(0) === account?.address) && (
<p className="text-xs text-destructive"> <p className="text-xs text-destructive">
You are attempting to use the nomination functionality from the current validator account, which is mutually exclusive. Please switch accounts or proceed at your own risk. You are attempting to use the nomination functionality from the current validator account, which is mutually exclusive. Please switch accounts or proceed at your own risk.
</p> </p>
@ -538,7 +549,7 @@ export const Nominations = () => {
</div> </div>
{eraRewardPoints && ( {eraRewardPoints && (
<Accordion collapsible onValueChange={setInterestingValidator} type="single" className="sm:w-[500px] w-[85%] h-fit flex flex-col flex-1 gap-4 justify-center self-center sm:text-base text-xs"> <Accordion collapsible onValueChange={setInterestingValidator} type="single" className="sm:w-[500px] w-[85%] h-fit flex flex-col flex-1 gap-4 justify-center self-center sm:text-base text-xs">
{eraRewardPoints?.individual.map((indivial: RewardPoints, idx: number) => ( {eraRewardPoints?.map((indivial: RewardPoints, idx: number) => (
<Item <Item
key={idx} key={idx}
name={addressBook?.find((record: AddressBookRecord) => record.address === indivial.at(0))?.name} name={addressBook?.find((record: AddressBookRecord) => record.address === indivial.at(0))?.name}

View File

@ -20,3 +20,4 @@ export * from "./usePayee"
export * from "./useSlasingSpans" export * from "./useSlasingSpans"
export * from "./useAuthorities" export * from "./useAuthorities"
export * from "./useCurrentIndex" export * from "./useCurrentIndex"
export * from "./useValidators"

View File

@ -14,7 +14,6 @@ export type EraRewardPoints = {
} }
export const useEraRewardPoints = ({ eraIndex }: { eraIndex: number | undefined }) => { export const useEraRewardPoints = ({ eraIndex }: { eraIndex: number | undefined }) => {
const { chainHead$, chainId } = useUnstableProvider() const { chainHead$, chainId } = useUnstableProvider()
const metadata = useMetadata() const metadata = useMetadata()
const { data: eraRewardPoints } = useSWRSubscription( const { data: eraRewardPoints } = useSWRSubscription(

View File

@ -0,0 +1,42 @@
import useSWRSubscription from "swr/subscription"
import { getDynamicBuilder, getLookupFn } from "@polkadot-api/metadata-builders"
import type { BlockInfo } from "@polkadot-api/observable-client"
import { distinct, filter, map, mergeMap } from "rxjs"
import { useUnstableProvider } from "./useUnstableProvider"
import { useMetadata } from "./useMetadata"
export const useValidators = () => {
const { chainHead$, chainId } = useUnstableProvider()
const metadata = useMetadata()
const { data: validators } = useSWRSubscription(
chainHead$ && chainId && metadata
? ["SessionValidators", chainHead$, chainId, metadata]
: null,
([_, chainHead$, chainId, metadata], { next }) => {
const { finalized$, storage$ } = chainHead$
const subscription = finalized$.pipe(
filter(Boolean),
mergeMap((blockInfo: BlockInfo) => {
const builder = getDynamicBuilder(getLookupFn(metadata))
const validators = builder.buildStorage("Session", "Validators")
return storage$(blockInfo?.hash, "value", () =>
validators?.keys.enc()
).pipe(
filter(Boolean),
distinct(),
map((value: string) => validators?.value.dec(value))
)
}),
)
.subscribe({
next(validators: string[]) {
next(null, validators)
},
error: next,
})
return () => subscription.unsubscribe()
}
)
return validators
}