nostr-wasm
Nostr signature stuff in WASM based on libsecp256k1.
Install
yarn install
Demo
A demo application using this package is available at https://nostr-wasm-demo.pages.dev/.
Usage
First, choose which import method suites your needs:
Default
Import with the WASM binary preloaded and uncompressed. No need to perform fetch
, but bundle will be larger (+332 KiB).
import {initNostrWasm} from 'nostr-wasm'
const nw = await initNostrWasm()
Compressed
Import with the WASM binary preloaded and gzipped (requires access to globalThis.DecompressionSteam
). No need to perform fetch
, but bundle will be still be a bit larger (+175 KiB).
import {initNostrWasm} from 'nostr-wasm/gzipped'
const nw = await initNostrWasm()
Headless
Import without the WASM binary. Produces the smallest bundle size but requires fetching the binary yourself.
import {NostrWasm} from 'nostr-wasm/headless'
const nw = await NostrWasm(await fetch('secp256k1.wasm'))
Using the instance:
const sec = nw.generateSecretKey()
const pubkey = nw.getPublicKey(sec)
nw.finalizeEvent(event, sec)
try {
nw.verifyEvent(event)
} catch (err) {
console.log(err)
}
Caller is responsible for zero-ing out private keys in the Uint8Array it passes. Library only zeroes out the bytes in the copies it makes.
Is libsecp256k1 modified?
No, the library is imported as a git submodule directly from upstream.
Building from source
Prerequisites:
git clone --recurse-submodules https://github.com/fiatjaf/nostr-wasm
cd nostr-wasm
bun install
just
The WASM binary will be output to public/out/secp256k1.wasm
.
The Emscripten-generated js file at public/out/secp256k1.js
is not needed for production if you are using the provided wrapper.