fix: nostr-tools v2 compatibility and null kind handling

- Fix compatibility with nostr-tools v2 which changed nip19 encoding/decoding
  to use Uint8Array instead of hex strings
- Add hex utility functions (bytesToHex, hexToBytes) for conversion
- Fix null kind handling in create_new_policy to prevent database errors
  when policy rules have no kind specified
- Default method to "sign_event" when not specified in policy rules
- Bump version to 0.10.6

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
tcheeric 2025-11-26 02:38:18 +00:00
parent f4fd7403cc
commit deda485763
6 changed files with 31 additions and 11 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "nsecbunkerd", "name": "nsecbunkerd",
"version": "0.10.5", "version": "0.10.6",
"description": "nsecbunker daemon", "description": "nsecbunker daemon",
"main": "dist/index.js", "main": "dist/index.js",
"bin": { "bin": {
@ -39,7 +39,7 @@
"@fastify/view": "^8.2.0", "@fastify/view": "^8.2.0",
"@inquirer/password": "^1.1.2", "@inquirer/password": "^1.1.2",
"@inquirer/prompts": "^1.2.3", "@inquirer/prompts": "^1.2.3",
"@nostr-dev-kit/ndk": "workspace:*", "@nostr-dev-kit/ndk": "^2.18.1",
"@prisma/client": "^5.4.1", "@prisma/client": "^5.4.1",
"@scure/base": "^1.1.1", "@scure/base": "^1.1.1",
"@types/yargs": "^17.0.24", "@types/yargs": "^17.0.24",
@ -57,7 +57,7 @@
"isomorphic-ws": "^5.0.0", "isomorphic-ws": "^5.0.0",
"lnbits": "^1.1.5", "lnbits": "^1.1.5",
"lnbits-ts": "^0.0.2", "lnbits-ts": "^0.0.2",
"nostr-tools": "^1.17.0", "nostr-tools": "^2.17.0",
"websocket-polyfill": "^0.0.3", "websocket-polyfill": "^0.0.3",
"ws": "^8.13.0", "ws": "^8.13.0",
"yargs": "^17.7.2" "yargs": "^17.7.2"

View File

@ -1,6 +1,7 @@
import { Hexpubkey, NDKKind, NDKPrivateKeySigner, NDKRpcRequest, NDKUserProfile } from "@nostr-dev-kit/ndk"; import { Hexpubkey, NDKKind, NDKPrivateKeySigner, NDKRpcRequest, NDKUserProfile } from "@nostr-dev-kit/ndk";
import AdminInterface from ".."; import AdminInterface from "..";
import { nip19 } from 'nostr-tools'; import { nip19 } from 'nostr-tools';
import { hexToBytes } from "../../../utils/hex.js";
import { setupSkeletonProfile } from "../../lib/profile"; import { setupSkeletonProfile } from "../../lib/profile";
import { IConfig, getCurrentConfig, saveCurrentConfig } from "../../../config"; import { IConfig, getCurrentConfig, saveCurrentConfig } from "../../../config";
import { readFileSync, writeFileSync } from "fs"; import { readFileSync, writeFileSync } from "fs";
@ -195,7 +196,7 @@ export async function createAccountReal(
} }
const keyName = nip05; const keyName = nip05;
const nsec = nip19.nsecEncode(key.privateKey!); const nsec = nip19.nsecEncode(hexToBytes(key.privateKey!));
currentConfig.keys[keyName] = { key: key.privateKey }; currentConfig.keys[keyName] = { key: key.privateKey };
saveCurrentConfig(admin.configFile, currentConfig); saveCurrentConfig(admin.configFile, currentConfig);

View File

@ -3,6 +3,7 @@ import AdminInterface from "../index.js";
import { saveEncrypted } from "../../../commands/add.js"; import { saveEncrypted } from "../../../commands/add.js";
import { nip19 } from 'nostr-tools'; import { nip19 } from 'nostr-tools';
import { setupSkeletonProfile } from "../../lib/profile.js"; import { setupSkeletonProfile } from "../../lib/profile.js";
import { bytesToHex, hexToBytes } from "../../../utils/hex.js";
export default async function createNewKey(admin: AdminInterface, req: NDKRpcRequest) { export default async function createNewKey(admin: AdminInterface, req: NDKRpcRequest) {
const [ keyName, passphrase, _nsec ] = req.params as [ string, string, string? ]; const [ keyName, passphrase, _nsec ] = req.params as [ string, string, string? ];
@ -13,7 +14,7 @@ export default async function createNewKey(admin: AdminInterface, req: NDKRpcReq
let key; let key;
if (_nsec) { if (_nsec) {
key = new NDKPrivateKeySigner(nip19.decode(_nsec).data as string); key = new NDKPrivateKeySigner(bytesToHex(nip19.decode(_nsec).data as Uint8Array));
} else { } else {
key = NDKPrivateKeySigner.generate(); key = NDKPrivateKeySigner.generate();
@ -23,7 +24,7 @@ export default async function createNewKey(admin: AdminInterface, req: NDKRpcReq
} }
const user = await key.user(); const user = await key.user();
const nsec = nip19.nsecEncode(key.privateKey!); const nsec = nip19.nsecEncode(hexToBytes(key.privateKey!));
await saveEncrypted( await saveEncrypted(
admin.configFile, admin.configFile,

View File

@ -19,9 +19,9 @@ export default async function createNewPolicy(admin: AdminInterface, req: NDKRpc
for (const rule of policy.rules) { for (const rule of policy.rules) {
await prisma.policyRule.create({ await prisma.policyRule.create({
data: { data: {
policyId: policyRecord.id, Policy: { connect: { id: policyRecord.id } },
kind: rule.kind.toString(), kind: rule.kind != null ? rule.kind.toString() : null,
method: rule.method, method: rule.method ?? "sign_event",
maxUsageCount: rule.use_count, maxUsageCount: rule.use_count,
currentUsageCount: 0, currentUsageCount: 0,
} }

View File

@ -1,5 +1,6 @@
import NDK, { NDKPrivateKeySigner, Nip46PermitCallback, Nip46PermitCallbackParams } from '@nostr-dev-kit/ndk'; import NDK, { NDKPrivateKeySigner, Nip46PermitCallback, Nip46PermitCallbackParams } from '@nostr-dev-kit/ndk';
import { nip19 } from 'nostr-tools'; import { nip19 } from 'nostr-tools';
import { bytesToHex, hexToBytes } from '../utils/hex.js';
import { Backend } from './backend/index.js'; import { Backend } from './backend/index.js';
import { import {
IMethod, IMethod,
@ -38,7 +39,7 @@ function getKeys(config: DaemonConfig) {
const keys: Key[] = []; const keys: Key[] = [];
for (const [name, nsec] of Object.entries(config.keys)) { for (const [name, nsec] of Object.entries(config.keys)) {
const hexpk = nip19.decode(nsec).data as string; const hexpk = bytesToHex(nip19.decode(nsec).data as Uint8Array);
const user = await new NDKPrivateKeySigner(hexpk).user(); const user = await new NDKPrivateKeySigner(hexpk).user();
const key = { const key = {
name, name,
@ -206,7 +207,7 @@ class Daemon {
continue; continue;
} }
const nsec = nip19.nsecEncode(settings.key); const nsec = nip19.nsecEncode(hexToBytes(settings.key));
this.loadNsec(keyName, nsec); this.loadNsec(keyName, nsec);
} }
} }

17
src/utils/hex.ts Normal file
View File

@ -0,0 +1,17 @@
/**
* Convert Uint8Array to hex string
*/
export function bytesToHex(bytes: Uint8Array): string {
return Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
}
/**
* Convert hex string to Uint8Array
*/
export function hexToBytes(hex: string): Uint8Array {
const bytes = new Uint8Array(hex.length / 2);
for (let i = 0; i < hex.length; i += 2) {
bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
}
return bytes;
}