55 lines
1.9 KiB
TypeScript
55 lines
1.9 KiB
TypeScript
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
|
|
}
|