refactor: move extrinsic stuff to a separate folder
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import { BlockContext } from "@/state/block.state"
|
||||
import { client$ } from "@/state/chains/chain.state"
|
||||
import { useStateObservable, withDefault } from "@react-rxjs/core"
|
||||
import { jsonSerialize } from "polkadot-api/utils"
|
||||
import { FC, useContext } from "react"
|
||||
import { map, switchMap } from "rxjs"
|
||||
import { BlockContext } from "./blockContext"
|
||||
|
||||
const finalizedNumber$ = client$.pipeState(
|
||||
switchMap((v) => v.bestBlocks$),
|
||||
@@ -29,8 +29,8 @@ export const MortalityAnalyzer: FC<{
|
||||
)
|
||||
}
|
||||
|
||||
const parseResult = /^Mortal(\d+)$/.exec(mortality.type)
|
||||
if (parseResult === null) {
|
||||
const decoded = decodeMortality(mortality)
|
||||
if (decoded === null) {
|
||||
return (
|
||||
<div className="rounded-lg border border-foreground/10 bg-background/60 px-3 py-2">
|
||||
<div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-foreground/50">
|
||||
@@ -43,14 +43,7 @@ export const MortalityAnalyzer: FC<{
|
||||
)
|
||||
}
|
||||
|
||||
const first = BigInt(parseResult[1])
|
||||
const second = BigInt(mortality.value)
|
||||
// from polkadot-sdk primitives runtime generic era fn decode
|
||||
const encoded = first + (second << 8n)
|
||||
const period = Number(2n << (encoded % (1n << 4n)))
|
||||
const factor = period >> 12 || 1
|
||||
const phase = Number(encoded >> 4n) * factor
|
||||
|
||||
const { period, phase } = decoded
|
||||
// From fn birth
|
||||
const birthBlock = selectedBlockNumber
|
||||
? Math.floor((Math.max(selectedBlockNumber, phase) - phase) / period) *
|
||||
@@ -69,12 +62,8 @@ export const MortalityAnalyzer: FC<{
|
||||
|
||||
return (
|
||||
<div className="space-y-3 rounded-lg border border-foreground/10 bg-background/60 px-3 py-3">
|
||||
<div className="flex flex-wrap items-start justify-between gap-3">
|
||||
<div>
|
||||
<div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-foreground/50">
|
||||
Lifetime
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-foreground/50">
|
||||
Lifetime
|
||||
</div>
|
||||
|
||||
<div className="grid gap-2 sm:grid-cols-2 xl:grid-cols-4">
|
||||
@@ -152,11 +141,7 @@ const Metric: FC<{ label: string; value: string }> = ({ label, value }) => (
|
||||
const formatOptional = (value: number | null) =>
|
||||
value == null ? "N/A" : value.toLocaleString()
|
||||
|
||||
const getTimelineProgress = (
|
||||
start: number,
|
||||
end: number,
|
||||
value: number,
|
||||
): number => {
|
||||
const getTimelineProgress = (start: number, end: number, value: number) => {
|
||||
if (end <= start) return 0
|
||||
const raw = ((value - start) / (end - start)) * 100
|
||||
return Math.max(0, Math.min(100, raw))
|
||||
@@ -167,8 +152,15 @@ export const InlineMortality: FC<{
|
||||
}> = ({ mortality }) => {
|
||||
if (mortality.type === "Immortal") return "Immortal"
|
||||
|
||||
const decoded = decodeMortality(mortality)
|
||||
if (decoded === null) return JSON.stringify(mortality, jsonSerialize)
|
||||
|
||||
return JSON.stringify(decoded) + " " + JSON.stringify(mortality)
|
||||
}
|
||||
|
||||
const decodeMortality = (mortality: { type: string; value: number }) => {
|
||||
const parseResult = /^Mortal(\d+)$/.exec(mortality.type)
|
||||
if (parseResult === null) return JSON.stringify(mortality, jsonSerialize)
|
||||
if (!parseResult) return null
|
||||
|
||||
const first = BigInt(parseResult[1])
|
||||
const second = BigInt(mortality.value)
|
||||
@@ -177,6 +169,5 @@ export const InlineMortality: FC<{
|
||||
const period = Number(2n << (encoded % (1n << 4n)))
|
||||
const factor = period >> 12 || 1
|
||||
const phase = Number(encoded >> 4n) * factor
|
||||
|
||||
return JSON.stringify({ period, phase }) + " " + JSON.stringify(mortality)
|
||||
return { period, phase }
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { TokenAmount } from "@/components/TokenAmount"
|
||||
import { BlockContext } from "@/pages/Explorer/Detail/blockContext"
|
||||
import { BlockContext } from "@/state/block.state"
|
||||
import { client$ } from "@/state/chains/chain.state"
|
||||
import { polkadot_people } from "@polkadot-api/descriptors"
|
||||
import { Binary, HexString } from "polkadot-api"
|
||||
@@ -127,18 +127,12 @@ const getPriority = async (
|
||||
|
||||
try {
|
||||
const [length, weights, queryInfo] = await Promise.all([
|
||||
typedApi.constants.System.BlockLength({
|
||||
at,
|
||||
}),
|
||||
typedApi.constants.System.BlockWeights({
|
||||
at,
|
||||
}),
|
||||
typedApi.constants.System.BlockLength({ at }),
|
||||
typedApi.constants.System.BlockWeights({ at }),
|
||||
typedApi.apis.TransactionPaymentApi.query_info(
|
||||
Binary.fromOpaque(extrinsic),
|
||||
extLength,
|
||||
{
|
||||
at,
|
||||
},
|
||||
{ at },
|
||||
),
|
||||
])
|
||||
|
||||
@@ -176,6 +170,7 @@ const getPriority = async (
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
type PriorityDetails = Awaited<ReturnType<typeof getPriority>>
|
||||
|
||||
const usePriorityAnalysis = ({
|
||||
@@ -192,8 +187,7 @@ const usePriorityAnalysis = ({
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
getPriority(extrinsic, txPayment, blockHex).then((r) => {
|
||||
if (cancelled) return
|
||||
setResult(r)
|
||||
if (!cancelled) setResult(r)
|
||||
})
|
||||
return () => {
|
||||
cancelled = true
|
||||
19
src/components/Extrinsics/Sender.tsx
Normal file
19
src/components/Extrinsics/Sender.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { AccountIdDisplay } from "@/components/AccountIdDisplay"
|
||||
import { Enum, HexString, SS58String } from "polkadot-api"
|
||||
|
||||
const senderToAddress = (
|
||||
sender: Enum<{ Id: SS58String }> | SS58String | HexString,
|
||||
) =>
|
||||
typeof sender === "string"
|
||||
? sender
|
||||
: "type" in sender && sender.type === "Id"
|
||||
? sender.value
|
||||
: null
|
||||
|
||||
export const Sender: React.FC<{
|
||||
sender: Enum<{ Id: SS58String }> | SS58String | HexString
|
||||
}> = ({ sender }) => {
|
||||
const value = senderToAddress(sender)
|
||||
if (!value) return null
|
||||
return value ? <AccountIdDisplay value={value} /> : null
|
||||
}
|
||||
@@ -76,7 +76,7 @@ const ExpandableLine: FC<
|
||||
|
||||
return (
|
||||
<li className="space-y-2 rounded-lg border border-foreground/10 bg-foreground/5 px-3 py-2">
|
||||
<div className="flex gap-2 items-center">
|
||||
<div className="flex items-center gap-2">
|
||||
<ExpandBtn
|
||||
className="shrink-0"
|
||||
expanded={expanded}
|
||||
@@ -84,7 +84,7 @@ const ExpandableLine: FC<
|
||||
/>
|
||||
{id}
|
||||
{inlineContent ? (
|
||||
<div className="max-w-full whitespace-nowrap font-mono text-sm overflow-hidden text-ellipsis">
|
||||
<div className="max-w-full overflow-hidden text-ellipsis whitespace-nowrap font-mono text-sm">
|
||||
- {inlineContent}
|
||||
</div>
|
||||
) : null}
|
||||
@@ -99,12 +99,12 @@ const InlineLine: FC<{ id: string; inlineContent?: ReactNode }> = ({
|
||||
inlineContent,
|
||||
}) => (
|
||||
<li className="flex items-center gap-2 rounded-lg border border-foreground/10 bg-foreground/5 px-3 py-2">
|
||||
<div className="flex gap-2 items-center">
|
||||
<div className="flex items-center gap-2">
|
||||
<Dot size={16} />
|
||||
{id}
|
||||
</div>
|
||||
{inlineContent ? (
|
||||
<div className="max-w-full whitespace-nowrap font-mono text-sm overflow-hidden text-ellipsis">
|
||||
<div className="max-w-full overflow-hidden text-ellipsis whitespace-nowrap font-mono text-sm">
|
||||
- {inlineContent}
|
||||
</div>
|
||||
) : null}
|
||||
4
src/components/Extrinsics/index.ts
Normal file
4
src/components/Extrinsics/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export { MortalityAnalyzer, InlineMortality } from "./MortalityAnalyzer"
|
||||
export { AnalyzePriority, PriorityValue } from "./Priority"
|
||||
export { Sender } from "./Sender"
|
||||
export { SignedExtensions, knownSignedExtensions } from "./SignedExtensions"
|
||||
@@ -2,11 +2,11 @@ import { CircularProgress } from "@/components/CircularProgress"
|
||||
import { CopyText } from "@/components/Copy"
|
||||
import { Link } from "@/hashParams"
|
||||
import { groupBy } from "@/lib/groupBy"
|
||||
import { blockInfoState$ } from "@/state/block.state"
|
||||
import { runtimeCtx$ } from "@/state/chains/chain.state"
|
||||
import { state, useStateObservable } from "@react-rxjs/core"
|
||||
import { FC } from "react"
|
||||
import { map } from "rxjs"
|
||||
import { blockInfoState$ } from "./block.state"
|
||||
import { BlockStatusIcon, statusText } from "./Detail/BlockState"
|
||||
import { filterEvt } from "./events.state"
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import { CopyText } from "@/components/Copy"
|
||||
import { Popover } from "@/components/Popover"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { SearchInput } from "@/components/ui/search-input"
|
||||
import { Link, useNavigate } from "@/hashParams"
|
||||
import { BlockInfo, blocksByHeight$, finalized$ } from "@/state/block.state"
|
||||
import { client$ } from "@/state/chains/chain.state"
|
||||
import { state, useStateObservable } from "@react-rxjs/core"
|
||||
import { Search } from "lucide-react"
|
||||
import { FC } from "react"
|
||||
import { combineLatest, debounceTime, map, switchMap } from "rxjs"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
import { BlockInfo, blocksByHeight$, finalized$ } from "./block.state"
|
||||
import { BlockPopover } from "./BlockPopover"
|
||||
import * as Finalizing from "./FinalizingTable"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { SearchInput } from "@/components/ui/search-input"
|
||||
import { Search } from "lucide-react"
|
||||
|
||||
const best$ = client$.pipeState(
|
||||
switchMap((client) => client.bestBlocks$.pipe(map(([best]) => best))),
|
||||
@@ -174,7 +174,7 @@ export const BlockTable = () => {
|
||||
<button
|
||||
className={twMerge(
|
||||
"overflow-hidden text-ellipsis whitespace-nowrap font-mono text-sm",
|
||||
"text-card-foreground/80 hover:text-card-foreground/100",
|
||||
"text-card-foreground/80 hover:text-card-foreground",
|
||||
row.position === 0
|
||||
? ""
|
||||
: row.block.number > finalized.number
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { blockInfoState$, BlockState, finalized$ } from "@/state/block.state"
|
||||
import { client$ } from "@/state/chains/chain.state"
|
||||
import { Polkadot_people } from "@polkadot-api/descriptors"
|
||||
import {
|
||||
@@ -23,7 +24,6 @@ import {
|
||||
switchMap,
|
||||
take,
|
||||
} from "rxjs"
|
||||
import { blockInfoState$, BlockState, finalized$ } from "../block.state"
|
||||
|
||||
const validatorCache: WeakMap<
|
||||
PolkadotClient,
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Chopsticks } from "@/components/Icons"
|
||||
import { Loading } from "@/components/Loading"
|
||||
import { getHashParams } from "@/hashParams"
|
||||
import { groupBy } from "@/lib/groupBy"
|
||||
import { BlockContext, blockInfoState$ } from "@/state/block.state"
|
||||
import { runtimeCtx$, runtimeCtxAt$ } from "@/state/chains/chain.state"
|
||||
import { Blake2256 } from "@polkadot-api/substrate-bindings"
|
||||
import { getExtrinsicDecoder } from "@polkadot-api/tx-utils"
|
||||
@@ -12,11 +13,9 @@ import { FC, useContext, useState } from "react"
|
||||
import { useLocation } from "react-router-dom"
|
||||
import { catchError, combineLatest, filter, map, take } from "rxjs"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
import { blockInfoState$ } from "../block.state"
|
||||
import { BlockEvents } from "./BlockEvents"
|
||||
import { BlockStorageDiff } from "./BlockStorageDiff"
|
||||
import { ApplyExtrinsicEvent, Extrinsic } from "./Extrinsic"
|
||||
import { BlockContext } from "./blockContext"
|
||||
|
||||
const blockExtrinsics$ = state((hash: string) => {
|
||||
const body$ = blockInfoState$(hash).pipe(
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { Loading } from "@/components/Loading"
|
||||
import { BlockContext, blockInfoState$ } from "@/state/block.state"
|
||||
import { useStateObservable } from "@react-rxjs/core"
|
||||
import { useParams } from "react-router-dom"
|
||||
import { blockInfoState$ } from "../block.state"
|
||||
import { BlockBody } from "./BlockBody"
|
||||
import { BlockInfoView } from "./BlockInfo"
|
||||
import { BlockContext } from "./blockContext"
|
||||
|
||||
export const BlockDetail = () => {
|
||||
const { hashOrHeight } = useParams()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { FC, useState } from "react"
|
||||
import { BlockInfo } from "../block.state"
|
||||
import { BlockInfo } from "@/state/block.state"
|
||||
import { groupBy } from "@/lib/groupBy"
|
||||
import { EventDisplay } from "./Extrinsic"
|
||||
import { SystemEvent } from "@polkadot-api/observable-client"
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import { CopyText } from "@/components/Copy"
|
||||
import { Link } from "@/hashParams"
|
||||
import {
|
||||
BlockContext,
|
||||
blockInfoState$,
|
||||
blocksByHeight$,
|
||||
BlockState,
|
||||
} from "@/state/block.state"
|
||||
import { state, useStateObservable } from "@react-rxjs/core"
|
||||
import { combineKeys } from "@react-rxjs/utils"
|
||||
import { FC, ReactNode, useContext } from "react"
|
||||
import { filter, map, startWith, switchMap, take } from "rxjs"
|
||||
import { blockInfoState$, blocksByHeight$, BlockState } from "../block.state"
|
||||
import { BlockAuthor } from "./BlockAuthor"
|
||||
import { BlockStatusIcon, statusText } from "./BlockState"
|
||||
import { BlockContext } from "./blockContext"
|
||||
|
||||
export const BlockInfoView: FC = () => {
|
||||
const block = useContext(BlockContext)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { ComponentType, FC } from "react"
|
||||
import { BlockState } from "../block.state"
|
||||
import { BlockState } from "@/state/block.state"
|
||||
import {
|
||||
CircleAlert,
|
||||
CircleCheck,
|
||||
@@ -8,6 +7,7 @@ import {
|
||||
Clock,
|
||||
LucideProps,
|
||||
} from "lucide-react"
|
||||
import { ComponentType, FC } from "react"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
||||
const statusIcon: Record<BlockState, ComponentType<LucideProps>> = {
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion"
|
||||
import { groupBy } from "@/lib/groupBy"
|
||||
import { BlockInfo, blockInfo$ } from "@/state/block.state"
|
||||
import { dynamicBuilder$, lookup$ } from "@/state/chains/chain.state"
|
||||
import {
|
||||
HexString,
|
||||
@@ -19,12 +20,11 @@ import {
|
||||
u8,
|
||||
Vector,
|
||||
} from "@polkadot-api/substrate-bindings"
|
||||
import { toHex } from "polkadot-api/utils"
|
||||
import { state, useStateObservable } from "@react-rxjs/core"
|
||||
import { Binary, Codec } from "polkadot-api"
|
||||
import { toHex } from "polkadot-api/utils"
|
||||
import { FC } from "react"
|
||||
import { combineLatest, map } from "rxjs"
|
||||
import { BlockInfo, blockInfo$ } from "../block.state"
|
||||
|
||||
const TWOX128_LEN = 32
|
||||
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
import { CopyBinary } from "@/codec-components/ViewCodec/CopyBinary"
|
||||
import { AccountIdDisplay } from "@/components/AccountIdDisplay"
|
||||
import { CopyText } from "@/components/Copy"
|
||||
import { ExpandBtn } from "@/components/Expand"
|
||||
import {
|
||||
PriorityValue,
|
||||
Sender,
|
||||
SignedExtensions,
|
||||
} from "@/components/Extrinsics"
|
||||
import { JsonDisplay } from "@/components/JsonDisplay"
|
||||
import { Link } from "@/hashParams"
|
||||
import { shortStr } from "@/utils"
|
||||
import { SystemEvent } from "@polkadot-api/observable-client"
|
||||
import { DecodedExtrinsic } from "@polkadot-api/tx-utils"
|
||||
import { Edit, FileSearch } from "lucide-react"
|
||||
import { Enum, HexString, SS58String } from "polkadot-api"
|
||||
import { HexString } from "polkadot-api"
|
||||
import { toHex } from "polkadot-api/utils"
|
||||
import { FC, ReactNode, useEffect, useRef, useState } from "react"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
import { PriorityValue } from "../../Extrinsics/Analyzer/Priority"
|
||||
import { SignedExtensions } from "./SignedExtensions"
|
||||
|
||||
export type ApplyExtrinsicEvent = SystemEvent & {
|
||||
phase: { type: "ApplyExtrinsic" }
|
||||
@@ -73,9 +75,11 @@ export const Extrinsic: FC<{
|
||||
{expanded ? (
|
||||
<div className="space-y-2 border-t border-foreground/10 px-2 py-2">
|
||||
<div className="grid gap-2 lg:grid-cols-[minmax(0,1.25fr)_minmax(0,1fr)_auto]">
|
||||
<CompactBlock label="Signer">
|
||||
<Sender sender={sender} />
|
||||
</CompactBlock>
|
||||
{sender ? (
|
||||
<CompactBlock label="Signer">
|
||||
<Sender sender={sender} />
|
||||
</CompactBlock>
|
||||
) : null}
|
||||
|
||||
<CompactBlock label="Extrinsic Hash">
|
||||
<div className="flex min-w-0 items-center gap-2">
|
||||
@@ -160,23 +164,6 @@ export const EventDisplay: FC<{
|
||||
)
|
||||
}
|
||||
|
||||
const senderToAddress = (
|
||||
sender: Enum<{ Id: SS58String }> | SS58String | HexString,
|
||||
) =>
|
||||
typeof sender === "string"
|
||||
? sender
|
||||
: "type" in sender && sender.type === "Id"
|
||||
? sender.value
|
||||
: null
|
||||
|
||||
export const Sender: React.FC<{
|
||||
sender: Enum<{ Id: SS58String }> | SS58String | HexString
|
||||
}> = ({ sender }) => {
|
||||
const value = senderToAddress(sender)
|
||||
if (!value) return null
|
||||
return <AccountIdDisplay value={value} />
|
||||
}
|
||||
|
||||
const CompactSection: FC<{ title: string; children: ReactNode }> = ({
|
||||
title,
|
||||
children,
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
import { createContext } from "react"
|
||||
import { BlockInfo } from "../block.state"
|
||||
|
||||
export const BlockContext = createContext<BlockInfo | null>(null)
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Popover } from "@/components/Popover"
|
||||
import { Link } from "@/hashParams"
|
||||
import { finalized$ } from "@/state/block.state"
|
||||
import { useStateObservable } from "@react-rxjs/core"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
import { finalized$ } from "./block.state"
|
||||
import { EventPopover } from "./EventPopover"
|
||||
import { eventKey, recentEvents$ } from "./events.state"
|
||||
import * as Finalizing from "./FinalizingTable"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { groupBy } from "@/lib/groupBy"
|
||||
import { blockInfo$, BlockState, recordedBlocks$ } from "@/state/block.state"
|
||||
import type { SystemEvent } from "@polkadot-api/observable-client"
|
||||
import { state } from "@react-rxjs/core"
|
||||
import { combineKeys } from "@react-rxjs/utils"
|
||||
import { filter, map, takeWhile } from "rxjs"
|
||||
import { blockInfo$, BlockState, recordedBlocks$ } from "./block.state"
|
||||
|
||||
const blackList = new Set([
|
||||
"System.*",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { blocksByHeight$ } from "./block.state"
|
||||
import { blocksByHeight$ } from "@/state/block.state"
|
||||
|
||||
export * from "./Explorer"
|
||||
export const explorer$ = blocksByHeight$
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import { CopyBinary } from "@/codec-components/ViewCodec/CopyBinary"
|
||||
import { CopyText } from "@/components/Copy"
|
||||
import {
|
||||
AnalyzePriority,
|
||||
Sender,
|
||||
SignedExtensions,
|
||||
} from "@/components/Extrinsics"
|
||||
import { JsonDisplay } from "@/components/JsonDisplay"
|
||||
import { blockInfoState$ } from "@/pages/Explorer/block.state"
|
||||
import { BlockContext } from "@/pages/Explorer/Detail/blockContext"
|
||||
import { SignedExtensions } from "@/pages/Explorer/Detail/SignedExtensions"
|
||||
import { BlockContext, blockInfoState$ } from "@/state/block.state"
|
||||
import { chainClient$ } from "@/state/chains/chain.state"
|
||||
import { shortStr } from "@/utils"
|
||||
import { getExtrinsicDecoder } from "@polkadot-api/tx-utils"
|
||||
@@ -12,8 +15,6 @@ import { HexString, TxCallData } from "polkadot-api"
|
||||
import { fromHex, toHex } from "polkadot-api/utils"
|
||||
import { FC, ReactNode, useMemo } from "react"
|
||||
import { map, switchMap } from "rxjs"
|
||||
import { Sender } from "../../Explorer/Detail/Extrinsic"
|
||||
import { AnalyzePriority } from "./Priority"
|
||||
import { selectedBlock$, selectedBlockHex$ } from "./selectedBlock"
|
||||
|
||||
const extDecoder$ = selectedBlock$.pipeState(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Spinner } from "@/components/Icons"
|
||||
import { blockHash$ } from "@/state/block.state"
|
||||
import {
|
||||
CachedRuntime,
|
||||
runtimeCtx$,
|
||||
@@ -22,7 +23,6 @@ import {
|
||||
startWith,
|
||||
switchMap,
|
||||
} from "rxjs"
|
||||
import { blockHash$ } from "../Explorer/block.state"
|
||||
|
||||
const [valueChange$, setValue] = createSignal<string>()
|
||||
const inputValue$ = state(valueChange$, "Latest")
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
} from "@/components/ui/tooltip"
|
||||
import { Link } from "@/hashParams"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { BlockState } from "@/state/block.state"
|
||||
import { shortStr } from "@/utils"
|
||||
import { ViewValue } from "@/ViewValue"
|
||||
import { RuntimeContext } from "@polkadot-api/observable-client"
|
||||
@@ -18,9 +19,9 @@ import { Button } from "@polkahub/ui-components"
|
||||
import { useStateObservable } from "@react-rxjs/core"
|
||||
import { ChevronLeft, ChevronRight, StopCircle, Trash2 } from "lucide-react"
|
||||
import { Enum } from "polkadot-api"
|
||||
import { fromHex } from "polkadot-api/utils"
|
||||
import { FC, MouseEvent, ReactNode, useMemo, useState } from "react"
|
||||
import { Virtuoso } from "react-virtuoso"
|
||||
import { BlockState } from "../Explorer/block.state"
|
||||
import { BlockStatusIcon } from "../Explorer/Detail/BlockState"
|
||||
import {
|
||||
KeyCodec,
|
||||
@@ -30,7 +31,6 @@ import {
|
||||
storageSubscriptionKeys$,
|
||||
StorageSubscriptionValue,
|
||||
} from "./storage.state"
|
||||
import { fromHex } from "polkadot-api/utils"
|
||||
|
||||
export const StorageSubscriptions: FC = () => {
|
||||
const keys = useStateObservable(storageSubscriptionKeys$)
|
||||
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
BlockInfo as RawBlockInfo,
|
||||
} from "polkadot-api"
|
||||
import { fromHex } from "polkadot-api/utils"
|
||||
import { createContext } from "react"
|
||||
import {
|
||||
catchError,
|
||||
combineLatest,
|
||||
@@ -61,6 +62,7 @@ export interface BlockInfo {
|
||||
status: BlockState
|
||||
diff: Record<string, [string | null, string | null]> | null
|
||||
}
|
||||
export const BlockContext = createContext<BlockInfo | null>(null)
|
||||
|
||||
const finalizedBlocks$ = state(
|
||||
client$.pipe(
|
||||
Reference in New Issue
Block a user