Sign a Nostr event locally

Paste a disposable nsec or hex secret key, set the event kind, content, tags and timestamp, and get a NIP-01 event JSON object with id, pubkey and BIP-340 Schnorr signature. No relay publish, no upload.

Try:
Signed event

About this tool

This tool builds and signs a Nostr event without contacting a relay. Paste a disposable nsec1… key (or a 64-character hex secret key), fill in the event content, kind, tags and timestamp, and it returns publish-ready JSON containing id, pubkey, created_at, kind, tags, content and sig.

The event id is computed exactly as NIP-01 specifies: the compact serialization [0, pubkey, created_at, kind, tags, content] is hashed with SHA-256. The tool then signs that 32-byte id with a BIP-340 Schnorr signature on secp256k1 and verifies the signature before emitting anything.

Use a test key unless you fully trust the machine where you run this. Everything runs locally in WebAssembly, but a private key is still a private key.

Worked example

With this throwaway secret key:

nsec1vl029mgpspedva04g90vltkh6fvh240zqtv9k0t9af8935ke9laqsnlfe5

and:

it emits a signed event JSON object. The pubkey is derived from the secret key, id is the NIP-01 event hash, and sig is a 128-character Schnorr signature. Switch Output to Relay EVENT frame to wrap the same object as:

["EVENT", { "id": "…", "pubkey": "…", "sig": "…" }]

which is the frame shape a relay websocket expects.

Tags

Tags can be pasted two ways:

Use JSON form when a value itself contains a comma or newline.

Raw template input

If you already have an unsigned event object, paste it into Unsigned event template. Fields present in the template (kind, content, tags, created_at) override the individual controls, while id, pubkey and sig are always recomputed from the signing key.

Limits and edge cases

FAQ

Can I paste my real Nostr private key here?

Technically yes, but you should prefer a disposable test key. The tool runs locally in your browser and does not upload the key, yet any page or machine where you paste an nsec has enough information to sign as you. Treat it like a wallet seed.

What does the event id sign?

NIP-01 signs the SHA-256 hash of a compact JSON array: [0, pubkey, created_at, kind, tags, content]. This tool constructs that array, hashes it to get id, signs the 32-byte id with BIP-340 Schnorr, and verifies the signature before returning the event.

How do I add reply or mention tags?

Use shorthand such as e=<event id>;wss://relay.example.com;root for an event tag or p=<pubkey hex> for a pubkey tag. For exact control, paste full JSON tag arrays like [["e","<id>","wss://relay.example.com","root"],["p","<pubkey>"]].

What is proof of work here?

NIP-13 proof of work means changing a nonce tag until the event id begins with a requested number of zero bits. This can get slow quickly, so the page caps the request at 20 bits and replaces any existing nonce tag when mining.

Does this publish to relays?

No. It only builds and signs the event or relay frame. Publishing requires a network connection to one or more relays, which is outside this local pure-WASM block. Copy the JSON into a relay client if you want to send it.

Developer & Automation Access

Run it from the terminal

Same engine as this page, headless — via the gizza CLI:

gizza tool nostr-event-signer "nsec1vl029mgpspedva04g90vltkh6fvh240zqtv9k0t9af8935ke9laqsnlfe5"

New to the CLI? Get gizza →

Open it by URL

Pre-fill and auto-run this tool with query parameters — the names match the API/CLI:

https://gizza.ai/tools/nostr-event-signer/?nsec=nsec1vl029mgpspedva04g90vltkh6fvh240zqtv9k0t9af8935ke9laqsnlfe5&content=hello%20from%20gizza&kind=1&tags=t%3Dtools%0Ae%3D%3Cevent%20id%3E%3Bwss%3A%2F%2Frelay.example.com%3Broot&created_at=1700000000&template=%7B%22kind%22%3A1%2C%22content%22%3A%22hello%20from%20template%22%2C%22tags%22%3A%5B%5D%2C%22created_at%22%3A1700000000%7D&pow=0&output=event&pretty=true

Machine-readable descriptor: tool.json — title + parameters JSON Schema for agents.