2024-08-06 10:42:21 +00:00
|
|
|
import { useEffect, useState } from 'react'
|
|
|
|
import { CreateSignatureEventContent, Meta } from '../types'
|
2024-08-12 12:26:03 +00:00
|
|
|
import { Mark } from '../types/mark'
|
|
|
|
import {
|
|
|
|
parseCreateSignatureEvent,
|
|
|
|
parseCreateSignatureEventContent,
|
|
|
|
SigitMetaParseError,
|
|
|
|
SigitStatus,
|
|
|
|
SignStatus
|
|
|
|
} from '../utils'
|
|
|
|
import { toast } from 'react-toastify'
|
|
|
|
import { verifyEvent } from 'nostr-tools'
|
2024-08-06 10:42:21 +00:00
|
|
|
import { Event } from 'nostr-tools'
|
|
|
|
|
2024-08-12 12:26:03 +00:00
|
|
|
interface FlatMeta extends Meta, CreateSignatureEventContent, Partial<Event> {
|
|
|
|
// Validated create signature event
|
|
|
|
isValid: boolean
|
2024-08-07 12:15:20 +00:00
|
|
|
|
2024-08-12 12:26:03 +00:00
|
|
|
// Calculated status fields
|
|
|
|
signedStatus: SigitStatus
|
|
|
|
signersStatus: {
|
|
|
|
[signer: `npub1${string}`]: SignStatus
|
2024-08-07 12:15:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-12 12:26:03 +00:00
|
|
|
/**
|
|
|
|
* Custom use hook for parsing the Sigit Meta
|
|
|
|
* @param meta Sigit Meta
|
|
|
|
* @returns flattened Meta object with calculated signed status
|
|
|
|
*/
|
|
|
|
export const useSigitMeta = (meta: Meta): FlatMeta => {
|
|
|
|
const [isValid, setIsValid] = useState(false)
|
|
|
|
const [kind, setKind] = useState<number>()
|
|
|
|
const [tags, setTags] = useState<string[][]>()
|
|
|
|
const [created_at, setCreatedAt] = useState<number>()
|
|
|
|
const [pubkey, setPubkey] = useState<string>() // submittedBy, pubkey from nostr event
|
|
|
|
const [id, setId] = useState<string>()
|
|
|
|
const [sig, setSig] = useState<string>()
|
|
|
|
|
|
|
|
const [signers, setSigners] = useState<`npub1${string}`[]>([])
|
|
|
|
const [viewers, setViewers] = useState<`npub1${string}`[]>([])
|
|
|
|
const [fileHashes, setFileHashes] = useState<{
|
|
|
|
[user: `npub1${string}`]: string
|
|
|
|
}>({})
|
|
|
|
const [markConfig, setMarkConfig] = useState<Mark[]>([])
|
|
|
|
const [title, setTitle] = useState<string>('')
|
|
|
|
const [zipUrl, setZipUrl] = useState<string>('')
|
|
|
|
|
|
|
|
const [signedStatus, setSignedStatus] = useState<SigitStatus>(
|
|
|
|
SigitStatus.Partial
|
2024-08-06 10:42:21 +00:00
|
|
|
)
|
2024-08-12 12:26:03 +00:00
|
|
|
const [signersStatus, setSignersStatus] = useState<{
|
|
|
|
[signer: `npub1${string}`]: SignStatus
|
|
|
|
}>({})
|
2024-08-06 10:42:21 +00:00
|
|
|
|
|
|
|
useEffect(() => {
|
2024-08-12 12:26:03 +00:00
|
|
|
if (!meta) return
|
|
|
|
;(async function () {
|
|
|
|
try {
|
|
|
|
const createSignatureEvent = await parseCreateSignatureEvent(
|
|
|
|
meta.createSignature
|
|
|
|
)
|
|
|
|
|
|
|
|
const { kind, tags, created_at, pubkey, id, sig, content } =
|
|
|
|
createSignatureEvent
|
|
|
|
|
|
|
|
setIsValid(verifyEvent(createSignatureEvent))
|
|
|
|
setKind(kind)
|
|
|
|
setTags(tags)
|
|
|
|
// created_at in nostr events are stored in seconds
|
|
|
|
setCreatedAt(created_at * 1000)
|
|
|
|
setPubkey(pubkey)
|
|
|
|
setId(id)
|
|
|
|
setSig(sig)
|
|
|
|
|
|
|
|
const { title, signers, viewers, fileHashes, markConfig, zipUrl } =
|
|
|
|
await parseCreateSignatureEventContent(content)
|
|
|
|
|
|
|
|
setTitle(title)
|
|
|
|
setSigners(signers)
|
|
|
|
setViewers(viewers)
|
|
|
|
setFileHashes(fileHashes)
|
|
|
|
setMarkConfig(markConfig)
|
|
|
|
setZipUrl(zipUrl)
|
|
|
|
|
|
|
|
// Parse each signature event and set signer status
|
|
|
|
for (const npub in meta.docSignatures) {
|
|
|
|
try {
|
|
|
|
const event = await parseCreateSignatureEvent(
|
|
|
|
meta.docSignatures[npub as `npub1${string}`]
|
|
|
|
)
|
|
|
|
const isValidSignature = verifyEvent(event)
|
|
|
|
setSignersStatus((prev) => {
|
|
|
|
return {
|
|
|
|
...prev,
|
|
|
|
[npub]: isValidSignature
|
|
|
|
? SignStatus.Signed
|
|
|
|
: SignStatus.Invalid
|
|
|
|
}
|
|
|
|
})
|
|
|
|
} catch (error) {
|
|
|
|
setSignersStatus((prev) => {
|
|
|
|
return {
|
|
|
|
...prev,
|
|
|
|
[npub]: SignStatus.Invalid
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const signedBy = Object.keys(meta.docSignatures) as `npub1${string}`[]
|
|
|
|
const isCompletelySigned = signers.every((signer) =>
|
|
|
|
signedBy.includes(signer)
|
|
|
|
)
|
|
|
|
setSignedStatus(
|
|
|
|
isCompletelySigned ? SigitStatus.Complete : SigitStatus.Partial
|
|
|
|
)
|
|
|
|
} catch (error) {
|
|
|
|
if (error instanceof SigitMetaParseError) {
|
|
|
|
toast.error(error.message)
|
|
|
|
}
|
|
|
|
console.error(error)
|
|
|
|
}
|
|
|
|
})()
|
2024-08-06 10:42:21 +00:00
|
|
|
}, [meta])
|
|
|
|
|
|
|
|
return {
|
2024-08-12 12:26:03 +00:00
|
|
|
modifiedAt: meta.modifiedAt,
|
|
|
|
createSignature: meta.createSignature,
|
|
|
|
docSignatures: meta.docSignatures,
|
|
|
|
keys: meta.keys,
|
|
|
|
isValid,
|
|
|
|
kind,
|
|
|
|
tags,
|
|
|
|
created_at,
|
|
|
|
pubkey,
|
|
|
|
id,
|
|
|
|
sig,
|
2024-08-06 10:42:21 +00:00
|
|
|
signers,
|
2024-08-12 12:26:03 +00:00
|
|
|
viewers,
|
|
|
|
fileHashes,
|
|
|
|
markConfig,
|
|
|
|
title,
|
|
|
|
zipUrl,
|
2024-08-06 10:42:21 +00:00
|
|
|
signedStatus,
|
2024-08-12 12:26:03 +00:00
|
|
|
signersStatus
|
2024-08-06 10:42:21 +00:00
|
|
|
}
|
|
|
|
}
|