mirror of
https://github.com/PR0M3TH3AN/bitlogin.git
synced 2026-11-09 23:11:25 +00:00
widget: headless signer — restore + sign without the custom element
The element was the only way to sign, so a host that renders its own UI, a background job, or a headless test couldn't sign without mounting <bitlogin-auth>. Add @bitlogin/widget/headless: createHeadlessSigner() → a DOM-free wrapper over the crypto worker exposing restore, getPublicKey, signEvent, nip44Encrypt/Decrypt, isUnlocked, logout, destroy. It restores the cached session and signs with no element and no window.nostr. It deliberately cannot interactively log in (that needs the password UI): restore() returns null when nothing is cached, at which point the host mounts <bitlogin-auth> once; after that the headless signer works across reloads. New bitlogin-headless.js build entry + @bitlogin/widget/headless export (also re-exported from @bitlogin/widget). Covered by headless.test.ts with a scripted worker; README gains "Signing without the widget (headless)". Addresses the "headless session-restore API" item of the Tessera integration feedback (docs/TODO.md). Co-Authored-By: Claude Opus 4.8 <[email protected]> Claude-Session: https://claude.ai/code/session_01BXQCvJPA6sVSQ5j8uBd9bB
This commit is contained in:
1 parent
5ae41ed9db
commit
b8b19599e0
7 files changed
+245
-5
No files matched your search
@@ -128,6 +128,30 @@ call is also on the full widget as `window.bitlogin.readCachedSession()`, so
|
||||
pages that already load `bitlogin.js` can use it without a second import.
|
||||
Deploy `bitlogin-session.js` alongside `bitlogin.js`.
|
||||
|
||||
**Signing without the widget (headless).** `readCachedSession` reads identity
|
||||
but can't sign. When a host needs to *sign* programmatically — a background job,
|
||||
a framework rendering its own account UI, a headless test — and doesn't want the
|
||||
custom element, use the headless signer. It runs the same crypto worker without
|
||||
any DOM:
|
||||
|
||||
```javascript
|
||||
import { createHeadlessSigner } from "@bitlogin/widget/headless";
|
||||
|
||||
const signer = await createHeadlessSigner();
|
||||
const who = await signer.restore(); // { pubkey } | null (null → no cached session)
|
||||
if (who) {
|
||||
const event = await signer.signEvent({ kind: 1, content: "gm", tags: [] });
|
||||
const pubkey = await signer.getPublicKey();
|
||||
// also: nip44Encrypt / nip44Decrypt / isUnlocked / logout / destroy
|
||||
}
|
||||
```
|
||||
|
||||
It deliberately can't *log in* (that needs the password UI): `restore()` returns
|
||||
null when no session is cached, at which point mount `<bitlogin-auth>` once so
|
||||
the user signs in — after that the headless signer works across reloads from the
|
||||
cached session. Deploy `bitlogin-headless.js` next to `cryptoWorker.js` and the
|
||||
shared chunks, same as `bitlogin.js`.
|
||||
|
||||
The `<bitlogin-auth>` element also mirrors `window.nostr` directly on the
|
||||
element instance (`getPublicKey`, `signEvent`, `nip44Encrypt`, `nip44Decrypt`)
|
||||
— prefer this over `window.nostr` when your host page holds a reference to
|
||||
|
||||
Reference in new issue
Block a user