// Two signing paths: NIP-07 browser extension and NIP-46 remote signer // (covers Primal app + Amber via bunker:// URI). The active signer is held // in module state — there's only one logged-in user at a time. import type { Event as NostrEvent, EventTemplate } from "nostr-tools"; export type SignerKind = "extension" | "bunker"; export type Signer = { kind: SignerKind; getPublicKey(): Promise; signEvent(template: EventTemplate): Promise; }; let activeSigner: Signer | null = null; export function getActiveSigner(): Signer | null { return activeSigner; } export function clearSigner(): void { activeSigner = null; } export async function loginWithExtension(): Promise { if (!window.nostr) { throw new Error("No NIP-07 extension found. Try Alby, nos2x, or Primal extension."); } const ext = window.nostr; const pubkey = await ext.getPublicKey(); activeSigner = { kind: "extension", getPublicKey: async () => pubkey, signEvent: async (template: EventTemplate) => (await ext.signEvent({ kind: template.kind, created_at: template.created_at, tags: template.tags, content: template.content, })) as NostrEvent, }; return pubkey; } export async function loginWithBunker(bunkerUri: string): Promise { // Lazy-load applesauce-signers — only pulled when bunker login is attempted // so the dashboard works for users who only use NIP-07. const mod = await import("applesauce-signers"); const Ctor = (mod as { NostrConnectSigner?: any }).NostrConnectSigner ?? ((mod as { default?: { NostrConnectSigner?: any } }).default?.NostrConnectSigner); if (!Ctor) { throw new Error("applesauce-signers does not expose NostrConnectSigner"); } const fromUri = Ctor.fromBunkerURI ?? Ctor.fromURI; if (!fromUri) { throw new Error("NostrConnectSigner has no fromBunkerURI / fromURI helper"); } const signer = await fromUri.call(Ctor, bunkerUri); const pubkey: string = await signer.getPublicKey(); activeSigner = { kind: "bunker", getPublicKey: async () => pubkey, signEvent: async (template: EventTemplate) => (await signer.signEvent(template)) as NostrEvent, }; return pubkey; }