feat(#14): bump @nostr-dev-kit/ndk 2.8.1 → 3.0.3 + nostr-tools v1 → v2.20 + acl wire-name vocabulary #15
22 changed files with 79 additions and 72 deletions
refactor: adapt source to NDK 3.0.3 / nostr-tools v2 surface (#14)
Mechanical adjustments to the source after the dep bump in the
previous commit. No semantic changes — every site adapts to API
drift between the pinned versions.
Surface changes addressed:
* `NDKKind` strict numeric enum (was wider in 2.8.1). 18 sites
passed the literal `24134` (NIP-46 admin-RPC response kind) to
`rpc.sendResponse` / `rpc.sendRequest`; NDK 3's `NDKKind` enum
omits 24134. Introduced `src/daemon/admin/kinds.ts` exporting
`NIP46_ADMIN_RESPONSE_KIND = 24134 as NDKKind` so the cast lives
once, and routed all 18 sites through the named constant.
* `NDKPrivateKeySigner` constructor now accepts nsec1 or hex
directly (the `@ai-guardrail` in NDK 3 source explicitly tells
callers not to `nip19.decode` ahead of construction). Simplified
`Daemon.startKey` and `createNewKey` accordingly — the bech32
decode workaround for #8 was tied to NDK 2.8.1's old behavior
and is no longer needed.
* `NDKPrivateKeySigner.privateKey` is `string` (hex) on the public
surface, not `Uint8Array`. `nostr-tools` v2's `nip19.nsecEncode`
wants `Uint8Array`. Replaced `nip19.nsecEncode(key.privateKey!)`
with `key.nsec` (NDK 3 exposes the getter directly), avoiding
both the type mismatch and the unnecessary round-trip. For the
one remaining hex-string-from-config call site, used
`nostrUtils.hexToBytes` to convert before encoding.
* `NDKPool` event rename: `'relay:notice'` → `'notice'`, with
flipped arg order `(notice, relay)` → `(relay, notice)`.
* `NDKUser.fromNip05` now requires the `ndk` instance as a 2nd
positional arg (was implicit-global before).
* `Nip46PermitCallbackParams.params` narrowed to `string |
NostrEvent`; type guards added at the two access sites
(`authorize.ts` and `acl/index.ts:requestToSigningConditionQuery`).
* `req.params` is now `(string | undefined)[]` instead of `any[]`;
`create_account.ts` `authorizationWithPayload` branch now
explicitly throws on missing username/domain before passing to
`createAccountReal` (validates what was implicit before).
* Removed `src/daemon/backend/publish-event.ts` (defined a strategy
that's never registered — wiring is commented out in
`backend/index.ts:22`; in NDK 3 the file refs the removed
`NDKNip46Backend.signEvent`). Dead since at least NDK 2.x; the
bump just made the breakage visible.
Pre-existing `tsc` errors at `src/db.ts` and `src/daemon/authorize.ts`
on `'PrismaClient'` / `'Request'` exports are unrelated to this PR —
the regtest container's nix derivation can't reach the prisma engine
binary store on this host (`nsecbunkerd#14` parked separately).
`pnpm run build` (tsup) is green; the Docker container runs
`prisma generate` against its own engine at image-build time and
resolves these at runtime.
#11's wire-name policy convention adoption is the next commit —
this one is purely keep-it-compiling work.
Refs aiolabs/nsecbunkerd#14.
commit
94b5d55376
|
|
@ -100,7 +100,7 @@ function loadPrivateKey(): string | undefined {
|
|||
} else {
|
||||
// check if we have a @ so we try to get the npub from nip05
|
||||
if (remotePubkey.includes('@')) {
|
||||
const u = await NDKUser.fromNip05(remotePubkey);
|
||||
const u = await NDKUser.fromNip05(remotePubkey, ndk);
|
||||
if (!u) {
|
||||
console.log(`Invalid nip05 ${remotePubkey}`);
|
||||
process.exit(1);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { NDKRpcRequest } from "@nostr-dev-kit/ndk";
|
||||
import AdminInterface from "../index.js";
|
||||
import { NIP46_ADMIN_RESPONSE_KIND } from "../kinds.js";
|
||||
import prisma from "../../../db.js";
|
||||
|
||||
/**
|
||||
|
|
@ -43,5 +44,5 @@ export default async function addPolicyRule(admin: AdminInterface, req: NDKRpcRe
|
|||
});
|
||||
|
||||
const result = JSON.stringify(["ok"]);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, 24134);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { NDKRpcRequest } from "@nostr-dev-kit/ndk";
|
||||
import AdminInterface from "../index.js";
|
||||
import { NIP46_ADMIN_RESPONSE_KIND } from "../kinds.js";
|
||||
import prisma from "../../../db.js";
|
||||
|
||||
/**
|
||||
|
|
@ -42,5 +43,5 @@ export default async function addSigningCondition(admin: AdminInterface, req: ND
|
|||
});
|
||||
|
||||
const result = JSON.stringify(["ok"]);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, 24134);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -131,6 +131,9 @@ export default async function createAccount(admin: AdminInterface, req: NDKRpcRe
|
|||
username = payload[0];
|
||||
domain = payload[1];
|
||||
email = payload[2];
|
||||
if (!username || !domain) {
|
||||
throw new Error('Invalid authorization payload: missing username/domain');
|
||||
}
|
||||
return createAccountReal(admin, req, username, domain, email);
|
||||
}
|
||||
}
|
||||
|
|
@ -195,7 +198,7 @@ export async function createAccountReal(
|
|||
}
|
||||
|
||||
const keyName = nip05;
|
||||
const nsec = nip19.nsecEncode(key.privateKey!);
|
||||
const nsec = key.nsec;
|
||||
currentConfig.keys[keyName] = { key: key.privateKey };
|
||||
|
||||
saveCurrentConfig(admin.configFile, currentConfig);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import NDK, { NDKEvent, NDKPrivateKeySigner, NDKRpcRequest, type NostrEvent } from "@nostr-dev-kit/ndk";
|
||||
import AdminInterface from "../index.js";
|
||||
import { NIP46_ADMIN_RESPONSE_KIND } from "../kinds.js";
|
||||
import { saveEncrypted } from "../../../commands/add.js";
|
||||
import { nip19 } from 'nostr-tools';
|
||||
import { setupSkeletonProfile } from "../../lib/profile.js";
|
||||
|
||||
export default async function createNewKey(admin: AdminInterface, req: NDKRpcRequest) {
|
||||
|
|
@ -13,7 +13,9 @@ export default async function createNewKey(admin: AdminInterface, req: NDKRpcReq
|
|||
let key;
|
||||
|
||||
if (_nsec) {
|
||||
key = new NDKPrivateKeySigner(nip19.decode(_nsec).data as string);
|
||||
// NDK 3.x's `NDKPrivateKeySigner` accepts nsec1 or hex directly
|
||||
// (see core/src/signers/private-key/index.ts `@ai-guardrail`).
|
||||
key = new NDKPrivateKeySigner(_nsec);
|
||||
} else {
|
||||
key = NDKPrivateKeySigner.generate();
|
||||
|
||||
|
|
@ -23,7 +25,7 @@ export default async function createNewKey(admin: AdminInterface, req: NDKRpcReq
|
|||
}
|
||||
|
||||
const user = await key.user();
|
||||
const nsec = nip19.nsecEncode(key.privateKey!);
|
||||
const nsec = key.nsec;
|
||||
|
||||
await saveEncrypted(
|
||||
admin.configFile,
|
||||
|
|
@ -38,5 +40,5 @@ export default async function createNewKey(admin: AdminInterface, req: NDKRpcReq
|
|||
npub: user.npub,
|
||||
});
|
||||
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, 24134);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { NDKRpcRequest } from "@nostr-dev-kit/ndk";
|
||||
import AdminInterface from "../index.js";
|
||||
import { NIP46_ADMIN_RESPONSE_KIND } from "../kinds.js";
|
||||
import prisma from "../../../db.js";
|
||||
|
||||
export default async function createNewPolicy(admin: AdminInterface, req: NDKRpcRequest) {
|
||||
|
|
@ -29,5 +30,5 @@ export default async function createNewPolicy(admin: AdminInterface, req: NDKRpc
|
|||
}
|
||||
|
||||
const result = JSON.stringify(["ok"]);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, 24134);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import { NDKRpcRequest } from "@nostr-dev-kit/ndk";
|
||||
import AdminInterface from "../index.js";
|
||||
import { NIP46_ADMIN_RESPONSE_KIND } from "../kinds.js";
|
||||
import prisma from "../../../db.js";
|
||||
|
||||
export default async function createNewToken(admin: AdminInterface, req: NDKRpcRequest) {
|
||||
|
|
@ -30,5 +31,5 @@ export default async function createNewToken(admin: AdminInterface, req: NDKRpcR
|
|||
if (!tokenRecord) throw new Error("Token not created");
|
||||
|
||||
const result = JSON.stringify(["ok"]);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, 24134);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import { NDKRpcRequest } from "@nostr-dev-kit/ndk";
|
||||
import AdminInterface from "../index.js";
|
||||
import { NIP46_ADMIN_RESPONSE_KIND } from "../kinds.js";
|
||||
|
||||
export default async function ping(admin: AdminInterface, req: NDKRpcRequest) {
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, "ok", 24134);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, "ok", NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { NDKRpcRequest } from "@nostr-dev-kit/ndk";
|
||||
import AdminInterface from "../index.js";
|
||||
import { NIP46_ADMIN_RESPONSE_KIND } from "../kinds.js";
|
||||
import prisma from "../../../db.js";
|
||||
|
||||
/**
|
||||
|
|
@ -29,5 +30,5 @@ export default async function removePolicyRule(admin: AdminInterface, req: NDKRp
|
|||
await prisma.policyRule.delete({ where: { id: ruleId } });
|
||||
|
||||
const result = JSON.stringify(["ok"]);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, 24134);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { NDKRpcRequest } from "@nostr-dev-kit/ndk";
|
||||
import AdminInterface from "../index.js";
|
||||
import { NIP46_ADMIN_RESPONSE_KIND } from "../kinds.js";
|
||||
import prisma from "../../../db.js";
|
||||
|
||||
/**
|
||||
|
|
@ -22,5 +23,5 @@ export default async function removeSigningCondition(admin: AdminInterface, req:
|
|||
await prisma.signingCondition.delete({ where: { id: conditionId } });
|
||||
|
||||
const result = JSON.stringify(["ok"]);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, 24134);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { NDKRpcRequest } from "@nostr-dev-kit/ndk";
|
||||
import AdminInterface from "../index.js";
|
||||
import { NIP46_ADMIN_RESPONSE_KIND } from "../kinds.js";
|
||||
import prisma from "../../../db.js";
|
||||
|
||||
export default async function renameKeyUser(admin: AdminInterface, req: NDKRpcRequest) {
|
||||
|
|
@ -25,5 +26,5 @@ export default async function renameKeyUser(admin: AdminInterface, req: NDKRpcRe
|
|||
});
|
||||
|
||||
const result = JSON.stringify(["ok"]);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, 24134);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { NDKRpcRequest } from "@nostr-dev-kit/ndk";
|
||||
import AdminInterface from "../index.js";
|
||||
import { NIP46_ADMIN_RESPONSE_KIND } from "../kinds.js";
|
||||
import prisma from "../../../db.js";
|
||||
|
||||
/**
|
||||
|
|
@ -32,5 +33,5 @@ export default async function revokeToken(admin: AdminInterface, req: NDKRpcRequ
|
|||
});
|
||||
|
||||
const result = JSON.stringify(["ok"]);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, 24134);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { NDKRpcRequest } from "@nostr-dev-kit/ndk";
|
||||
import AdminInterface from "../index.js";
|
||||
import { NIP46_ADMIN_RESPONSE_KIND } from "../kinds.js";
|
||||
import prisma from "../../../db.js";
|
||||
|
||||
export default async function revokeUser(admin: AdminInterface, req: NDKRpcRequest) {
|
||||
|
|
@ -20,5 +21,5 @@ export default async function revokeUser(admin: AdminInterface, req: NDKRpcReque
|
|||
});
|
||||
|
||||
const result = JSON.stringify(["ok"]);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, 24134);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { NDKRpcRequest } from "@nostr-dev-kit/ndk";
|
||||
import AdminInterface from "../index.js";
|
||||
import { NIP46_ADMIN_RESPONSE_KIND } from "../kinds.js";
|
||||
|
||||
export default async function unlockKey(admin: AdminInterface, req: NDKRpcRequest) {
|
||||
const [ keyName, passphrase ] = req.params as [ string, string ];
|
||||
|
|
@ -16,5 +17,5 @@ export default async function unlockKey(admin: AdminInterface, req: NDKRpcReques
|
|||
result = JSON.stringify({ success: false, error: e.message });
|
||||
}
|
||||
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, 24134);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
import { NDKRpcRequest } from "@nostr-dev-kit/ndk";
|
||||
import AdminInterface from "../index.js";
|
||||
import { NIP46_ADMIN_RESPONSE_KIND } from "../kinds.js";
|
||||
import prisma from "../../../db.js";
|
||||
|
||||
/**
|
||||
|
|
@ -39,5 +40,5 @@ export default async function updatePolicy(admin: AdminInterface, req: NDKRpcReq
|
|||
await prisma.policy.update({ where: { id: policyId }, data });
|
||||
|
||||
const result = JSON.stringify(["ok"]);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, 24134);
|
||||
return admin.rpc.sendResponse(req.id, req.pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import updatePolicy from './commands/update_policy';
|
|||
import addSigningCondition from './commands/add_signing_condition';
|
||||
import removeSigningCondition from './commands/remove_signing_condition';
|
||||
import revokeToken from './commands/revoke_token';
|
||||
import { NIP46_ADMIN_RESPONSE_KIND } from './kinds.js';
|
||||
import fs from 'fs';
|
||||
import { validateRequestFromAdmin } from './validations/request-from-admin';
|
||||
import { dmUser } from '../../utils/dm-user';
|
||||
|
|
@ -142,7 +143,7 @@ class AdminInterface {
|
|||
this.ndk.connect(2500).then(() => {
|
||||
// connect for whitelisted admins
|
||||
this.rpc.subscribe({
|
||||
"kinds": [NDKKind.NostrConnect, 24134 as number],
|
||||
"kinds": [NDKKind.NostrConnect, NIP46_ADMIN_RESPONSE_KIND],
|
||||
"#p": [this.signerUser!.pubkey]
|
||||
});
|
||||
|
||||
|
|
@ -272,7 +273,7 @@ class AdminInterface {
|
|||
const key = keys.find((k) => k.name === keyName);
|
||||
|
||||
if (!key || !key.npub) {
|
||||
return this.rpc.sendResponse(req.id, req.pubkey, JSON.stringify([]), 24134);
|
||||
return this.rpc.sendResponse(req.id, req.pubkey, JSON.stringify([]), NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
||||
const npub = key.npub;
|
||||
|
|
@ -294,7 +295,7 @@ class AdminInterface {
|
|||
};
|
||||
}));
|
||||
|
||||
return this.rpc.sendResponse(req.id, req.pubkey, result, 24134);
|
||||
return this.rpc.sendResponse(req.id, req.pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -326,7 +327,7 @@ class AdminInterface {
|
|||
};
|
||||
}));
|
||||
|
||||
return this.rpc.sendResponse(req.id, req.pubkey, result, 24134);
|
||||
return this.rpc.sendResponse(req.id, req.pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -338,7 +339,7 @@ class AdminInterface {
|
|||
const result = JSON.stringify(await this.getKeys());
|
||||
const pubkey = req.pubkey;
|
||||
|
||||
return this.rpc.sendResponse(req.id, pubkey, result, 24134); // 24134
|
||||
return this.rpc.sendResponse(req.id, pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -350,7 +351,7 @@ class AdminInterface {
|
|||
const result = JSON.stringify(await this.getKeyUsers(req));
|
||||
const pubkey = req.pubkey;
|
||||
|
||||
return this.rpc.sendResponse(req.id, pubkey, result, 24134); // 24134
|
||||
return this.rpc.sendResponse(req.id, pubkey, result, NIP46_ADMIN_RESPONSE_KIND);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -416,7 +417,7 @@ class AdminInterface {
|
|||
remoteUser.pubkey,
|
||||
'acl',
|
||||
[params],
|
||||
24134,
|
||||
NIP46_ADMIN_RESPONSE_KIND,
|
||||
(res: NDKRpcResponse) => {
|
||||
this.requestPermissionResponse(
|
||||
remotePubkey,
|
||||
|
|
|
|||
14
src/daemon/admin/kinds.ts
Normal file
14
src/daemon/admin/kinds.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import type { NDKKind } from '@nostr-dev-kit/ndk';
|
||||
|
||||
/**
|
||||
* NIP-46 admin-RPC response channel — kind-24134. Distinct from the
|
||||
* standard NIP-46 client channel kind-24133 (`NDKKind.NostrConnect`)
|
||||
* which carries `sign_event` / `nip04_*` / `nip44_*` / etc.
|
||||
*
|
||||
* nsecbunkerd's admin surface uses a dedicated kind so signer clients
|
||||
* and admin clients don't subscribe to each other's events.
|
||||
*
|
||||
* NDK 3.x's `NDKKind` enum does not include 24134; the cast happens
|
||||
* once here so callers can pass a typed value to `rpc.sendResponse`.
|
||||
*/
|
||||
export const NIP46_ADMIN_RESPONSE_KIND = 24134 as NDKKind;
|
||||
|
|
@ -59,9 +59,8 @@ async function createRecord(
|
|||
) {
|
||||
let params: string | undefined;
|
||||
|
||||
if (param?.rawEvent) {
|
||||
const e = param as NDKEvent;
|
||||
params = JSON.stringify(e.rawEvent());
|
||||
if (typeof param === 'object' && param !== null && 'rawEvent' in param) {
|
||||
params = JSON.stringify(param.rawEvent());
|
||||
} else if (param) {
|
||||
params = param.toString();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@ export class Backend extends NDKNip46Backend {
|
|||
|
||||
this.baseUrl = baseUrl;
|
||||
this.fastify = fastify;
|
||||
|
||||
// this.setStrategy('publish_event', new PublishEventHandlingStrategy());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
import { NDKNip46Backend } from "@nostr-dev-kit/ndk";
|
||||
import { IEventHandlingStrategy } from '@nostr-dev-kit/ndk';
|
||||
|
||||
export default class PublishEventHandlingStrategy implements IEventHandlingStrategy {
|
||||
async handle(backend: NDKNip46Backend, id: string, remotePubkey: string, params: string[]): Promise<string|undefined> {
|
||||
const event = await backend.signEvent(remotePubkey, params);
|
||||
if (!event) return undefined;
|
||||
|
||||
console.log('Publishing event', event);
|
||||
await event.publish();
|
||||
|
||||
return JSON.stringify(await event.toNostrEvent());
|
||||
}
|
||||
}
|
||||
|
|
@ -124,9 +124,13 @@ export function requestToSigningConditionQuery(method: IMethod, payload?: string
|
|||
const signingConditionQuery: any = { method };
|
||||
|
||||
switch (method) {
|
||||
case 'sign_event':
|
||||
signingConditionQuery.kind = { in: [ payload?.kind?.toString(), 'all' ] };
|
||||
case 'sign_event': {
|
||||
const kindString = (typeof payload === 'object' && payload?.kind !== undefined)
|
||||
? payload.kind.toString()
|
||||
: undefined;
|
||||
signingConditionQuery.kind = { in: [kindString, 'all'] };
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return signingConditionQuery;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import NDK, { NDKPrivateKeySigner, Nip46PermitCallback, Nip46PermitCallbackParams } from '@nostr-dev-kit/ndk';
|
||||
import { nip19 } from 'nostr-tools';
|
||||
import { nip19, utils as nostrUtils } from 'nostr-tools';
|
||||
import { Backend } from './backend/index.js';
|
||||
import {
|
||||
IMethod,
|
||||
|
|
@ -38,8 +38,7 @@ function getKeys(config: DaemonConfig) {
|
|||
const keys: Key[] = [];
|
||||
|
||||
for (const [name, nsec] of Object.entries(config.keys)) {
|
||||
const hexpk = nip19.decode(nsec).data as string;
|
||||
const user = await new NDKPrivateKeySigner(hexpk).user();
|
||||
const user = await new NDKPrivateKeySigner(nsec).user();
|
||||
const key = {
|
||||
name,
|
||||
npub: user.npub,
|
||||
|
|
@ -164,7 +163,7 @@ class Daemon {
|
|||
explicitRelayUrls: config.nostr.relays,
|
||||
});
|
||||
this.ndk.pool.on('relay:connect', (r) => console.log(`✅ Connected to ${r.url}`) );
|
||||
this.ndk.pool.on('relay:notice', (n, r) => { console.log(`👀 Notice from ${r.url}`, n); });
|
||||
this.ndk.pool.on('notice', (r, n) => { console.log(`👀 Notice from ${r.url}`, n); });
|
||||
|
||||
this.ndk.pool.on('relay:disconnect', (r) => {
|
||||
console.log(`🚫 Disconnected from ${r.url}`);
|
||||
|
|
@ -206,7 +205,10 @@ class Daemon {
|
|||
continue;
|
||||
}
|
||||
|
||||
const nsec = nip19.nsecEncode(settings.key);
|
||||
// nostr-tools v2: `nsecEncode` takes `Uint8Array`, not hex string.
|
||||
// pragma: allowlist secret
|
||||
// `settings.key` is the hex-encoded private key from config.
|
||||
const nsec = nip19.nsecEncode(nostrUtils.hexToBytes(settings.key));
|
||||
this.loadNsec(keyName, nsec);
|
||||
}
|
||||
}
|
||||
|
|
@ -226,27 +228,13 @@ class Daemon {
|
|||
*/
|
||||
async startKey(name: string, nsec: string) {
|
||||
const cb = signingAuthorizationCallback(name, this.adminInterface);
|
||||
let hexpk: string;
|
||||
|
||||
if (nsec.startsWith('nsec1')) {
|
||||
try {
|
||||
// NDK 2.8.1's NDKPrivateKeySigner constructor passes its
|
||||
// arg straight to nostr-tools getPublicKey() which requires
|
||||
// 32-byte hex / bytes / bigint, not bech32. Without this
|
||||
// decode, every key created via create_new_key fails to
|
||||
// load with the nostr-tools getPublicKey type error, so
|
||||
// the bunker can never sign for any target it provisions.
|
||||
// See aiolabs/nsecbunkerd#8.
|
||||
hexpk = nip19.decode(nsec).data as string;
|
||||
} catch(e) {
|
||||
console.error(`Error loading key ${name}:`, e);
|
||||
return
|
||||
}
|
||||
} else {
|
||||
hexpk = nsec;
|
||||
}
|
||||
|
||||
const backend = new Backend(this.ndk, this.fastify, hexpk, cb, this.config.baseUrl);
|
||||
// NDK 3.x's `NDKPrivateKeySigner` accepts nsec1 or hex directly
|
||||
// (see `core/src/signers/private-key/index.ts` `@ai-guardrail`
|
||||
// — "DO NOT use nip19.decode() to convert nsec to hex before
|
||||
// passing it here"). The bech32-decode workaround for #8 was
|
||||
// tied to NDK 2.8.1's old constructor behavior and is no
|
||||
// longer needed post-#14 NDK bump.
|
||||
const backend = new Backend(this.ndk, this.fastify, nsec, cb, this.config.baseUrl);
|
||||
await backend.start();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue