1# 🔑 helium.js - keys & signatures23helium.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.45```html6<script src="helium.js"></script>7<script src="xenon.js"></script>89<form nxe-publish><input name="content"><button>Post</button></form>10<ol nxe-filter='{"kinds":[1]}' nhe-verify></ol>11```1213The form publishes with a local key when there is no extension, and the list drops any event whose id or signature is invalid.1415## Attributes1617| attribute | description |18|---|---|19| `nhe-verify` | Verify every event for subscriptions on or under this element |2021`window.nheCfg = {local:true}` always signs with the local key. `window.nheCfg = {verify:true}` verifies every subscription.2223## API2425| function | returns |26|---|---|27| `helium.generate()` | new secret key (hex) |28| `helium.pub(sk)` | x-only public key (hex) |29| `helium.id(event)` | event id (hex) |30| `helium.finish(event, sk)` | signed event with `pubkey`, `id`, `sig` |31| `helium.check(event)` | `true` if id and signature are valid |32| `helium.sign(msg, sk, aux?)` | 64-byte signature (`Uint8Array`) |33| `helium.verify(sig, msg, pk)` | `true` or `false` |34| `helium.key(sk?)` | local key: gets (creating one), sets, or with `null` replaces |35| `helium.signer` | NIP-07 shaped `{getPublicKey, signEvent}` using the local key |3637## Caveats3839BigInt 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.