Compare commits
No commits in common. "f34d53a9364d9650239f2141c8cc454c027fdeaa" and "5b32bd5500129fbf41c5f791f552bd947bd6fb84" have entirely different histories.
f34d53a936
...
5b32bd5500
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ghost-lite",
|
"name": "ghost-lite",
|
||||||
"version": "0.1.3",
|
"version": "0.1.1",
|
||||||
"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": [
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { useEffect, useState, useMemo, useCallback } from "react"
|
import React, { useEffect, useState, useMemo, useCallback } from "react"
|
||||||
import { Nut, NutOff, Users, PiggyBank } from "lucide-react"
|
import { Nut, NutOff, Users } from "lucide-react"
|
||||||
|
|
||||||
import { ss58Decode } from "@polkadot-labs/hdkd-helpers"
|
import { ss58Decode } from "@polkadot-labs/hdkd-helpers"
|
||||||
import { toHex } from "@polkadot-api/utils"
|
import { toHex } from "@polkadot-api/utils"
|
||||||
@ -22,8 +22,6 @@ import {
|
|||||||
useMetadata,
|
useMetadata,
|
||||||
useEraIndex,
|
useEraIndex,
|
||||||
useNominations,
|
useNominations,
|
||||||
useLedger,
|
|
||||||
usePayee,
|
|
||||||
useEraRewardPoints,
|
useEraRewardPoints,
|
||||||
useCurrentValidators,
|
useCurrentValidators,
|
||||||
useValidatorsOverview,
|
useValidatorsOverview,
|
||||||
@ -31,10 +29,8 @@ import {
|
|||||||
useNominateCalldata,
|
useNominateCalldata,
|
||||||
useSystemAccount,
|
useSystemAccount,
|
||||||
useBondCalldata,
|
useBondCalldata,
|
||||||
useUnbondCalldata,
|
|
||||||
useUnstableProvider,
|
useUnstableProvider,
|
||||||
RewardPoints,
|
RewardPoints,
|
||||||
Unlocking,
|
|
||||||
} from "../hooks"
|
} from "../hooks"
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -114,9 +110,7 @@ const Item: React.FC<ItemProps> = (props) => {
|
|||||||
<div>
|
<div>
|
||||||
<AccordionTrigger>
|
<AccordionTrigger>
|
||||||
<div className="w-100 flex flex-row items-center justify-start gap-4 space-x-2 cursor-pointer">
|
<div className="w-100 flex flex-row items-center justify-start gap-4 space-x-2 cursor-pointer">
|
||||||
<div className={`w-[300px] overflow-hidden whitespace-nowrap text-ellipsis text-left ${nominated ? "text-foreground" : ""}`}>
|
<div className={`w-[300px] overflow-hidden whitespace-nowrap text-ellipsis text-left ${nominated ? "text-foreground" : ""}`}>{name ?? address}</div>
|
||||||
{name ?? (address.slice(0, 15) + "..." + address.slice(-15))}
|
|
||||||
</div>
|
|
||||||
<div>{points}</div>
|
<div>{points}</div>
|
||||||
</div>
|
</div>
|
||||||
</AccordionTrigger>
|
</AccordionTrigger>
|
||||||
@ -204,8 +198,6 @@ export const Nominations = () => {
|
|||||||
const chainSpecV1 = useChainSpecV1()
|
const chainSpecV1 = useChainSpecV1()
|
||||||
const eraIndex = useEraIndex()
|
const eraIndex = useEraIndex()
|
||||||
const nominations = useNominations({ address: account?.address })
|
const nominations = useNominations({ address: account?.address })
|
||||||
const ledger = useLedger({ address: account?.address })
|
|
||||||
const payee = usePayee({ address: account?.address })
|
|
||||||
const eraRewardPoints = useEraRewardPoints({ eraIndex: eraIndex?.index })
|
const eraRewardPoints = 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 })
|
||||||
@ -233,54 +225,6 @@ export const Nominations = () => {
|
|||||||
const bondCalldata = useBondCalldata(
|
const bondCalldata = useBondCalldata(
|
||||||
convertedAmount > 0n ? convertedAmount : undefined
|
convertedAmount > 0n ? convertedAmount : undefined
|
||||||
)
|
)
|
||||||
const unbondCalldata = useUnbondCalldata(
|
|
||||||
convertedAmount > 0n ? convertedAmount : undefined
|
|
||||||
)
|
|
||||||
|
|
||||||
const payeeDescription = useMemo(() => {
|
|
||||||
let description = "Unknown reward destination"
|
|
||||||
switch (payee?.type) {
|
|
||||||
case "Staked":
|
|
||||||
description = "Re-stake rewards"
|
|
||||||
break;
|
|
||||||
case "Stash":
|
|
||||||
description = "Withdraw rewards to free"
|
|
||||||
break;
|
|
||||||
case "Account":
|
|
||||||
description = `Rewards to => ${payee?.value}`
|
|
||||||
break;
|
|
||||||
case "None":
|
|
||||||
description = "Refuse to receive rewards"
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return description
|
|
||||||
}, [payee])
|
|
||||||
|
|
||||||
const readyToWithdraw = useMemo(() => {
|
|
||||||
return ledger?.unlocking.reduce((acc: bigint, item: Unlocking) => {
|
|
||||||
if ((eraIndex?.index ?? 0) >= item.era) {
|
|
||||||
return item.value
|
|
||||||
}
|
|
||||||
return 0n
|
|
||||||
}, 0n)
|
|
||||||
}, [ledger, eraIndex])
|
|
||||||
|
|
||||||
const waitingForWithdraw = useMemo(() => {
|
|
||||||
return ledger?.unlocking.reduce((acc: bigint, item: Unlocking) => {
|
|
||||||
if ((eraIndex?.index ?? 0) < item.era) {
|
|
||||||
return item.value
|
|
||||||
}
|
|
||||||
return 0n
|
|
||||||
}, 0n)
|
|
||||||
}, [ledger, eraIndex])
|
|
||||||
|
|
||||||
const latestWithdrawEra = useMemo(() => {
|
|
||||||
return Math.max(ledger?.unlocking.map((el: Unlocking) => el.era - (eraIndex?.index ?? 0)) ?? [])
|
|
||||||
}, [eraIndex, ledger])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setIsCheckedAddresses([])
|
|
||||||
}, [account])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (checkedAddresses.length === 0 && nominations) {
|
if (checkedAddresses.length === 0 && nominations) {
|
||||||
@ -303,55 +247,6 @@ export const Nominations = () => {
|
|||||||
return `${formatter.format(numberValue)} ${tokenSymbol}`
|
return `${formatter.format(numberValue)} ${tokenSymbol}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleOnUnbond = useCallback(async () => {
|
|
||||||
setIsSubmittingTransaction(true)
|
|
||||||
setTransactionStatus(undefined)
|
|
||||||
setError(undefined)
|
|
||||||
|
|
||||||
try {
|
|
||||||
const tx = await provider!.createTx(
|
|
||||||
chainId ?? "",
|
|
||||||
account ? toHex(ss58Decode(account.address)[0]) : "",
|
|
||||||
unbondCalldata ?? ""
|
|
||||||
)
|
|
||||||
await lastValueFrom(
|
|
||||||
submitTransaction$(clientFull, tx)
|
|
||||||
.pipe(
|
|
||||||
tap(({ txEvent }) => {
|
|
||||||
let status: string = ""
|
|
||||||
switch (txEvent.type) {
|
|
||||||
case "broadcasted":
|
|
||||||
status = "broadcasted to available peers"
|
|
||||||
break
|
|
||||||
case "txBestBlocksState":
|
|
||||||
status = `included in block #${txEvent.block.number}`
|
|
||||||
break
|
|
||||||
case "finalized":
|
|
||||||
status = `finalized at block #${txEvent.block.number}`
|
|
||||||
break
|
|
||||||
case "throttled":
|
|
||||||
status = "throttling to detect chain head..."
|
|
||||||
break
|
|
||||||
}
|
|
||||||
setTransactionStatus({
|
|
||||||
status,
|
|
||||||
hash: txEvent.block?.hash,
|
|
||||||
})
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
} catch (err) {
|
|
||||||
if (err instanceof Error) {
|
|
||||||
const currentError = { type: "error", error: err.message }
|
|
||||||
setError(currentError)
|
|
||||||
}
|
|
||||||
console.error(err)
|
|
||||||
} finally {
|
|
||||||
setAmount("")
|
|
||||||
setIsSubmittingTransaction(false)
|
|
||||||
}
|
|
||||||
}, [account, unbondCalldata, chainId, clientFull, provider])
|
|
||||||
|
|
||||||
const handleOnBond = useCallback(async () => {
|
const handleOnBond = useCallback(async () => {
|
||||||
setIsSubmittingTransaction(true)
|
setIsSubmittingTransaction(true)
|
||||||
setTransactionStatus(undefined)
|
setTransactionStatus(undefined)
|
||||||
@ -471,76 +366,23 @@ export const Nominations = () => {
|
|||||||
connectAccount={connectAccount}
|
connectAccount={connectAccount}
|
||||||
applyDecimals={applyDecimals}
|
applyDecimals={applyDecimals}
|
||||||
/>
|
/>
|
||||||
{ledger && ledger.total > 0n && (<Accordion type="multiple" className="w-full flex flex-col gap-4 mb-4">
|
<Row title="Bonded Amount" element={<Input
|
||||||
<AccordionItem className="bg-muted rounded text-sm" value="Bonding Details">
|
|
||||||
<AccordionTrigger>
|
|
||||||
<div className="flex items-center gap-2 space-x-2 cursor-pointer">
|
|
||||||
Bonding Details
|
|
||||||
</div>
|
|
||||||
</AccordionTrigger>
|
|
||||||
<AccordionContent className="flex flex-col gap-2 pl-8">
|
|
||||||
<Row title="Destination" element={<Input
|
|
||||||
readOnly
|
readOnly
|
||||||
aria-label="Destination"
|
aria-label="Bonded Amount"
|
||||||
type="text"
|
type="text"
|
||||||
className="sm:w-[300px] w-full"
|
className="sm:w-[300px] w-full"
|
||||||
placeholder={payeeDescription}
|
placeholder={applyDecimals(senderAccount?.data.frozen, tokenDecimals, tokenSymbol)}
|
||||||
/>} />
|
/>} />
|
||||||
<Row title="Total Bond" element={<Input
|
<hr />
|
||||||
readOnly
|
<Row title="Amount" element={<Input
|
||||||
aria-label="Total Bond"
|
|
||||||
type="text"
|
|
||||||
className="sm:w-[300px] w-full"
|
|
||||||
placeholder={applyDecimals(ledger?.total, tokenDecimals, tokenSymbol)}
|
|
||||||
/>} />
|
|
||||||
<Row title="Active Bond" element={<Input
|
|
||||||
readOnly
|
|
||||||
aria-label="Active Bond"
|
|
||||||
type="text"
|
|
||||||
className="sm:w-[300px] w-full"
|
|
||||||
placeholder={applyDecimals(ledger?.active, tokenDecimals, tokenSymbol)}
|
|
||||||
/>} />
|
|
||||||
{ledger && ledger.unlocking.length > 0 && (
|
|
||||||
<>
|
|
||||||
<hr className="my-2" />
|
|
||||||
<Row title="Ready" element={<Input
|
|
||||||
readOnly
|
|
||||||
aria-label="Ready"
|
|
||||||
type="text"
|
|
||||||
className="sm:w-[300px] w-full"
|
|
||||||
placeholder={applyDecimals(readyToWithdraw, tokenDecimals, tokenSymbol)}
|
|
||||||
/>} />
|
|
||||||
<Row title={`After ${latestWithdrawEra} era${latestWithdrawEra > 1 ? "s" : ""}`} element={<Input
|
|
||||||
readOnly
|
|
||||||
aria-label="Pending"
|
|
||||||
type="text"
|
|
||||||
className="sm:w-[300px] w-full"
|
|
||||||
placeholder={applyDecimals(waitingForWithdraw, tokenDecimals, tokenSymbol)}
|
|
||||||
/>} />
|
|
||||||
<Button
|
|
||||||
type="button"
|
|
||||||
variant="secondary"
|
|
||||||
className="text-sm my-4 w-full"
|
|
||||||
onClick={() => alert("Not implemented yet")}
|
|
||||||
disabled={isSubmittingTransaction || readyToWithdraw === 0n}
|
|
||||||
>
|
|
||||||
<PiggyBank className="w-4 h-4 inline-block mr-2" />
|
|
||||||
Withdraw
|
|
||||||
</Button>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</AccordionContent>
|
|
||||||
</AccordionItem>
|
|
||||||
</Accordion>)}
|
|
||||||
<Input
|
|
||||||
value={amount}
|
value={amount}
|
||||||
onChange={e => setAmount(e.target.value)}
|
onChange={e => setAmount(e.target.value)}
|
||||||
disabled={isSubmittingTransaction}
|
disabled={isSubmittingTransaction}
|
||||||
aria-label="Transfer Amount"
|
aria-label="Transfer Amount"
|
||||||
type="text"
|
type="text"
|
||||||
className="w-full"
|
className="sm:w-[300px] w-full"
|
||||||
placeholder="Input amount to bond or unbond"
|
placeholder="Input amount to bond or unbond"
|
||||||
/>
|
/>} />
|
||||||
<div className="flex justify-between gap-2">
|
<div className="flex justify-between gap-2">
|
||||||
{bondedAddress && (
|
{bondedAddress && (
|
||||||
<Button
|
<Button
|
||||||
@ -548,7 +390,6 @@ export const Nominations = () => {
|
|||||||
variant="secondary"
|
variant="secondary"
|
||||||
className="text-sm p-4 w-full"
|
className="text-sm p-4 w-full"
|
||||||
onClick={handleOnNominate}
|
onClick={handleOnNominate}
|
||||||
disabled={isSubmittingTransaction || convertedAmount === 0n}
|
|
||||||
>
|
>
|
||||||
<Users className="w-4 h-4 inline-block mr-2" />
|
<Users className="w-4 h-4 inline-block mr-2" />
|
||||||
Nominate
|
Nominate
|
||||||
@ -560,7 +401,6 @@ export const Nominations = () => {
|
|||||||
variant="secondary"
|
variant="secondary"
|
||||||
className="text-sm p-4 w-full"
|
className="text-sm p-4 w-full"
|
||||||
onClick={handleOnBond}
|
onClick={handleOnBond}
|
||||||
disabled={isSubmittingTransaction || convertedAmount === 0n}
|
|
||||||
>
|
>
|
||||||
<Nut className="w-4 h-4 inline-block mr-2" />
|
<Nut className="w-4 h-4 inline-block mr-2" />
|
||||||
Bond
|
Bond
|
||||||
@ -569,9 +409,8 @@ export const Nominations = () => {
|
|||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
|
disabled={!bondedAddress}
|
||||||
className="text-sm p-4 w-full"
|
className="text-sm p-4 w-full"
|
||||||
onClick={handleOnUnbond}
|
|
||||||
disabled={isSubmittingTransaction || convertedAmount === 0n}
|
|
||||||
>
|
>
|
||||||
<NutOff className="w-4 h-4 inline-block mr-2" />
|
<NutOff className="w-4 h-4 inline-block mr-2" />
|
||||||
Unbond
|
Unbond
|
||||||
@ -600,7 +439,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 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?.individual.map((indivial: RewardPoints, idx: number) => (
|
||||||
<Item
|
<Item
|
||||||
key={idx}
|
key={idx}
|
||||||
|
@ -14,5 +14,3 @@ export * from "./useCurrentValidators"
|
|||||||
export * from "./useValidatorsOverview"
|
export * from "./useValidatorsOverview"
|
||||||
export * from "./useBondedAddress"
|
export * from "./useBondedAddress"
|
||||||
export * from "./useNominations"
|
export * from "./useNominations"
|
||||||
export * from "./useLedger"
|
|
||||||
export * from "./usePayee"
|
|
||||||
|
@ -48,34 +48,12 @@ export const useTransferCalldata = (destination: SS58String | undefined, amount:
|
|||||||
return calldata
|
return calldata
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useUnbondCalldata = (amount: bigint | undefined) => {
|
|
||||||
const { client, chainId } = useUnstableProvider()
|
|
||||||
const metadata = useMetadata()
|
|
||||||
const { data: calldata } = useSWR(
|
|
||||||
client && chainId && amount && metadata
|
|
||||||
? ["unbond", client, chainId, metadata, amount]
|
|
||||||
: null,
|
|
||||||
([_, client, _chainId, metadata, amount]) => {
|
|
||||||
const builder = getDynamicBuilder(getLookupFn(metadata))
|
|
||||||
const { codec, location } = builder.buildCall("Staking", "unbond")
|
|
||||||
|
|
||||||
return toHex(
|
|
||||||
mergeUint8(
|
|
||||||
new Uint8Array(location),
|
|
||||||
codec.enc({ value: amount }),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return calldata
|
|
||||||
}
|
|
||||||
|
|
||||||
export const useBondCalldata = (amount: bigint | undefined) => {
|
export const useBondCalldata = (amount: bigint | undefined) => {
|
||||||
const { client, chainId } = useUnstableProvider()
|
const { client, chainId } = useUnstableProvider()
|
||||||
const metadata = useMetadata()
|
const metadata = useMetadata()
|
||||||
const { data: calldata } = useSWR(
|
const { data: calldata } = useSWR(
|
||||||
client && chainId && amount && metadata
|
client && chainId && amount && metadata
|
||||||
? ["bond", client, chainId, metadata, amount]
|
? ["metadata", client, chainId, metadata, amount]
|
||||||
: null,
|
: null,
|
||||||
([_, client, _chainId, metadata, amount]) => {
|
([_, client, _chainId, metadata, amount]) => {
|
||||||
const builder = getDynamicBuilder(getLookupFn(metadata))
|
const builder = getDynamicBuilder(getLookupFn(metadata))
|
||||||
@ -100,7 +78,7 @@ export const useNominateCalldata = (addresses: string[]) => {
|
|||||||
const metadata = useMetadata()
|
const metadata = useMetadata()
|
||||||
const { data: calldata } = useSWR(
|
const { data: calldata } = useSWR(
|
||||||
client && chainId && addresses && metadata
|
client && chainId && addresses && metadata
|
||||||
? ["nominate", client, chainId, metadata, addresses]
|
? ["metadata", client, chainId, metadata, addresses]
|
||||||
: null,
|
: null,
|
||||||
([_, client, _chainId, metadata, addresses]) => {
|
([_, client, _chainId, metadata, addresses]) => {
|
||||||
const builder = getDynamicBuilder(getLookupFn(metadata))
|
const builder = getDynamicBuilder(getLookupFn(metadata))
|
||||||
|
@ -1,54 +0,0 @@
|
|||||||
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 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
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
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 type Payee = {
|
|
||||||
type: string
|
|
||||||
value: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export const usePayee = ({ address }: { address: string | undefined }) => {
|
|
||||||
const { chainHead$, chainId } = useUnstableProvider()
|
|
||||||
const metadata = useMetadata()
|
|
||||||
const { data: payee } = useSWRSubscription(
|
|
||||||
chainHead$ && address && chainId && metadata
|
|
||||||
? ["payee", 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 payee = builder.buildStorage("Staking", "Payee")
|
|
||||||
return storage$(blockInfo?.hash, "value", () =>
|
|
||||||
payee?.keys.enc(address)
|
|
||||||
).pipe(
|
|
||||||
filter(Boolean),
|
|
||||||
distinct(),
|
|
||||||
map((value: string) => payee?.value.dec(value) as Payee)
|
|
||||||
)
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.subscribe({
|
|
||||||
next(payee: Payee) {
|
|
||||||
next(null, payee)
|
|
||||||
},
|
|
||||||
error: next,
|
|
||||||
})
|
|
||||||
return () => subscription.unsubscribe()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return payee
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user