1- import { useMemo , useState , Fragment } from "react" ;
1+ import { useMemo , useState , Fragment , useEffect } from "react" ;
22import { Box , Tabs , Tab , styled , Skeleton } from "@mui/material" ;
33import { useLocation } from "react-router-dom" ;
4+ import CheckCircleIcon from "@mui/icons-material/CheckCircle" ;
5+ import CancelIcon from "@mui/icons-material/Cancel" ;
46
57import { CopyButton , ExternalModalButton , Tooltip , Typography } from "@atoms" ;
68import {
@@ -23,6 +25,7 @@ import {
2325 getFullGovActionId ,
2426 mapArrayToObjectByKeys ,
2527 encodeCIP129Identifier ,
28+ validateSignature ,
2629} from "@utils" ;
2730import { MetadataValidationStatus , ProposalData } from "@models" ;
2831import { GovernanceActionType } from "@/types/governanceAction" ;
@@ -77,6 +80,7 @@ export const GovernanceActionDetailsCardData = ({
7780 proposal : {
7881 abstract,
7982 authors,
83+ body,
8084 createdDate,
8185 createdEpochNo,
8286 details,
@@ -386,7 +390,21 @@ export const GovernanceActionDetailsCardData = ({
386390 placement = "bottom-end"
387391 arrow
388392 >
389- < span > { author . name } </ span >
393+ < span
394+ style = { {
395+ display : "inline-flex" ,
396+ alignItems : "center" ,
397+ gap : 2 ,
398+ } }
399+ >
400+ < AuthorSignatureStatus
401+ signature = { author . signature }
402+ publicKey = { author . publicKey }
403+ algorithm = { author . witnessAlgorithm }
404+ body = { body }
405+ />
406+ { author . name }
407+ </ span >
390408 </ Tooltip >
391409 { idx < arr . length - 1 && < span > , </ span > }
392410 </ Fragment >
@@ -498,3 +516,48 @@ const HardforkDetailsTabContent = ({
498516 </ Box >
499517 ) ;
500518} ;
519+
520+ const AuthorSignatureStatus = ( {
521+ algorithm,
522+ publicKey,
523+ signature,
524+ body,
525+ } : {
526+ algorithm ?: string ;
527+ publicKey ?: string ;
528+ signature ?: string ;
529+ body ?: string ;
530+ } ) => {
531+ const [ isSignatureValid , setIsSignatureValid ] = useState < boolean | null > (
532+ null ,
533+ ) ;
534+
535+ useEffect ( ( ) => {
536+ let cancelled = false ;
537+ async function checkSignature ( ) {
538+ const args = {
539+ message : body ,
540+ algorithm,
541+ publicKey :
542+ "6A29D3C5C6280FBD9EF17EFFB29F8E8435D404BCF2FCED9336ABAEF1D06B62CB" ,
543+ signature :
544+ "23CFF1D1DA358AF8D835CD2F1F2A972D6E09DA5BD05C08E076017F83FEF1CAC082A853C12E7EA6BB44FC322809E6554ED69302CEE03DF6ABEF2C9D709C0E8906" ,
545+ } ;
546+ const result = await validateSignature ( args ) ;
547+ if ( ! cancelled ) setIsSignatureValid ( result ) ;
548+ }
549+ checkSignature ( ) ;
550+ return ( ) => {
551+ cancelled = true ;
552+ } ;
553+ } , [ algorithm , body , publicKey , signature ] ) ;
554+
555+ if ( isSignatureValid === null ) {
556+ return < Skeleton variant = "text" width = { 16 } /> ;
557+ }
558+ return isSignatureValid ? (
559+ < CheckCircleIcon sx = { { color : "success.main" , fontSize : 16 } } />
560+ ) : (
561+ < CancelIcon sx = { { color : "error.main" , fontSize : 16 } } />
562+ ) ;
563+ } ;
0 commit comments