import { type WorkQueueItem, processWorkQueue, barrierQueue, unwrap } from "@snort/shared" import type { EventSigner, NostrEvent } from ".." const Nip7Queue: Array = [] processWorkQueue(Nip7Queue) declare global { interface NostrEncryptor { encrypt(recipientHexPubKey: string, value: string): Promise decrypt(senderHexPubKey: string, value: string): Promise } interface Window { nostr?: { getPublicKey: () => Promise signEvent: (ev: NostrEvent) => Promise nip04?: NostrEncryptor nip44?: NostrEncryptor } } } export class Nip7Signer implements EventSigner { get supports(): string[] { const supports = ["nip04"] if (window.nostr && "nip44" in window.nostr) { supports.push("nip44") } return supports } init(): Promise { return Promise.resolve() } async getPubKey(): Promise { if (!window.nostr) { throw new Error("Cannot use NIP-07 signer, not found!") } return await barrierQueue(Nip7Queue, () => unwrap(window.nostr).getPublicKey()) } async nip4Encrypt(content: string, key: string): Promise { if (!window.nostr) { throw new Error("Cannot use NIP-07 signer, not found!") } return await barrierQueue(Nip7Queue, () => unwrap(window.nostr?.nip04?.encrypt).call(window.nostr?.nip04, key, content), ) } async nip4Decrypt(content: string, otherKey: string): Promise { if (!window.nostr) { throw new Error("Cannot use NIP-07 signer, not found!") } return await barrierQueue(Nip7Queue, () => unwrap(window.nostr?.nip04?.decrypt).call(window.nostr?.nip04, otherKey, content), ) } async nip44Encrypt(content: string, key: string): Promise { if (!window.nostr) { throw new Error("Cannot use NIP-07 signer, not found!") } return await barrierQueue(Nip7Queue, async () => { const nostr = globalThis.window.nostr if (!nostr) throw new Error("Nostr signer not found") return await nostr.nip44!.encrypt(key, content) }) } async nip44Decrypt(content: string, otherKey: string): Promise { if (!window.nostr) { throw new Error("Cannot use NIP-07 signer, not found!") } return await barrierQueue(Nip7Queue, async () => { const nostr = globalThis.window.nostr if (!nostr) throw new Error("Nostr signer not found") return await nostr.nip44!.decrypt(otherKey, content) }) } async sign(ev: NostrEvent): Promise { if (!window.nostr) { throw new Error("Cannot use NIP-07 signer, not found!") } return await barrierQueue(Nip7Queue, async () => { const signed = await unwrap(window.nostr).signEvent(ev) return { ...ev, id: signed.id, sig: signed.sig, } }) } }