issue-166-open-timestamps #220

Merged
eugene merged 25 commits from issue-166-open-timestamps into staging 2024-10-25 11:18:47 +00:00
3 changed files with 35 additions and 32 deletions
Showing only changes of commit 07f1a15aa1 - Show all commits

View File

@ -20,7 +20,7 @@ import {
CreateSignatureEventContent,
Meta,
ProfileMetadata,
Timestamp,
SignedEvent,
User,
UserRole
} from '../../types'
@ -62,7 +62,7 @@ import {
faUpload
} from '@fortawesome/free-solid-svg-icons'
import { SigitFile } from '../../utils/file.ts'
import { generateTimestamps } from '../../utils/opentimestamps.ts'
import { generateTimestamp } from '../../utils/opentimestamps.ts'
export const CreatePage = () => {
const navigate = useNavigate()
@ -560,8 +560,7 @@ export const CreatePage = () => {
fileHashes: {
[key: string]: string
},
zipUrl: string,
timestamps?: Timestamp[]
zipUrl: string
) => {
const content: CreateSignatureEventContent = {
signers: signers.map((signer) => hexToNpub(signer.pubkey)),
@ -569,8 +568,7 @@ export const CreatePage = () => {
fileHashes,
markConfig,
zipUrl,
title,
...(timestamps && { timestamps })
title
}
setLoadingSpinnerDesc('Signing nostr event for create signature')
@ -602,6 +600,11 @@ export const CreatePage = () => {
return receivers.map((receiver) => sendNotification(receiver, meta))
}
const extractNostrId = (stringifiedEvent: string): string => {
const e = JSON.parse(stringifiedEvent) as SignedEvent
return e.id
}
const handleCreate = async () => {
try {
if (!validateInputs()) return
@ -611,10 +614,6 @@ export const CreatePage = () => {
const fileHashes = await generateFileHashes()
if (!fileHashes) return
setLoadingSpinnerDesc('Timestamping your files')
const timestamps = await generateTimestamps(Object.values(fileHashes))
if (!timestamps) return
setLoadingSpinnerDesc('Generating encryption key')
const encryptionKey = await generateEncryptionKey()
@ -639,8 +638,7 @@ export const CreatePage = () => {
const createSignature = await generateCreateSignature(
markConfig,
fileHashes,
fileUrl,
timestamps
fileUrl
)
if (!createSignature) return
@ -656,6 +654,10 @@ export const CreatePage = () => {
const keys = await generateKeys(pubkeys, encryptionKey)
if (!keys) return
const timestamp = await generateTimestamp(
extractNostrId(createSignature)
)
const meta: Meta = {
createSignature,
keys,
@ -663,6 +665,10 @@ export const CreatePage = () => {
docSignatures: {}
}
if (timestamp) {
meta.timestamps = [timestamp]
}
setLoadingSpinnerDesc('Updating user app data')
const event = await updateUsersAppData(meta)
if (!event) return

View File

@ -18,6 +18,7 @@ export interface Meta {
docSignatures: { [key: `npub1${string}`]: string }
exportSignature?: string
keys?: { sender: string; keys: { [user: `npub1${string}`]: string } }
timestamps?: Timestamp[]
}
export interface CreateSignatureEventContent {
@ -27,13 +28,11 @@ export interface CreateSignatureEventContent {
markConfig: Mark[]
title: string
zipUrl: string
timestamps?: Timestamp[]
}
export interface SignedEventContent {
prevSig: string
marks: Mark[]
timestamps: Timestamp[]
}
export interface Sigit {
@ -42,7 +41,7 @@ export interface Sigit {
}
export interface Timestamp {
fileHash: string
nostrId: string
timestamp: string
}

View File

@ -1,28 +1,26 @@
import { Timestamp } from '../types'
import { isPromiseFulfilled } from './utils.ts'
import { retryAll } from './retry.ts'
import { retry } from './retry.ts'
import { bytesToHex, hexToBytes } from '@noble/hashes/utils'
/**
* Generates a timestamp for the provided document hashes.
* @returns Timestamp in a hex string format
* Generates a timestamp for the provided nostr event ID.
* @returns Timestamp with its value and the nostr event ID.
*/
export const generateTimestamps = async (
fileHashes: string[]
): Promise<Timestamp[] | undefined> => {
const promises = fileHashes.map((fileHash) => () => timestamp(fileHash))
const resolvedPromises = await retryAll(promises)
if (resolvedPromises.every(isPromiseFulfilled)) {
return resolvedPromises.map(({ value }, index) => {
export const generateTimestamp = async (
nostrId: string
): Promise<Timestamp | undefined> => {
try {
return {
fileHash: fileHashes[index],
timestamp: value
timestamp: await retry(() => timestamp(nostrId)),
nostrId: nostrId
}
})
} catch (error) {
console.error(error)
return
}
}
const timestamp = async (hash: string) => {
const timestamp = async (hash: string): Promise<string> => {
const detachedTimestamp =
window.OpenTimestamps.DetachedTimestampFile.fromHash(
new window.OpenTimestamps.Ops.OpSHA256(),