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