Podkey is a browser extension for did:nostr and Solid authentication. It puts a NIP-07 window.nostr provider on every page and authenticates to Solid pods over NIP-98, both keyed to your did:nostr identity.
npm installThe extension needs to bundle npm dependencies before it can be loaded:
npm run buildThis will:
- Bundle
@noble/secp256k1and@noble/hashesinto the service worker - Create
src/background.bundle.js - Update
manifest.jsonto use the bundled file
- Open Chrome and navigate to
chrome://extensions/ - Enable Developer mode (toggle in top-right corner)
- Click "Load unpacked"
- Select the
podkeydirectory (the one containingmanifest.json) - The extension should now appear in your extensions list!
- Click the puzzle piece icon (🧩) in Chrome's toolbar
- Find "Podkey" and click the pin icon 📌
- The Podkey icon (🔑) will now appear in your toolbar
- Click the Podkey icon (🔑) in your browser toolbar
- Click "✨ Generate New Key"
- Choose an encryption passphrase (at least 8 characters) and confirm it
- Your new Nostr identity is ready, sealed under your passphrase! 🎉
- Click the Podkey icon (🔑) in your browser toolbar
- Click "📥 Import Existing Key"
- Paste your 64-character hexadecimal private key
- Choose an encryption passphrase (at least 8 characters) and confirm it
- Click "Import"
Your key is encrypted at rest, so when you restart the browser the popup shows an Unlock screen. Enter your passphrase to unlock it for the session — until you do, signing requests show a clear "Podkey is locked" prompt rather than failing silently. Your passphrase is never stored and cannot be recovered, so keep a backup of your private key (and the passphrase).
Podkey provides the standard window.nostr API. Any Nostr app that supports NIP-07 will work automatically!
// In any web page or Nostr app
const pubkey = await window.nostr.getPublicKey()
console.log('Your public key:', pubkey)// Create a Nostr event
const event = {
kind: 1, // Text note
created_at: Math.floor(Date.now() / 1000),
tags: [],
content: 'Hello from Podkey! 🔑'
}
// Sign it
const signedEvent = await window.nostr.signEvent(event)
console.log('Signed event:', signedEvent)// Check if Podkey is available
if (window.nostr) {
// Get your public key
const pubkey = await window.nostr.getPublicKey()
// Create and sign a note
const event = {
kind: 1,
created_at: Math.floor(Date.now() / 1000),
tags: [],
content: 'Hello Nostr!'
}
const signed = await window.nostr.signEvent(event)
// Now you can publish to relays
console.log('Ready to publish:', signed)
} else {
console.log('Podkey not installed')
}Podkey authenticates to Solid servers over NIP-98, using your did:nostr key.
- You request a protected resource on a Solid server.
- The server replies with a 401.
- Podkey asks you to trust the origin (first time only).
- Podkey signs a NIP-98 HTTP authentication event.
- The request is retried with the signed header, and you get access.
No OAuth redirect, no identity-provider account.
Auto-sign is off by default. To turn it on:
- Click the Podkey icon.
- Toggle Auto-sign for Solid to on.
- Trusted Solid servers then authenticate without a prompt.
- Click the Podkey icon
- Scroll to "Trusted Sites" section
- See all origins you've granted permissions to
- Click the Podkey icon
- Find the site in "Trusted Sites"
- Click "Remove" next to the site
- Click the Podkey icon
- Your Public Key (64-char hex) is displayed
- Click "📋 Copy Public Key" to copy it
Your public key is also your did:nostr identifier:
did:nostr:YOUR_PUBLIC_KEY_HERE
This enables:
- ✅ Decentralized identity
- ✅ Cross-platform identity portability
- ✅ Solid pod authentication
- Click the Podkey icon (unlock it first if it shows the Unlock screen)
- Click "Export Key" in the footer
- Confirm the warning
- Your private key will be shown (keep it safe!)
You can also Lock the key on demand from the footer, or Forget key from the Unlock screen to wipe the encrypted vault and start over.
- Make your changes to source files
- Rebuild the extension:
npm run build
- In Chrome, go to
chrome://extensions/ - Click the reload icon (🔄) on the Podkey extension
- Reload any pages using the extension
# Run tests
npm test
# Lint code
npm run lint- Make sure Developer Mode is enabled
- Check that you selected the correct directory
- Look for errors in
chrome://extensions/(click "Errors" if shown)
- Reload the page after installing Podkey
- Check that the extension is enabled
- Look for conflicts with other Nostr extensions
- Check browser console for errors
- Make sure you've generated or imported a key
- Check for permission prompts that may be blocked
- Check the extension console (click "service worker" link in chrome://extensions)
- Make sure all dependencies are installed:
npm install - Check Node.js version (needs >= 18.0.0)
- Try deleting
node_modulesandpackage-lock.json, thennpm installagain
- Make sure esbuild is installed:
npm install - Check that
scripts/bundle.jsexists - Try running:
node scripts/bundle.jsdirectly
Returns your public key (64-char hex).
const pubkey = await window.nostr.getPublicKey()Signs a Nostr event. A trusted origin signs with no prompt; a new origin prompts once, and approving it grants trust.
const signed = await window.nostr.signEvent({
kind: 1,
created_at: Math.floor(Date.now() / 1000),
tags: [],
content: 'Hello!'
})NIP-44 (v2) encryption for NIP-17 / NIP-59 direct messages. The private key stays in the background worker.
const payload = await window.nostr.nip44.encrypt(peerPubkey, 'hello')
const plaintext = await window.nostr.nip44.decrypt(peerPubkey, payload)- Never share your private key - Anyone with it can control your identity
- Review permission prompts - Only trust sites you know
- Use auto-sign carefully - Only enable for trusted Solid servers
- Backup your key - Export and store it securely if needed
- Keep the extension updated - Check for updates regularly
- GitHub Issues: https://github.com/JavaScriptSolidServer/podkey/issues
- Documentation: See README.md
- NIP-07 Spec: https://github.com/nostr-protocol/nips/blob/master/07.md
Made with 🔑 by the JavaScriptSolidServer team