clone

tiny dependency-free nostr libraries for plain html, each under 5kb and named for an element. public domain

main
nobel / helium / README.md
README.md 1.8K source

🔑 helium.js - keys & signatures

helium.js is a miniature @noble/secp256k1: BIP-340 Schnorr keys, signing and verification in about 4kb of BigInt and crypto.subtle. Loaded alongside xenon.js, it signs nxe-publish events when no NIP-07 extension is present, and verifies incoming events under nhe-verify. It also runs in Deno and other runtimes with Web Crypto, where it needs no document.

<script src="helium.js"></script>
<script src="xenon.js"></script>

<form nxe-publish><input name="content"><button>Post</button></form>
<ol nxe-filter='{"kinds":[1]}' nhe-verify></ol>

The form publishes with a local key when there is no extension, and the list drops any event whose id or signature is invalid.

Attributes

attribute description
nhe-verify Verify every event for subscriptions on or under this element

window.nheCfg = {local:true} always signs with the local key. window.nheCfg = {verify:true} verifies every subscription.

API

function returns
helium.generate() new secret key (hex)
helium.pub(sk) x-only public key (hex)
helium.id(event) event id (hex)
helium.finish(event, sk) signed event with pubkey, id, sig
helium.check(event) true if id and signature are valid
helium.sign(msg, sk, aux?) 64-byte signature (Uint8Array)
helium.verify(sig, msg, pk) true or false
helium.key(sk?) local key: gets (creating one), sets, or with null replaces
helium.signer NIP-07 shaped {getPublicKey, signEvent} using the local key

Caveats

BigInt arithmetic is not constant time, and the local key lives in localStorage. Use it for demos, throwaway or low-value keys. Prefer a NIP-07 extension for anything that matters. Tests check keys and signatures byte for byte against @noble/curves.