import {StampedEvent} from '@welshman/util' import {hash, own, Sign, ISigner, EncryptionImplementation} from '../util' export type Nip07 = { signEvent: Sign nip04: EncryptionImplementation nip44: EncryptionImplementation getPublicKey: () => string | undefined } export const getNip07 = () => (window as {nostr?: Nip07}).nostr export class Nip07Signer implements ISigner { #lock = Promise.resolve() #then = async (f: (ext: Nip07) => T | Promise) => { const promise = this.#lock.then(() => { const ext = getNip07() if (!ext) throw new Error("Nip07 is not enabled") return f(ext) }) // Recover from errors this.#lock = promise.then(() => undefined, () => undefined) return promise } getPubkey = async () => getNip07()!.getPublicKey()! sign = async (template: StampedEvent) => { const event = hash(own(template, await this.getPubkey())) return this.#then(ext => ext.signEvent(event)) } nip04 = { encrypt: (pubkey: string, message: string) => this.#then(ext => ext.nip04.encrypt(pubkey, message)), decrypt: (pubkey: string, message: string) => this.#then(ext => ext.nip04.decrypt(pubkey, message)), } nip44 = { encrypt: (pubkey: string, message: string) => this.#then(ext => ext.nip44.encrypt(pubkey, message)), decrypt: (pubkey: string, message: string) => this.#then(ext => ext.nip44.decrypt(pubkey, message)), } }