release #111

Merged
b merged 39 commits from staging into main 2024-07-11 13:42:05 +00:00
3 changed files with 4 additions and 134 deletions
Showing only changes of commit 412da32293 - Show all commits

View File

@ -1,5 +1,3 @@
import { UnsignedEvent } from 'nostr-tools'
export interface SignedEvent { export interface SignedEvent {
kind: number kind: number
tags: string[][] tags: string[][]
@ -14,5 +12,3 @@ export interface NostrJoiningBlock {
block: number block: number
encodedEventPointer: string encodedEventPointer: string
} }
export type Rumor = UnsignedEvent & { id: string }

View File

@ -8,13 +8,12 @@ import {
verifyEvent verifyEvent
} from 'nostr-tools' } from 'nostr-tools'
import { toast } from 'react-toastify' import { toast } from 'react-toastify'
import { MetadataController, NostrController } from '../controllers' import { NostrController } from '../controllers'
import { appPrivateRoutes } from '../routes' import { AuthState } from '../store/auth/types'
import store from '../store/store'
import { CreateSignatureEventContent, Meta } from '../types'
import { hexToNpub, now } from './nostr' import { hexToNpub, now } from './nostr'
import { parseJson } from './string' import { parseJson } from './string'
import { CreateSignatureEventContent, Meta } from '../types'
import store from '../store/store'
import { AuthState } from '../store/auth/types'
/** /**
* Uploads a file to a file storage service. * Uploads a file to a file storage service.
@ -57,128 +56,6 @@ export const uploadToFileStorage = async (
return response.data.url as string return response.data.url as string
} }
/**
* Sends a Direct Message (DM) to a recipient, encrypting the content and handling authentication.
* @param fileUrl The URL of the encrypted zip file to be included in the DM.
* @param encryptionKey The encryption key used to decrypt the zip file to be included in the DM.
* @param pubkey The public key of the recipient.
* @param nostrController The NostrController instance for handling authentication and encryption.
* @param isSigner Boolean indicating whether the recipient is a signer or viewer.
* @param setAuthUrl Function to set the authentication URL in the component state.
*/
export const sendDM = async (
fileUrl: string,
encryptionKey: string,
pubkey: string,
nostrController: NostrController,
isSigner: boolean,
setAuthUrl: (value: React.SetStateAction<string | undefined>) => void
) => {
// Construct the content of the DM
const initialLine = isSigner
? 'Your signature is requested on the document below!'
: 'You have received a signed document.'
const decryptionUrl = `${window.location.origin}/#${
appPrivateRoutes.sign
}?file=${encodeURIComponent(fileUrl)}&key=${encodeURIComponent(
encryptionKey
)}`
const content = `${initialLine}\n\n${decryptionUrl}`
// Set up event listener for authentication event
nostrController.on('nsecbunker-auth', (url) => {
setAuthUrl(url)
})
// Set up timeout promise to handle encryption timeout
const timeoutPromise = new Promise<never>((_, reject) => {
setTimeout(() => {
reject(new Error('Timeout occurred'))
}, 60000) // Timeout duration = 60 seconds
})
// Encrypt the DM content, with timeout
const encrypted = await Promise.race([
nostrController.nip04Encrypt(pubkey, content),
timeoutPromise
])
.then((res) => {
return res
})
.catch((err) => {
console.log('err :>> ', err)
toast.error(
err.message || 'An error occurred while encrypting DM content'
)
return null
})
.finally(() => {
setAuthUrl(undefined) // Clear authentication URL
})
// Return if encryption failed
if (!encrypted) return
// Construct event metadata for the DM
const event: EventTemplate = {
kind: 4, // DM event type
content: encrypted, // Encrypted DM content
created_at: Math.floor(Date.now() / 1000), // Current timestamp
tags: [['p', pubkey]] // Tag with recipient's public key
}
// Sign the DM event
const signedEvent = await nostrController.signEvent(event).catch((err) => {
console.log('err :>> ', err)
toast.error(err.message || 'An error occurred while signing event for DM')
return null
})
// Return if event signing failed
if (!signedEvent) return
// Get relay list metadata
const metadataController = new MetadataController()
const relaySet = await metadataController
.findRelayListMetadata(pubkey)
.catch((err) => {
toast.error(
err.message || 'An error occurred while finding relay list metadata'
)
return null
})
// Return if metadata retrieval failed
if (!relaySet) return
// Ensure relay list is not empty
if (relaySet.read.length === 0) {
toast.error('No relay found for publishing encrypted DM')
return
}
// Publish the signed DM event to the recipient's read relays
await nostrController
.publishEvent(signedEvent, relaySet.read)
.then((relays) => {
toast.success(`Encrypted DM sent on: ${relays.join('\n')}`)
})
.catch((errResults) => {
console.log('err :>> ', errResults)
toast.error('An error occurred while publishing DM')
errResults.forEach((errResult: any) => {
toast.error(
`Publishing to ${errResult.relay} caused the following error: ${errResult.error}`
)
})
return null
})
}
/** /**
* Signs an event for a meta.json file. * Signs an event for a meta.json file.
* @param content contains content for event. * @param content contains content for event.

View File

@ -209,10 +209,7 @@ export const getRoboHashPicture = (
return `https://robohash.org/${npub}.png?set=set${set}` return `https://robohash.org/${npub}.png?set=set${set}`
} }
export const TWO_DAYS = 2 * 24 * 60 * 60
export const now = () => Math.round(Date.now() / 1000) export const now = () => Math.round(Date.now() / 1000)
export const randomNow = () => Math.round(now() - Math.random() * TWO_DAYS)
/** /**
* Generate nip44 conversation key * Generate nip44 conversation key