diff --git a/apps/extension/src/ui/domains/Sign/ViewDetails/ViewDetailsSub.tsx b/apps/extension/src/ui/domains/Sign/ViewDetails/ViewDetailsSub.tsx index 0e29b38747..1c3681366c 100644 --- a/apps/extension/src/ui/domains/Sign/ViewDetails/ViewDetailsSub.tsx +++ b/apps/extension/src/ui/domains/Sign/ViewDetails/ViewDetailsSub.tsx @@ -1,4 +1,6 @@ import { TypeRegistry } from "@polkadot/types" +import { classNames } from "@talismn/util" +import { useQuery } from "@tanstack/react-query" import { FC, useEffect, useMemo } from "react" import { useTranslation } from "react-i18next" import { Button, Drawer } from "talisman-ui" @@ -21,6 +23,19 @@ import { ViewDetailsButton } from "./ViewDetailsButton" import { ViewDetailsField } from "./ViewDetailsField" import { ViewDetailsTxObject } from "./ViewDetailsTxObject" +export const ViewDetailsSub: FC = () => { + const { isOpen, open, close } = useOpenClose() + + return ( + <> + + + + + + ) +} + const ViewDetailsContent: FC<{ onClose: () => void }> = ({ onClose }) => { @@ -75,6 +90,8 @@ const ViewDetailsContent: FC<{ return { methodName, args } }, [extrinsic, t]) + const { data: lifetimeRows } = useLifetimeRows() + useEffect(() => { genericEvent("open sign transaction view details", { type: "substrate" }) }, [genericEvent]) @@ -100,6 +117,16 @@ const ViewDetailsContent: FC<{ token={nativeToken} /> + + {decodedPayload?.nonce.toNumber()} + + + {lifetimeRows?.map((str, i) => ( +
+ {str} +
+ ))} +
{ - const { isOpen, open, close } = useOpenClose() +const useLifetimeRows = () => { + const { t } = useTranslation("request") + const { sapi, payload } = usePolkadotSigningRequest() - return ( - <> - - - - - - ) + const period = useMemo(() => { + try { + if (!isJsonPayload(payload)) return null + + // if blockhash is equal to genesis hash then transaction is immortal + if (payload.genesisHash === payload.blockHash) return null + + const registry = new TypeRegistry() + const ep = registry.createType("ExtrinsicPayload", payload) + + return ep.era.isMortalEra ? ep.era.asMortalEra.period.toNumber() : null + } catch (err) { + return null + } + }, [payload]) + + const mortality = useMemo(() => { + if (!isJsonPayload(payload)) return "" + + // note: for mortal transaction the period is never 0 + if (!period) return t("Immortal") + + const startBlock = parseInt(payload.blockNumber, 16) + return t("From block {{startBlock}} to block {{endBlock}}", { + startBlock, + endBlock: startBlock + period - 1, + }) + }, [payload, period, t]) + + return useQuery({ + queryKey: ["System.Number", sapi?.id], + queryFn: () => { + if (!sapi) return null + return sapi.getStorage("System", "Number", []) + }, + initialData: null, + refetchInterval: 2_000, + select: (blockNumber) => + period ? [mortality, t("Current block: {{blockNumber}}", { blockNumber })] : [mortality], + }) } diff --git a/apps/extension/src/ui/util/scaleApi/sapi.ts b/apps/extension/src/ui/util/scaleApi/sapi.ts index d1246fd1bc..8b2f8ad7fb 100644 --- a/apps/extension/src/ui/util/scaleApi/sapi.ts +++ b/apps/extension/src/ui/util/scaleApi/sapi.ts @@ -73,8 +73,8 @@ export const getScaleApi = ( getConstant: (pallet: string, constant: string) => getConstantValue(chainId, metadata, builder, pallet, constant), - getStorage: (pallet: string, entry: string, keys: unknown[]) => - getStorageValue(chainId, builder, pallet, entry, keys), + getStorage: (pallet: string, entry: string, keys: unknown[], at?: string) => + getStorageValue(chainId, builder, pallet, entry, keys, at), getDecodedCall: (pallet: string, method: string, args: unknown) => getDecodedCall(pallet, method, args), @@ -483,11 +483,12 @@ const getStorageValue = async ( pallet: string, entry: string, keys: unknown[], + at?: string, ) => { const storageCodec = scaleBuilder.buildStorage(pallet, entry) const stateKey = storageCodec.enc(...keys) - const hexValue = await api.subSend(chainId, "state_getStorage", [stateKey]) + const hexValue = await api.subSend(chainId, "state_getStorage", [stateKey, at]) if (!hexValue) return null as T // caller will need to expect null when applicable return storageCodec.dec(hexValue) as T