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" type Unlocking = { value: bigint era: number } export type AddressLedger = { stash: string total: bigint active: bigint unlocking: Unlocking[] } export const useLedger = ({ address }: { address: string | undefined }) => { const { chainHead$, chainId } = useUnstableProvider() const metadata = useMetadata() const { data: ledger } = useSWRSubscription( chainHead$ && address && chainId && metadata ? ["ledger", chainHead$, address, chainId, metadata] : null, ([_, chainHead$, address, chainId, metadata], { next }) => { const { finalized$, storage$ } = chainHead$ const subscription = finalized$.pipe( filter(Boolean), mergeMap((blockInfo: BlockInfo) => { const builder = getDynamicBuilder(getLookupFn(metadata)) const ledger = builder.buildStorage("Staking", "Ledger") return storage$(blockInfo?.hash, "value", () => ledger?.keys.enc(address) ).pipe( filter(Boolean), distinct(), map((value: string) => ledger?.value.dec(value) as AddressLedger) ) }), ) .subscribe({ next(ledger: AddressLedger) { next(null, ledger) }, error: next, }) return () => subscription.unsubscribe() } ) return ledger }