Get started with Nostr Connect
Nostr Connect (NIP46) is a remote key access protocol.
If you need continuous access to users’ Nostr keys, you have these options:
- store private keys in your app (please don’t do that!)
 - use 
window.nostr(NIP07), which is only available for web apps with a browser extension installed - use Amber or Keystache or other platform-specific solution
 - use Nostr Connect - a remote key access protocol that works on most platforms and is gaining wide adoption
 
This guide is for you if you want to implement Nostr Connect.
If you are looking for a more general login with Nostr guide, check out nostrlogin.org
How to get started with Nostr Connect?
Before we start, to test your Nostr Connect client you should get yourself a server first - try nsec.app or nsecbunker.com or Gossip nostr client.
Now, if you’re building a web app, the best place to start would be nostr-login or window.nostr.js.
These are drop-in scripts that provide the UI for users to log in with Nostr Connect, while exposing a window.nostr object for your app to work with.
It super easy!
Just call signEvent and other methods on the window.nostr object and these libs will handle the rest.
Because there’s actually a lot to handle…
How to implement login with Nostr Connect?
If you just want your own Nostr Connect UI you should probably use NDK or nostr-tools@v2 to avoid implementing the full nip46 protocol yourself.
However, even with one of these libraries, the flow will be quite complex:
- ask the user for their 
bunker URLornip05address - show a Loading state to the user when they click Login, establishing a connection will take a while
 - if 
nip05address is entered, fetch the nostr.json info to get remote user pubkey and thebunker relays(that’squeryBunkerProfilewithnostr-tools, withNDKyou just supply thenip05to theNDKNip46Signer) - if bunker URL is entered, parse it properly to get the 
remote user pubkey,bunker relaysand an optionalsecrettoken (example #1, #2) (that’sparseBunkerInputwithnostr-tool, withNDKyou have to do that yourself) - make sure you connect to the specified bunker relays (
NDK) - generate the Local keypair, it will be used to sign nip46 requests to the 
remote user pubkey - create a nip46 client and supply the 
local keypair privkeyand other params to it, that’sBunkerSignerwithnostr-toolsorNDKNip46SignerwithNDK - subscribe to 
auth_urlmessages, that’sonauthcallback withnostr-toolsorauthUrlevent withNDKNip46Signer- these are needed for users to confirm the actions you’re requesting from their keys - send a 
connectrequest, that’sBunkerSigner.connectwithnostr-toolsorNDKNip46Signer.blockUntilReadywithNDK - if 
auth_urlmessage arrives, you are supposed to open a popup browser tab with the provided URL - show users a Please confirm button and only open the popup when they click it, opening without direct user action will get your popups blocked in many browsers
 - the popup tabs are supposed to be closed automatically when user finishes interacting with them, you don’t have to do that yourself
 - when 
connectis finished, your connection is established and you’re ready to make other methods calls - save the 
local keypairand other params in persistent storage, reuse them next time your app starts 
Wow, we made it!
Well hopefully we didn’t miss anything and it actually worked.
How to access keys with Nostr Connect?
Here is what happens next:
- you send 
sign_eventor other requests using the nip46 client auth_urlmessages might arrive if key storage app needs a confirmation from the user- you should show a non-modal notification to the user saying Please confirm
 - when user clicks, open the URL provided by 
auth_urlmessage, opening it without a click will get your popup blocked and users irritated - the popup will be auto-closed, no need to watch it
 
Cool, we’re accessing those keys now!
How to implement signup with Nostr Connect?
Sign up differs from login in that there is no remote user pubkey yet.
Instead, we will use the remote signer pubkey to send a create_account request to the nip46 server.
Here is how it will look with nostr-tools or NDK:
- ask the user for their preferred username, and show them a list of nip46 providers - the full username will be 
name@provider.com - you might fetch the list of providers from the Nostr network, that’s 
fetchBunkerProviderswithnostr-tools, but keep in mind - anyone can publish a provider description, and you don’t want to send your users to some scammy service, so… - so maybe you start with a static list of good providers, and only fetch from network later, when you add some Web of Trust signals for your users to evaluate the providers
 - now that user has entered their preferred username and selected a provider - make a nip05 request to check if the username is available
 - if the name is available, let users click Sign up, show them the Loading state
 - fetch the 
remote signer pubkeyandbunker relaysof the selected provider from their nostr.json?name=_ endpoint - connect to the 
bunker relays(NDK) - with 
nostr-toolsyou will callcreateAccountand supply the provider info and theonauthcallback - with 
NDKyou’ll have to create aNDKNip46Signerwithremote signer pubkeyand then create thecreate_accountrequest yourself and send it with theirrpcobject - whenever 
auth_urlmessage arrives, follow the same logic as above with the Login flow create_accountwill return the newly createdremote_user_pubkey- with 
createAccountofnostr-tools, you will get a ready-to-useBunkerSignerobject (when they fix an issue) - with 
NDKyou’ll have to create a newNDKNip46Signeryourself with the samelocal keypairand the newremote user pubkey - and don’t forget to save the 
local keypairandremote user pubkeyandbunker relaysto the persistent storage to reuse later 
Now that was really hard, even with a help of some libraries. Hopefully, we get wider and more polished support for create_account method, for now - it is what it is.
How to implement the Nostr Connect client protocol?
This is really out of scope of a Getting started guide (just use libraries), but here are some hints:
- when subscribing to the replies from the signer, add the 
sincefilter with something like now - 10 seconds threshold, many strfry relays don’t actually delete the ephemeral events and will send you old replies - make sure the first parameter for 
connectmethod is theremote user pubkey, notlocal keypair pubkey - make sure you support passing the 
secretas a second parameter toconnectmethod, some providers only allow connections with asecret - all parameters and all return values of the nip46 method calls are 
strings, which means you’ll have to stringify the event forsignEvent, etc - make sure you handle relay disconnects properly - reconnect, and re-subscribe to nip46 replies
 - make sure you ignore duplicates of 
auth_urlmessages, only the firstauth_urlper method call should be handled - make sure you ignore duplicate replies, only handle the first one
 - make sure you test with relays dedicated to nip46, general purpose public relays may block ephemeral events or may impose rate limits if you make lots of method calls
 
How to implement the Nostr Connect server protocol?
Some hints here too:
- when subscribing to the replies from the signer, add the 
sincefilter with something like now - 10 seconds threshold, many strfry relays don’t actually delete the ephemeral events and will send you old replies - make sure you only allow confirmation of new connections without a 
secretusingauth_urlpages, do not show connection requests without asecretin other parts of your app, this is a security hole - make sure you handle relay disconnects properly - reconnect, resubscribe
 - LOTS MORE, TBD.
 
Still have questions?
Submit an issue for this repo, we will do our best to help. And please submit PRs if you have something to contribute.