Merge pull request #918 from PR0M3TH3AN/codex/fix-maxlistenersexceededwarning-errors

Hydrate extension signer capabilities for edits
This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2025-10-26 11:23:30 -04:00
commit 4e401b1f5a
2 files changed
+68

No files matched your search

+30
View File
@@ -211,11 +211,38 @@ function attachNipMethodAliases(signer) {
}
}
function hydrateExtensionSignerCapabilities(signer) {
if (!signer || typeof signer !== "object" || signer.type !== "extension") {
return;
}
const extension =
typeof window !== "undefined" && window && window.nostr ? window.nostr : null;
if (!extension) {
return;
}
if (typeof signer.signEvent !== "function" && extension.signEvent) {
if (typeof extension.signEvent === "function") {
signer.signEvent = extension.signEvent.bind(extension);
}
}
if (!signer.nip04 && extension.nip04) {
signer.nip04 = extension.nip04;
}
if (!signer.nip44 && extension.nip44) {
signer.nip44 = extension.nip44;
}
}
function setActiveSigner(signer) {
if (!signer || typeof signer !== "object") {
return;
}
hydrateExtensionSignerCapabilities(signer);
attachNipMethodAliases(signer);
activeSigner = signer;
@@ -242,6 +269,7 @@ function resolveActiveSigner(pubkey) {
const normalized = pubkey.trim().toLowerCase();
const direct = activeSignerRegistry.get(normalized);
if (direct) {
hydrateExtensionSignerCapabilities(direct);
return direct;
}
if (
@@ -249,9 +277,11 @@ function resolveActiveSigner(pubkey) {
typeof activeSigner.pubkey === "string" &&
activeSigner.pubkey.trim().toLowerCase() === normalized
) {
hydrateExtensionSignerCapabilities(activeSigner);
return activeSigner;
}
}
hydrateExtensionSignerCapabilities(activeSigner);
return activeSigner;
}
+38
View File
@@ -0,0 +1,38 @@
import test from "node:test";
import assert from "node:assert/strict";
const {
setActiveSigner,
resolveActiveSigner,
clearActiveSigner,
} = await import("../../js/nostr.js");
test("setActiveSigner hydrates extension capabilities from window.nostr", async () => {
clearActiveSigner();
const originalWindow = globalThis.window;
const signEvent = async (event) => ({ ...event, id: "signed", sig: "sig" });
const extension = {
signEvent,
nip04: { encrypt: () => "cipher", decrypt: () => "plain" },
nip44: { encrypt: () => "cipher44", decrypt: () => "plain44" },
};
globalThis.window = { nostr: extension };
try {
setActiveSigner({ type: "extension", pubkey: "deadbeef" });
const signer = resolveActiveSigner("deadbeef");
assert.ok(signer, "signer should be returned");
assert.equal(typeof signer.signEvent, "function", "signEvent should be hydrated");
const result = await signer.signEvent({ pubkey: "deadbeef", kind: 1, content: "" });
assert.equal(result.id, "signed", "hydrated signEvent should be used");
assert.equal(typeof signer.nip04Encrypt, "function", "nip04 alias should be attached");
assert.equal(typeof signer.nip44Encrypt, "function", "nip44 alias should be attached");
} finally {
clearActiveSigner();
if (originalWindow === undefined) {
delete globalThis.window;
} else {
globalThis.window = originalWindow;
}
}
});