Skip to main content
Glama

signNote

Sign Nostr text notes with a private key to authenticate and publish content on the decentralized social network.

Instructions

Sign a note event with a private key

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
privateKeyYesPrivate key to sign the note with (hex format or nsec format)
noteEventYesUnsigned note event to sign

Implementation Reference

  • The main handler function that performs the actual signing of the note event. It normalizes the private key, verifies it matches the event's pubkey, computes the event hash, signs it, and returns the complete signed event.
    export async function signNote( privateKey: string, noteEvent: { kind: number; content: string; tags: string[][]; created_at: number; pubkey: string; } ): Promise<{ success: boolean, message: string, signedNote?: any }> { try { // Normalize private key const normalizedPrivateKey = normalizePrivateKey(privateKey); // Verify the public key matches the private key const derivedPubkey = getPublicKeyFromPrivate(normalizedPrivateKey); if (derivedPubkey !== noteEvent.pubkey) { return { success: false, message: 'Private key does not match the public key in the note event', }; } // Get event hash and sign it const eventId = await getEventHash(noteEvent); const signature = await signEvent(eventId, normalizedPrivateKey); // Create complete signed event const signedNote = { ...noteEvent, id: eventId, sig: signature }; return { success: true, message: 'Note signed successfully', signedNote: signedNote, }; } catch (error) { return { success: false, message: `Error signing note: ${error instanceof Error ? error.message : "Unknown error"}`, }; } }
  • Zod schema defining the input parameters for the signNote tool: privateKey and the unsigned noteEvent object.
    export const signNoteToolConfig = { privateKey: z.string().describe("Private key to sign the note with (hex format or nsec format)"), noteEvent: z.object({ kind: z.number().describe("Event kind (should be 1 for text notes)"), content: z.string().describe("Content of the note"), tags: z.array(z.array(z.string())).describe("Tags array"), created_at: z.number().describe("Creation timestamp"), pubkey: z.string().describe("Public key of the author") }).describe("Unsigned note event to sign"), };
  • index.ts:1459-1506 (registration)
    Registration of the 'signNote' MCP tool using server.tool(), providing name, description, input schema, and handler that calls the signNote function and formats the MCP response.
    server.tool( "signNote", "Sign a note event with a private key", signNoteToolConfig, async ({ privateKey, noteEvent }) => { try { const result = await signNote(privateKey, noteEvent); if (result.success) { let response = `Note signed successfully!\n\n`; response += `${result.message}\n`; response += `Note ID: ${result.signedNote?.id}\n`; response += `Content: "${noteEvent.content}"\n`; response += `\nSigned Note Event:\n${JSON.stringify(result.signedNote, null, 2)}`; return { content: [ { type: "text", text: response, }, ], }; } else { return { content: [ { type: "text", text: `Failed to sign note: ${result.message}`, }, ], }; } } catch (error) { console.error("Error in signNote tool:", error); return { content: [ { type: "text", text: `Error signing note: ${error instanceof Error ? error.message : "Unknown error"}`, }, ], }; } }, );
  • Helper function to normalize private key input, converting nsec bech32 format to hex if necessary.
    function normalizePrivateKey(privateKey: string): string { if (privateKey.startsWith('nsec')) { const decoded = nip19decode(privateKey as `${string}1${string}`); if (decoded.type !== 'nsec') { throw new Error('Invalid nsec format'); } return decoded.data; } return privateKey; }
  • Helper function to derive the public key from a private key using schnorr signature library.
    function getPublicKeyFromPrivate(privateKey: string): string { return Buffer.from(schnorr.getPublicKey(privateKey)).toString('hex'); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/AustinKelsay/nostr-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server