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

View File

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

View File

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