Migrated n_signer verb names to nostr_ prefix (get_public_key→nostr_get_public_key, sign_event→nostr_sign_event)

This commit is contained in:
Laan Tungir
2026-07-20 18:35:51 -04:00
parent 2314265886
commit 4ec913783a
6 changed files with 96 additions and 3 deletions
+8
View File
@@ -1,3 +1,11 @@
---
slug: codium-nostr-extension
title: Codium nostr extension
summary: A Codium / VSCode extension to publish files to [Nostr].
image:
tags: [nostr, writing, codium, vscode]
---
# Nostr Publish
A Codium / VSCode extension to publish files to [Nostr](https://github.com/nostr-protocol/nostr).
+12
View File
@@ -26,6 +26,7 @@
"onCommand:nostr.fetchRelays",
"onCommand:nostr.selectBackend",
"onCommand:nostr.signInFromSidebar",
"onCommand:nostr.insertNoteHeader",
"onView:nostr.sidebar"
],
"contributes": {
@@ -101,6 +102,12 @@
"command": "nostr.selectBackend",
"title": "Nostr: Select Signer Backend",
"category": "Nostr"
},
{
"command": "nostr.insertNoteHeader",
"title": "Nostr: Insert Note Header",
"category": "Nostr",
"enablement": "editorLangId == markdown"
}
],
"menus": {
@@ -124,6 +131,11 @@
"command": "nostr.publishLongForm",
"when": "editorLangId == markdown",
"group": "nostr@2"
},
{
"command": "nostr.insertNoteHeader",
"when": "editorLangId == markdown",
"group": "nostr@0"
}
]
},
+66
View File
@@ -83,6 +83,11 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
cmdResetTimestamps(state),
),
);
context.subscriptions.push(
vscode.commands.registerCommand("nostr.insertNoteHeader", () =>
cmdInsertNoteHeader(),
),
);
context.subscriptions.push(
vscode.commands.registerCommand("nostr.selectBackend", () =>
cmdSelectBackend(config, state, statusBar),
@@ -914,6 +919,67 @@ async function cmdResetTimestamps(state: StateService): Promise<void> {
vscode.window.showInformationMessage("Published timestamps reset.");
}
/**
* Command: insert a YAML front-matter note header template into the active
* markdown document.
*
* If the document already starts with a `---` front-matter block, the command
* does nothing and shows a warning. Otherwise, it inserts the template at the
* top of the document (or at the cursor if the document is empty).
*
* The slug defaults to the filename stem; the user can edit it after insertion.
*/
async function cmdInsertNoteHeader(): Promise<void> {
const editor = vscode.window.activeTextEditor;
if (!editor) {
vscode.window.showErrorMessage("No active editor.");
return;
}
if (editor.document.languageId !== "markdown") {
vscode.window.showErrorMessage("Active file is not Markdown.");
return;
}
const text = editor.document.getText();
// Check if front-matter already exists.
if (/^---\r?\n/.test(text)) {
vscode.window.showWarningMessage("This document already has a front-matter block.");
return;
}
// Derive a default slug from the filename stem.
const stem = activeFilenameStem() ?? "my-post";
const slug = stem
.toLowerCase()
.replace(/\s+/g, "-")
.replace(/[^a-z0-9-]/g, "")
.replace(/-+/g, "-")
.replace(/^-|-$/g, "") || "my-post";
const header = `---
slug: ${slug}
title: ${stem ?? "Untitled"}
summary: A one-sentence abstract for feeds.
image: https://example.com/cover.png
tags: [nostr, writing]
---
`;
// Insert at position 0 (top of document).
const position = new vscode.Position(0, 0);
await editor.edit((editBuilder) => {
editBuilder.insert(position, header);
});
// Move cursor to the title line for easy editing.
const titleLine = 2; // 0-based: line 0 is `---`, line 1 is `slug:`, line 2 is `title:`
editor.selection = new vscode.Selection(titleLine, 7, titleLine, 7 + (stem?.length ?? 8));
editor.revealRange(new vscode.Range(0, 0, titleLine, 0), vscode.TextEditorRevealType.AtTop);
vscode.window.showInformationMessage("Inserted note header. Edit the metadata, then write your article below the --- line.");
}
/**
* Command: sign in from the sidebar's method dropdown.
*
+1 -1
View File
@@ -48,7 +48,7 @@ export class NsignerClient implements NsignerTransport {
* Send a JSON-RPC request to n_signer and return the parsed response.
* Throws on connection error, timeout, or frame parse failure.
*
* @param method RPC verb (e.g. "get_public_key", "sign_event").
* @param method RPC verb (e.g. "nostr_get_public_key", "nostr_sign_event").
* @param params Params array (e.g. `[{nostr_index: 0}]`).
* @param timeoutMs Per-call timeout (default 30s — signing may need human
* approval at the n_signer terminal, so this is deliberately long).
+2 -2
View File
@@ -62,7 +62,7 @@ export class NsignerBackend implements NostrSigner {
}
async getPublicKey(): Promise<string> {
const res = await this.transport.call("get_public_key", [{ nostr_index: this.nostrIndex }]);
const res = await this.transport.call("nostr_get_public_key", [{ nostr_index: this.nostrIndex }]);
if (res.error) {
throw new Error(`n_signer: ${res.error.message}`);
}
@@ -73,7 +73,7 @@ export class NsignerBackend implements NostrSigner {
}
async signEvent(event: EventTemplate): Promise<VerifiedEvent> {
const res = await this.transport.call("sign_event", [
const res = await this.transport.call("nostr_sign_event", [
JSON.stringify(event),
{ nostr_index: this.nostrIndex },
]);
+7
View File
@@ -15,6 +15,7 @@ type WebviewMessage =
| { type: "validateCurrentFile" }
| { type: "publishLongForm" }
| { type: "validateFrontMatter" }
| { type: "insertNoteHeader" }
| { type: "fetchRelays" }
| { type: "toggleRelay"; relay: string; enabled: boolean };
@@ -125,6 +126,9 @@ export class NostrSidebarProvider implements vscode.WebviewViewProvider {
case "validateFrontMatter":
await vscode.commands.executeCommand("nostr.validateFrontMatter");
break;
case "insertNoteHeader":
await vscode.commands.executeCommand("nostr.insertNoteHeader");
break;
case "fetchRelays":
await vscode.commands.executeCommand("nostr.fetchRelays");
break;
@@ -276,6 +280,7 @@ export class NostrSidebarProvider implements vscode.WebviewViewProvider {
<div class="section">
<h2>Actions</h2>
<button id="createBtn">+ New Event</button>
<button id="insertNoteHeaderBtn" disabled>Insert Note Header</button>
<button id="publishLongFormBtn" disabled>Publish Current File as Long-Form Note</button>
<button id="validateFrontMatterBtn" class="secondary" disabled>Validate Front-Matter</button>
<button id="publishBtn" disabled>Publish Current JSON File</button>
@@ -362,6 +367,7 @@ export class NostrSidebarProvider implements vscode.WebviewViewProvider {
$("validateBtn").addEventListener("click", () => vscode.postMessage({ type: "validateCurrentFile" }));
$("publishLongFormBtn").addEventListener("click", () => vscode.postMessage({ type: "publishLongForm" }));
$("validateFrontMatterBtn").addEventListener("click", () => vscode.postMessage({ type: "validateFrontMatter" }));
$("insertNoteHeaderBtn").addEventListener("click", () => vscode.postMessage({ type: "insertNoteHeader" }));
$("fetchRelaysBtn").addEventListener("click", () => vscode.postMessage({ type: "fetchRelays" }));
$("signOutBtn").addEventListener("click", () => vscode.postMessage({ type: "signOut" }));
@@ -410,6 +416,7 @@ export class NostrSidebarProvider implements vscode.WebviewViewProvider {
$("validateBtn").disabled = !s.canPublish;
$("publishLongFormBtn").disabled = !s.canPublishLongForm;
$("validateFrontMatterBtn").disabled = !s.canPublishLongForm;
$("insertNoteHeaderBtn").disabled = !s.canPublishLongForm;
$("fetchRelaysBtn").disabled = !s.signedIn;
// Identity