123 lines
No EOL
3.5 KiB
TypeScript
123 lines
No EOL
3.5 KiB
TypeScript
import type { NostrEvent, NostrRelayConfig } from '../types/nostr'
|
|
|
|
declare global {
|
|
interface Window {
|
|
NostrTools: {
|
|
getPublicKey: (privkey: string) => string
|
|
generatePrivateKey: () => string
|
|
nip04: {
|
|
encrypt: (privkey: string, pubkey: string, content: string) => Promise<string>
|
|
decrypt: (privkey: string, pubkey: string, content: string) => Promise<string>
|
|
}
|
|
getEventHash: (event: NostrEvent) => string
|
|
signEvent: (event: NostrEvent, privkey: string) => Promise<string>
|
|
getSignature: (event: NostrEvent, privkey: string) => string
|
|
verifySignature: (event: NostrEvent) => boolean
|
|
nip19: {
|
|
decode: (str: string) => { type: string; data: string }
|
|
npubEncode: (hex: string) => string
|
|
}
|
|
relayInit: (url: string) => {
|
|
connect: () => Promise<void>
|
|
sub: (filters: any[]) => {
|
|
on: (event: string, callback: (event: NostrEvent) => void) => void
|
|
}
|
|
publish: (event: NostrEvent) => {
|
|
on: (type: 'ok' | 'failed', cb: (msg?: string) => void) => void
|
|
}
|
|
close: () => void
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export async function connectToRelay(url: string) {
|
|
const relay = window.NostrTools.relayInit(url)
|
|
try {
|
|
await relay.connect()
|
|
return relay
|
|
} catch (err) {
|
|
console.error(`Failed to connect to ${url}:`, err)
|
|
return null
|
|
}
|
|
}
|
|
|
|
export async function publishEvent(event: NostrEvent, relays: NostrRelayConfig[]) {
|
|
const connectedRelays = await Promise.all(
|
|
relays.map(relay => connectToRelay(relay.url))
|
|
)
|
|
|
|
const activeRelays = connectedRelays.filter(relay => relay !== null)
|
|
|
|
return Promise.all(
|
|
activeRelays.map(relay =>
|
|
new Promise((resolve) => {
|
|
const pub = relay.publish(event)
|
|
pub.on('ok', () => {
|
|
resolve(true)
|
|
})
|
|
pub.on('failed', () => {
|
|
resolve(false)
|
|
})
|
|
})
|
|
)
|
|
)
|
|
}
|
|
|
|
export async function encryptMessage(privkey: string, pubkey: string, content: string): Promise<string> {
|
|
return await window.NostrTools.nip04.encrypt(privkey, pubkey, content)
|
|
}
|
|
|
|
export async function decryptMessage(privkey: string, pubkey: string, content: string): Promise<string> {
|
|
return await window.NostrTools.nip04.decrypt(privkey, pubkey, content)
|
|
}
|
|
|
|
export function generatePrivateKey(): string {
|
|
return window.NostrTools.generatePrivateKey()
|
|
}
|
|
|
|
export function getPublicKey(privateKey: string): string {
|
|
return window.NostrTools.getPublicKey(privateKey)
|
|
}
|
|
|
|
export function getEventHash(event: NostrEvent): string {
|
|
return window.NostrTools.getEventHash(event)
|
|
}
|
|
|
|
export async function signEvent(event: NostrEvent, privateKey: string): Promise<string> {
|
|
return window.NostrTools.getSignature(event, privateKey)
|
|
}
|
|
|
|
export function verifySignature(event: NostrEvent): boolean {
|
|
return window.NostrTools.verifySignature(event)
|
|
}
|
|
|
|
export function npubToHex(npub: string): string {
|
|
try {
|
|
const { type, data } = window.NostrTools.nip19.decode(npub)
|
|
if (type !== 'npub') throw new Error('Invalid npub')
|
|
return data
|
|
} catch (err) {
|
|
console.error('Failed to decode npub:', err)
|
|
throw err
|
|
}
|
|
}
|
|
|
|
export function hexToNpub(hex: string): string {
|
|
return window.NostrTools.nip19.npubEncode(hex)
|
|
}
|
|
|
|
export function isValidPrivateKey(key: string): boolean {
|
|
try {
|
|
if (!/^[0-9a-fA-F]{64}$/.test(key)) {
|
|
return false
|
|
}
|
|
return true
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
|
|
export function formatPrivateKey(key: string): string {
|
|
return key.trim().toLowerCase()
|
|
}
|