JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 17
  • Score
    100M100P100Q61375F
  • License AGPL-3.0-or-later

Passkey login for Nostr. Encrypt your nsec with a WebAuthn passkey, publish to relays, decrypt on any device. Implements NIP-K1.

Package Exports

  • @sovit.xyz/keytr
  • @sovit.xyz/keytr/crypto
  • @sovit.xyz/keytr/nostr
  • @sovit.xyz/keytr/webauthn

Readme

keytr

Passkey login for Nostr. Encrypt your nsec with a WebAuthn passkey, publish to relays, decrypt on any device. Implements NIP-K1.

How it works

Register a passkey, encrypt your nsec with the passkey's PRF output, publish the ciphertext to Nostr relays. On a new device, authenticate with the same synced passkey to decrypt. No server trust, no passwords, no manual key copying.

Passkey PRF → HKDF-SHA256 → AES-256-GCM → kind:30079 event → relay

Cross-client login works via a federated gateway model — any domain can authorize a set of Nostr clients to share passkey access using WebAuthn Related Origin Requests. The two official gateways (keytr.org on Cloudflare, nostkey.org on GitHub Pages) trust each other bidirectionally, so a passkey registered under either rpId works on both sites and all authorized client origins.

Documentation

Install

npm install @sovit.xyz/keytr

Quick start

Setup (new user)

import { setupKeytr, publishKeytrEvent } from '@sovit.xyz/keytr'
import { finalizeEvent } from 'nostr-tools/pure'

const { credential, encryptedBlob, eventTemplate, nsecBytes, npub } = await setupKeytr({
  userName: 'alice',
  userDisplayName: 'Alice',
})

// Sign and publish
const signedEvent = finalizeEvent(eventTemplate, nsecBytes)
await publishKeytrEvent(signedEvent, ['wss://relay.damus.io'])

Login (key recovery)

import { loginWithKeytr, fetchKeytrEvents } from '@sovit.xyz/keytr'

const events = await fetchKeytrEvents(pubkey, ['wss://relay.damus.io'])
const { nsecBytes, npub } = await loginWithKeytr(events[0])

Security properties

  • Hardware-bound — PRF output requires physical authenticator + biometric/PIN
  • Origin-bound — phishing sites on different domains get useless PRF output
  • AAD-bound — ciphertext tied to specific credential ID and version
  • No server trust — relay is a dumb store, encryption is end-to-end
  • Memory hygiene — PRF output and derived keys zeroed after use

License

AGPL-3.0-or-later