fix: Sync package-lock.json and fix tests for nostr-tools v2

- Synced `package-lock.json` with `package.json` to resolve `npm ci` failures.
- Updated `nostr-tools` dependencies to resolve conflicts.
- Fixed `SyntaxError` in `tests/nostr-login-permissions.test.mjs` caused by duplicate code.
- Updated `js/nostr/client.js`, `js/nostr/publishHelpers.js`, `js/nostr/adapters/nsecAdapter.js`, `js/nostr/nip46Client.js` to use `hexToBytes` helper when calling `nostr-tools` functions, as v2+ expects `Uint8Array` instead of hex strings.
- Added `hexToBytes` helper in `js/utils/hex.js`.
- Updated tests (`tests/nostr/dm-direct-message-flow.test.mjs`, `tests/nostr-send-direct-message.test.mjs`, `tests/nostr-private-key-signer.test.mjs`, `tests/nostr/nip46Client.test.js`) to use `Uint8Array` for keys where required.

Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
google-labs-jules[bot]andPR0M3TH3AN committed 2026-01-31 19:56:44 +00:00
1 parent 5a5772de3a
commit ffd8f0e23c
12 files changed
+186 -304

No files matched your search

+2 -1
View File
@@ -3,6 +3,7 @@
import { signEventWithPrivateKey } from "../publishHelpers.js";
import { createPrivateKeyCipherClosures } from "../signerHelpers.js";
import { ensureNostrTools, getCachedNostrTools } from "../toolkit.js";
import { hexToBytes } from "../../utils/hex.js";
import { normalizeActorKey } from "../watchHistory.js";
const HEX64_REGEX = /^[0-9a-f]{64}$/i;
@@ -30,7 +31,7 @@ async function resolvePublicKey(privateKey, pubkey) {
const tools = (await ensureNostrTools()) || getCachedNostrTools();
if (tools?.getPublicKey && typeof tools.getPublicKey === "function") {
const derived = tools.getPublicKey(privateKey);
const derived = tools.getPublicKey(hexToBytes(privateKey));
const normalized = normalizeActorKey(derived);
if (normalized && HEX64_REGEX.test(normalized)) {
return normalized;
+7 -6
View File
@@ -130,6 +130,7 @@ import {
summarizeDmEventForLog,
} from "./dmDecryptDiagnostics.js";
import { devLogger, userLogger } from "../utils/logger.js";
import { hexToBytes } from "../utils/hex.js";
import { LRUCache } from "../utils/lruCache.js";
import { updateConversationFromMessage, writeMessages } from "../storage/dmDb.js";
import {
@@ -1629,7 +1630,7 @@ export class NostrClient {
if (!tools || typeof tools.getPublicKey !== "function") {
throw new Error("Public key derivation is unavailable for remote signing.");
}
publicKey = tools.getPublicKey(privateKey);
publicKey = tools.getPublicKey(hexToBytes(privateKey));
}
if (!publicKey || !HEX64_REGEX.test(publicKey)) {
@@ -2275,7 +2276,7 @@ export class NostrClient {
if (!tools || typeof tools.getPublicKey !== "function") {
throw new Error("Public key derivation is unavailable for the remote signer handshake.");
}
clientPublicKey = normalizeNostrPubkey(tools.getPublicKey(clientPrivateKey));
clientPublicKey = normalizeNostrPubkey(tools.getPublicKey(hexToBytes(clientPrivateKey)));
}
if (!clientPublicKey || !HEX64_REGEX.test(clientPublicKey)) {
@@ -3440,7 +3441,7 @@ export class NostrClient {
let pubkey = "";
try {
pubkey = getPublicKey(normalizedPrivateKey);
pubkey = getPublicKey(hexToBytes(normalizedPrivateKey));
} catch (error) {
let retrySuccess = false;
try {
@@ -3551,7 +3552,7 @@ export class NostrClient {
let pubkey = "";
try {
pubkey = getPublicKey(privateKey);
pubkey = getPublicKey(hexToBytes(privateKey));
} catch (error) {
const failure = new Error("Failed to derive the public key.");
failure.cause = error;
@@ -3595,7 +3596,7 @@ export class NostrClient {
throw new Error("Public key derivation is unavailable.");
}
try {
normalizedPubkey = getPublicKey(normalizedPrivateKey);
normalizedPubkey = getPublicKey(hexToBytes(normalizedPrivateKey));
} catch (error) {
const failure = new Error("Failed to derive the public key.");
failure.cause = error;
@@ -3733,7 +3734,7 @@ export class NostrClient {
throw new Error("Public key derivation is unavailable.");
}
try {
normalizedPubkey = getPublicKey(normalizedPrivateKey);
normalizedPubkey = getPublicKey(hexToBytes(normalizedPrivateKey));
} catch (error) {
const failure = new Error("Failed to derive the public key.");
failure.cause = error;
+10 -3
View File
@@ -25,6 +25,7 @@ import {
assertAnyRelayAccepted as defaultAssertAnyRelayAccepted,
} from "../nostrPublish.js";
import { devLogger, userLogger } from "../utils/logger.js";
import { hexToBytes } from "../utils/hex.js";
import { Nip46RequestQueue, NIP46_PRIORITY } from "./nip46Queue.js";
export const HEX64_REGEX = /^[0-9a-f]{64}$/i;
@@ -1071,7 +1072,10 @@ function resolveAvailableNip46Ciphers(
typeof nip44v2GetConversationKey === "function"
) {
registerCipher("nip44.v2", () => {
const conversationKey = nip44v2GetConversationKey(privateKey, remotePubkey);
const conversationKey = nip44v2GetConversationKey(
hexToBytes(privateKey),
remotePubkey,
);
if (!conversationKey) {
throw new Error("Failed to derive a nip44 conversation key for remote signing.");
@@ -1095,7 +1099,10 @@ function resolveAvailableNip46Ciphers(
typeof nip44GetConversationKey === "function"
) {
registerCipher("nip44", () => {
const conversationKey = nip44GetConversationKey(privateKey, remotePubkey);
const conversationKey = nip44GetConversationKey(
hexToBytes(privateKey),
remotePubkey,
);
if (!conversationKey) {
throw new Error("Failed to derive a nip44 conversation key for remote signing.");
@@ -1494,7 +1501,7 @@ export class Nip46RpcClient {
if (!tools || typeof tools.getPublicKey !== "function") {
throw new Error("Public key derivation is unavailable.");
}
this.clientPublicKey = tools.getPublicKey(this.clientPrivateKey);
this.clientPublicKey = tools.getPublicKey(hexToBytes(this.clientPrivateKey));
if (!this.clientPublicKey || !HEX64_REGEX.test(this.clientPublicKey)) {
throw new Error("Failed to derive a valid public key for the remote signer session.");
}
+2 -1
View File
@@ -16,6 +16,7 @@ import {
getCachedNostrTools,
readToolkitFromScope,
} from "./toolkit.js";
import { hexToBytes } from "../utils/hex.js";
import { DEFAULT_NIP07_PERMISSION_METHODS } from "./nip07Permissions.js";
import { devLogger, userLogger } from "../utils/logger.js";
import { logRebroadcastCountFailure } from "./countDiagnostics.js";
@@ -134,7 +135,7 @@ export function signEventWithPrivateKey(event, privateKey) {
throw new Error("Missing signing primitives");
}
const finalized = finalizeFn(prepared, normalizedKey);
const finalized = finalizeFn(prepared, hexToBytes(normalizedKey));
if (
!finalized ||
typeof finalized.id !== "string" ||
+18
View File
@@ -9,3 +9,21 @@ export function normalizeHexString(value) {
export const normalizeHexId = normalizeHexString;
export const normalizeHexPubkey = normalizeHexString;
export function hexToBytes(hex) {
if (typeof hex !== "string") {
throw new TypeError("hexToBytes: expected string, got " + typeof hex);
}
const normalized = hex.trim();
if (normalized.length % 2) throw new Error("hex string must have even length");
const array = new Uint8Array(normalized.length / 2);
for (let i = 0; i < array.length; i++) {
const j = i * 2;
const byte = parseInt(normalized.substring(j, j + 2), 16);
if (Number.isNaN(byte) || byte < 0) {
throw new Error("Invalid hex string");
}
array[i] = byte;
}
return array;
}