support general transactions in extrinsic decoder

This commit is contained in:
Victor Oliva
2026-05-07 09:42:39 +02:00
parent b831b2999c
commit e800fe447a
3 changed files with 30 additions and 52 deletions

View File

@@ -1,7 +1,6 @@
import { CopyBinary } from "@/codec-components/ViewCodec/CopyBinary"
import { AccountIdDisplay } from "@/components/AccountIdDisplay"
import { CopyText } from "@/components/Copy"
import { EthAccountDisplay } from "@/components/EthAccountDisplay"
import { ExpandBtn } from "@/components/Expand"
import { JsonDisplay } from "@/components/JsonDisplay"
import { Link } from "@/hashParams"
@@ -43,11 +42,12 @@ export const Extrinsic: FC<{
extrinsic.extra.ChargeTxPayment)
: undefined
let sender = null
if (extrinsic.type === "signed") sender = extrinsic.address
else if (extrinsic.type === "general") {
if (extrinsic.extra?.VerifyMultiSignature?.type === "Signed")
sender = extrinsic.extra.VerifyMultiSignature.value.account
let sender = extrinsic.type === "signed" ? extrinsic.address : null
if (
extrinsic.type === "general" &&
extrinsic.extra.VerifyMultiSignature?.type === "Signed"
) {
sender = extrinsic.extra.VerifyMultiSignature.value.account
}
return (
@@ -73,11 +73,9 @@ 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]">
{extrinsic.type === "signed" ? (
<CompactBlock label="Signer">
<Sender compact sender={sender} />
</CompactBlock>
) : null}
<CompactBlock label="Signer">
<Sender sender={sender} />
</CompactBlock>
<CompactBlock label="Extrinsic Hash">
<div className="flex min-w-0 items-center gap-2">
@@ -162,7 +160,7 @@ export const EventDisplay: FC<{
)
}
export const senderToAddress = (
const senderToAddress = (
sender: Enum<{ Id: SS58String }> | SS58String | HexString,
) =>
typeof sender === "string"
@@ -171,26 +169,12 @@ export const senderToAddress = (
? sender.value
: null
const Sender: React.FC<{
export const Sender: React.FC<{
sender: Enum<{ Id: SS58String }> | SS58String | HexString
compact?: boolean
}> = ({ sender, compact }) => {
}> = ({ sender }) => {
const value = senderToAddress(sender)
return (
value && (
<div
className={
compact ? "flex items-center gap-2" : "flex items-center gap-2 py-2"
}
>
{value.startsWith("0x") ? (
<EthAccountDisplay value={value} />
) : (
<AccountIdDisplay value={value} />
)}
</div>
)
)
if (!value) return null
return <AccountIdDisplay value={value} />
}
const CompactSection: FC<{ title: string; children: ReactNode }> = ({

View File

@@ -1,5 +1,4 @@
import { CopyBinary } from "@/codec-components/ViewCodec/CopyBinary"
import { AccountIdDisplay } from "@/components/AccountIdDisplay"
import { CopyText } from "@/components/Copy"
import { JsonDisplay } from "@/components/JsonDisplay"
import { blockInfoState$ } from "@/pages/Explorer/block.state"
@@ -12,8 +11,8 @@ import { useStateObservable, withDefault } from "@react-rxjs/core"
import { HexString, TxCallData } from "polkadot-api"
import { fromHex, toHex } from "polkadot-api/utils"
import { FC, ReactNode, useMemo } from "react"
import { map, merge, switchMap } from "rxjs"
import { senderToAddress } from "../../Explorer/Detail/Extrinsic"
import { map, switchMap } from "rxjs"
import { Sender } from "../../Explorer/Detail/Extrinsic"
import { AnalyzePriority } from "./Priority"
import { selectedBlock$, selectedBlockHex$ } from "./selectedBlock"
@@ -70,13 +69,19 @@ export const ExtrinsicDecoder: FC<{
}
const decoded = decodeResult.value
const signerAddress =
decoded.type === "signed" ? senderToAddress(decoded.address) : null
const txPayment =
"extra" in decoded
? (decoded.extra.ChargeAssetTxPayment ?? decoded.extra.ChargeTxPayment)
: null
let sender = decoded.type === "signed" ? decoded.address : null
if (
decoded.type === "general" &&
decoded.extra.VerifyMultiSignature?.type === "Signed"
) {
sender = decoded.extra.VerifyMultiSignature.value.account
}
return (
<BlockContext value={block}>
<div className="space-y-4">
@@ -100,34 +105,23 @@ export const ExtrinsicDecoder: FC<{
</div>
</div>
{signerAddress ? (
{sender ? (
<div className="rounded-lg border border-foreground/10 bg-foreground/5 px-3 py-2">
<div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-foreground/50">
Signer
</div>
<div className="mt-1">
<AccountIdDisplay value={signerAddress} />
</div>
<Sender sender={sender} />
</div>
) : null}
</div>
</SectionCard>
<CallData
call={decoded.call as TxCallData}
callData={decoded.callData}
/>
<CallData call={decoded.call} callData={decoded.callData} />
{decoded.type === "signed" ? (
{"extra" in decoded ? (
<SectionCard title="Signed Extensions">
<SignedExtensions extra={decoded.extra} title={false} />
</SectionCard>
) : decoded.type === "general" ? (
<SectionCard>
<div className="text-sm text-muted-foreground">
General transaction analysis is not implemented yet.
</div>
</SectionCard>
) : null}
<SectionCard title="Priority Analysis">
<AnalyzePriority extrinsic={extrinsic} txPayment={txPayment} />

View File

@@ -49,7 +49,7 @@ export const AnalyzePriority: FC<{
<DetailRow label="Class" value={details.queryInfo.class.type} />
<DetailRow
label="Encoded Length"
value={length.toLocaleString()}
value={details.length.toLocaleString()}
/>
<DetailRow
label="Weight"
@@ -122,7 +122,7 @@ const getPriority = async (
const client = await client$.getValue()
const typedApi = client.getTypedApi(polkadot_people)
const extLength = (extrinsic.length - 2) / 8
const extLength = (extrinsic.length - 2) / 2
const tip = txPayment?.tip ?? 0n
try {