diff --git a/js/nostr/client.js b/js/nostr/client.js index fe0477aa..666cb82b 100644 --- a/js/nostr/client.js +++ b/js/nostr/client.js @@ -1420,6 +1420,8 @@ export class NostrClient { let generated = null; if (typeof tools.generateSecretKey === "function") { generated = tools.generateSecretKey(); + } else if (typeof tools.generatePrivateKey === "function") { + generated = tools.generatePrivateKey(); } if (generated instanceof Uint8Array) { @@ -1447,7 +1449,27 @@ export class NostrClient { if (!tools || typeof tools.getPublicKey !== "function") { throw new Error("Public key derivation is unavailable for remote signing."); } - publicKey = tools.getPublicKey(privateKey); + try { + publicKey = tools.getPublicKey(privateKey); + } catch (error) { + // Retry with bytes if string input failed (likely nostr-tools v2) + const hexToBytes = + typeof tools.utils?.hexToBytes === "function" + ? tools.utils.hexToBytes + : (hex) => { + if (typeof hex !== "string") return null; + const bytes = new Uint8Array(hex.length / 2); + for (let i = 0; i < hex.length; i += 2) + bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16); + return bytes; + }; + const bytes = hexToBytes(privateKey); + if (bytes) { + publicKey = tools.getPublicKey(bytes); + } else { + throw error; + } + } } if (!publicKey || !HEX64_REGEX.test(publicKey)) { @@ -2777,7 +2799,12 @@ export class NostrClient { let privateKey = ""; try { - if (typeof tools.generatePrivateKey === "function") { + if (typeof tools.generateSecretKey === "function") { + const secret = tools.generateSecretKey(); + if (secret instanceof Uint8Array) { + privateKey = bytesToHex(secret); + } + } else if (typeof tools.generatePrivateKey === "function") { privateKey = tools.generatePrivateKey(); } else if (window?.crypto?.getRandomValues) { const randomBytes = new Uint8Array(32); @@ -2804,8 +2831,28 @@ export class NostrClient { try { pubkey = getPublicKey(normalizedPrivateKey); } catch (error) { - devLogger.warn("[nostr] Failed to derive session pubkey:", error); - return null; + // Retry with bytes if string input failed (likely nostr-tools v2) + try { + const hexToBytes = + typeof tools.utils?.hexToBytes === "function" + ? tools.utils.hexToBytes + : (hex) => { + if (typeof hex !== "string") return null; + const bytes = new Uint8Array(hex.length / 2); + for (let i = 0; i < hex.length; i += 2) + bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16); + return bytes; + }; + const bytes = hexToBytes(normalizedPrivateKey); + if (bytes) { + pubkey = getPublicKey(bytes); + } else { + throw error; + } + } catch (retryError) { + devLogger.warn("[nostr] Failed to derive session pubkey:", error); + return null; + } } const normalizedPubkey = diff --git a/js/ui/applicationBootstrap.js b/js/ui/applicationBootstrap.js index 1447170e..22910063 100644 --- a/js/ui/applicationBootstrap.js +++ b/js/ui/applicationBootstrap.js @@ -392,7 +392,7 @@ export default class ApplicationBootstrap { app.loginModalController = null; app.currentUserNpub = null; - app.initializeLoginModalController({ logIfMissing: true }); + app.initializeLoginModalController({ logIfMissing: false }); app.profileButton = doc?.getElementById("profileButton") || null; app.profileAvatar = doc?.getElementById("profileAvatar") || null; diff --git a/js/ui/profileModalController.js b/js/ui/profileModalController.js index f30a33a9..793f5c93 100644 --- a/js/ui/profileModalController.js +++ b/js/ui/profileModalController.js @@ -1124,6 +1124,7 @@ export class ProfileModalController { this.directMessagesUnsubscribes = []; this.pendingMessagesRender = null; this.messagesStatusClearTimeout = null; + this.lastDirectMessageErrorTime = 0; this.profileHistoryRenderer = null; this.profileHistoryRendererConfig = null; @@ -2417,10 +2418,14 @@ export class ProfileModalController { handleDirectMessagesError(detail = {}) { const error = detail?.error || detail?.failure || detail; - userLogger.warn( - "[profileModal] Direct message sync issue detected:", - error, - ); + const now = Date.now(); + if (now - this.lastDirectMessageErrorTime > 5000) { + userLogger.warn( + "[profileModal] Direct message sync issue detected:", + error, + ); + this.lastDirectMessageErrorTime = now; + } if (this.activeMessagesRequest) { return; diff --git a/js/utils/profileMedia.js b/js/utils/profileMedia.js index 07cb2dfd..bbb48440 100644 --- a/js/utils/profileMedia.js +++ b/js/utils/profileMedia.js @@ -62,6 +62,10 @@ export function sanitizeProfileMediaUrl(value) { return trimmed; } + if (/^images\//i.test(trimmed)) { + return trimmed; + } + if (!/^https?:\/\//i.test(trimmed)) { if (LOCALHOST_PATTERN.test(trimmed)) { trimmed = `http://${trimmed}`;