mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Add signer registry helpers
This commit is contained in:
1 parent
0ead956fc5
commit
028d1164f9
3 files changed
+217
-26
No files matched your search
+15
-26
@@ -164,6 +164,12 @@ import {
|
||||
} from "./nip46Client.js";
|
||||
import { profileCache } from "../state/profileCache.js";
|
||||
import { createPrivateKeyCipherClosures } from "./signerHelpers.js";
|
||||
import {
|
||||
setActiveSigner as setActiveSignerInRegistry,
|
||||
getActiveSigner as getActiveSignerFromRegistry,
|
||||
clearActiveSigner as clearActiveSignerInRegistry,
|
||||
resolveActiveSigner as resolveActiveSignerFromRegistry,
|
||||
} from "../nostrClientRegistry.js";
|
||||
|
||||
function normalizeProfileFromEvent(event) {
|
||||
if (!event || !event.content) return null;
|
||||
@@ -174,9 +180,6 @@ function normalizeProfileFromEvent(event) {
|
||||
}
|
||||
}
|
||||
|
||||
let activeSigner = null;
|
||||
const activeSignerRegistry = new Map();
|
||||
|
||||
function attachNipMethodAliases(signer) {
|
||||
if (!signer || typeof signer !== "object") {
|
||||
return;
|
||||
@@ -283,45 +286,31 @@ function setActiveSigner(signer) {
|
||||
hydrateExtensionSignerCapabilities(signer);
|
||||
attachNipMethodAliases(signer);
|
||||
|
||||
activeSigner = signer;
|
||||
const pubkey =
|
||||
typeof signer.pubkey === "string" && signer.pubkey.trim()
|
||||
? signer.pubkey.trim().toLowerCase()
|
||||
: "";
|
||||
if (pubkey) {
|
||||
activeSignerRegistry.set(pubkey, signer);
|
||||
profileCache.clearSignerRuntime(pubkey);
|
||||
}
|
||||
|
||||
setActiveSignerInRegistry(signer);
|
||||
}
|
||||
|
||||
function getActiveSigner() {
|
||||
return activeSigner;
|
||||
const signer = getActiveSignerFromRegistry();
|
||||
hydrateExtensionSignerCapabilities(signer);
|
||||
return signer;
|
||||
}
|
||||
|
||||
function clearActiveSigner() {
|
||||
activeSigner = null;
|
||||
activeSignerRegistry.clear();
|
||||
clearActiveSignerInRegistry();
|
||||
}
|
||||
|
||||
function resolveActiveSigner(pubkey) {
|
||||
if (typeof pubkey === "string" && pubkey.trim()) {
|
||||
const normalized = pubkey.trim().toLowerCase();
|
||||
const direct = activeSignerRegistry.get(normalized);
|
||||
if (direct) {
|
||||
hydrateExtensionSignerCapabilities(direct);
|
||||
return direct;
|
||||
}
|
||||
if (
|
||||
activeSigner?.pubkey &&
|
||||
typeof activeSigner.pubkey === "string" &&
|
||||
activeSigner.pubkey.trim().toLowerCase() === normalized
|
||||
) {
|
||||
hydrateExtensionSignerCapabilities(activeSigner);
|
||||
return activeSigner;
|
||||
}
|
||||
}
|
||||
hydrateExtensionSignerCapabilities(activeSigner);
|
||||
return activeSigner;
|
||||
const signer = resolveActiveSignerFromRegistry(pubkey);
|
||||
hydrateExtensionSignerCapabilities(signer);
|
||||
return signer;
|
||||
}
|
||||
|
||||
function shouldRequestExtensionPermissions(signer) {
|
||||
|
||||
@@ -9,3 +9,13 @@ export {
|
||||
nostrClient,
|
||||
requestDefaultExtensionPermissions,
|
||||
} from "./nostr/defaultClient.js";
|
||||
|
||||
export {
|
||||
registerSigner,
|
||||
setActiveSigner,
|
||||
getActiveSigner,
|
||||
resolveActiveSigner,
|
||||
listRegisteredSigners,
|
||||
onActiveSignerChanged,
|
||||
offActiveSignerChanged,
|
||||
} from "./nostrClientRegistry.js";
|
||||
@@ -2,6 +2,77 @@
|
||||
|
||||
let registeredNostrClient = null;
|
||||
let requestPermissionsDelegate = null;
|
||||
const registeredSigners = new Map();
|
||||
let activeSigner = null;
|
||||
let activeSignerPubkey = "";
|
||||
const activeSignerListeners = new Set();
|
||||
|
||||
const globalScope =
|
||||
typeof window !== "undefined"
|
||||
? window
|
||||
: typeof globalThis !== "undefined"
|
||||
? globalThis
|
||||
: null;
|
||||
|
||||
function normalizePubkey(pubkey) {
|
||||
return typeof pubkey === "string" ? pubkey.trim().toLowerCase() : "";
|
||||
}
|
||||
|
||||
function emitSignerEvent(type, detail) {
|
||||
if (!globalScope || typeof globalScope.dispatchEvent !== "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
let event = null;
|
||||
if (typeof globalScope.CustomEvent === "function") {
|
||||
event = new globalScope.CustomEvent(type, { detail });
|
||||
} else if (typeof Event === "function") {
|
||||
event = new Event(type);
|
||||
event.detail = detail;
|
||||
}
|
||||
|
||||
if (event) {
|
||||
globalScope.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
function hasPermissionChanges(previousMeta, nextMeta) {
|
||||
const previous = previousMeta?.permissions ?? null;
|
||||
const next = nextMeta?.permissions ?? null;
|
||||
try {
|
||||
return JSON.stringify(previous) !== JSON.stringify(next);
|
||||
} catch (error) {
|
||||
return previous !== next;
|
||||
}
|
||||
}
|
||||
|
||||
function updateActiveSigner(nextSigner, nextPubkey) {
|
||||
const normalizedPubkey = normalizePubkey(nextPubkey);
|
||||
const previousSigner = activeSigner;
|
||||
const previousPubkey = activeSignerPubkey;
|
||||
|
||||
activeSigner = nextSigner || null;
|
||||
activeSignerPubkey = normalizedPubkey;
|
||||
|
||||
if (
|
||||
previousSigner !== activeSigner ||
|
||||
previousPubkey !== activeSignerPubkey
|
||||
) {
|
||||
const payload = {
|
||||
previousSigner,
|
||||
previousPubkey,
|
||||
signer: activeSigner,
|
||||
pubkey: activeSignerPubkey,
|
||||
};
|
||||
activeSignerListeners.forEach((listener) => {
|
||||
try {
|
||||
listener(payload);
|
||||
} catch (error) {
|
||||
// Intentionally swallow listener errors to avoid breaking signer updates.
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function registerNostrClient(client, options = {}) {
|
||||
registeredNostrClient = client || null;
|
||||
@@ -45,6 +116,127 @@ export function requestDefaultExtensionPermissions(...args) {
|
||||
return Promise.resolve({ ok: false, error });
|
||||
}
|
||||
|
||||
export function registerSigner(pubkey, signer, meta = {}) {
|
||||
const normalized = normalizePubkey(pubkey);
|
||||
if (!normalized) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const previous = registeredSigners.get(normalized) || null;
|
||||
|
||||
if (!signer || typeof signer !== "object") {
|
||||
if (previous) {
|
||||
registeredSigners.delete(normalized);
|
||||
emitSignerEvent("signer:disconnected", {
|
||||
pubkey: normalized,
|
||||
signer: previous.signer,
|
||||
meta: previous.meta,
|
||||
});
|
||||
|
||||
if (activeSignerPubkey === normalized) {
|
||||
updateActiveSigner(null, "");
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const sanitizedMeta =
|
||||
meta && typeof meta === "object" ? { ...meta } : {};
|
||||
|
||||
registeredSigners.set(normalized, { signer, meta: sanitizedMeta });
|
||||
|
||||
if (!previous) {
|
||||
emitSignerEvent("signer:connected", {
|
||||
pubkey: normalized,
|
||||
signer,
|
||||
meta: sanitizedMeta,
|
||||
});
|
||||
} else if (hasPermissionChanges(previous.meta, sanitizedMeta)) {
|
||||
emitSignerEvent("signer:permissions:changed", {
|
||||
pubkey: normalized,
|
||||
signer,
|
||||
previousMeta: previous.meta,
|
||||
meta: sanitizedMeta,
|
||||
});
|
||||
}
|
||||
|
||||
if (activeSignerPubkey === normalized) {
|
||||
updateActiveSigner(signer, normalized);
|
||||
}
|
||||
|
||||
return signer;
|
||||
}
|
||||
|
||||
export function setActiveSigner(signerOrPubkey) {
|
||||
if (!signerOrPubkey) {
|
||||
updateActiveSigner(null, "");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (typeof signerOrPubkey === "string") {
|
||||
const normalized = normalizePubkey(signerOrPubkey);
|
||||
const entry = registeredSigners.get(normalized);
|
||||
updateActiveSigner(entry?.signer || null, normalized);
|
||||
return entry?.signer || null;
|
||||
}
|
||||
|
||||
if (typeof signerOrPubkey === "object") {
|
||||
const pubkey = normalizePubkey(signerOrPubkey.pubkey);
|
||||
if (pubkey) {
|
||||
registerSigner(pubkey, signerOrPubkey);
|
||||
}
|
||||
updateActiveSigner(signerOrPubkey, pubkey);
|
||||
return signerOrPubkey;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function clearActiveSigner() {
|
||||
updateActiveSigner(null, "");
|
||||
}
|
||||
|
||||
export function getActiveSigner() {
|
||||
return activeSigner;
|
||||
}
|
||||
|
||||
export function resolveActiveSigner(pubkey) {
|
||||
const normalized = normalizePubkey(pubkey);
|
||||
if (normalized) {
|
||||
const entry = registeredSigners.get(normalized);
|
||||
if (entry?.signer) {
|
||||
return entry.signer;
|
||||
}
|
||||
if (
|
||||
activeSigner &&
|
||||
typeof activeSigner.pubkey === "string" &&
|
||||
normalizePubkey(activeSigner.pubkey) === normalized
|
||||
) {
|
||||
return activeSigner;
|
||||
}
|
||||
}
|
||||
return activeSigner;
|
||||
}
|
||||
|
||||
export function listRegisteredSigners() {
|
||||
return Array.from(registeredSigners.entries()).map(([pubkey, entry]) => ({
|
||||
pubkey,
|
||||
signer: entry.signer,
|
||||
meta: entry.meta,
|
||||
}));
|
||||
}
|
||||
|
||||
export function onActiveSignerChanged(callback) {
|
||||
if (typeof callback === "function") {
|
||||
activeSignerListeners.add(callback);
|
||||
}
|
||||
}
|
||||
|
||||
export function offActiveSignerChanged(callback) {
|
||||
activeSignerListeners.delete(callback);
|
||||
}
|
||||
|
||||
export const __nostrClientRegistryTestHooks = {
|
||||
clearNostrClientRegistration,
|
||||
clearActiveSigner,
|
||||
};
|
||||
Reference in new issue
Block a user