Open nostrband opened 3 weeks ago
Thank you for opening this. I was trying to implement this flow for https://github.com/fiatjaf/window.nostr.js just last week, but the partitioned storage thing hit me hard, so I gave up. I wasn't aware that it was a thing. I even tried some new API they came up with, for authorized storage access or whatnot, but I think it was broken on Chromium.
I am trying to read this NIP text now, but it's too complex, my brain is not following, will try again later.
This is very complex, and therefore probably fairly fragile, but non-desktop remote signers are such a poor experience right now that the benefits almost certainly outweigh the downsides. I'm highly motivated to improve the bunker UX, so give me a week or so to implement this and I'll have more to say. The code samples are helpful, is there a library anywhere?
partitioned storage thing hit me hard, so I gave up.
Storage is not only partitioned, but also ephemeral on many browsers, I spent 4 weeks making it work smoothly. It is complex, and there's no library, because I just slapped it on top of nostr-login's nip46 code. Samples are very basic just to show the main steps described in the NIP. It's a real pain to implement and clean up, but I feel like it's worth it.
I have reworked this approach to make sure it works end-to-end without relay support. Thus auth_url is no longer used to establish a connection - nostrconnect is used instead, and auth_url itself is displayed as iframe. Also MessageChannel is used to send nip46 requests to reduce latency. Plus added diagrams and spelled minor details to make sure it all comes together well.
Looks too long, maybe code examples are excessive now after details are better covered in the text.
Open here to view the diagrams: https://github.com/brugeman/nips/blob/nip/146/146.md
@staab @fiatjaf
This is awesome, and promising. I do have some comments though.
Disadvantage: potentially more frequent "confirmations", bigger surface for web-based hacks.
After struggling through NIP 46 implementation this last couple of weeks, I think we should add implementation complexity and fragmentation to this list. This criticism isn't exclusive to this PR, but there are many different modes for NIP 46 login, some of which can only be supported by certain kinds of bunkers:
Apart from just the complexity this imposes on apps, bunkers, and users who have to make a good decision, I'm a little worried about bunker lock-in. If DNS-based login is supported in all apps but nostrconnect QR codes isn't, then all signers must become DNS-based or miss out on supporting certain apps (like how lots of apps currently only support nip 07 login). NIP 46 fixed that by creating a universal (if sub-optimal in terms of latency/privacy) solution.
Not to say this is a bad idea, because reducing latency and third-party relays is always a great thing, just pointing out a possible downside.
Another danger is the introduction of a UI component, which will inevitably need to be customized by the embedding client. This will either become part of the spec, or create a hard dependency on whatever iframe signer is most popular. Other iframe signers will either look wrong, or have to adopt the de-facto standard.
I'm curious to see what this looks like in practice. It does improve UX in the sense that the user doesn't have to navigate anywhere in order to use it. However, I wonder if it also degrades UX in the sense that it's not clear what context is actually being trusted. Since users can't verify the url that's serving the iframe, and aren't manually selecting the signer themselves, they don't know if the signer they're using is actually spoofing another signer and trying to steal their key. Validating NIP 89 signer handlers, or requiring users to type in a domain name (which re-introduces a bunch of friction) would be required, and might not be very easy to do short of client developers maintaining a list of trusted signers.
there are many different modes for NIP 46 login, some of which can only be supported by certain kinds of bunkers:
I 100% agree, nostr-login is probably the most complete implementation of all login modes, and it's a total mess. The only reason I keep them all up is because I think we're still in research phase (hence this PR and recent nip46 improvements) and it's not yet clear which method is gonna win. I have now made nostrconnect the primary method, and all the rest are behind "advanced" button, this looks like a good solution for now.
I'm a little worried about bunker lock-in
nostrconnect:// again seems like the most promising solution - it doesn't require DNS and works well with web and native bunkers, and it works for this PR too (at least in terms of UX).
lots of apps currently only support nip 07 login
This is just due to simplicity for devs, but with libs like nostr-login it becomes easier to support all modes through nip07 interface. I'd say all web apps should just focus on nip07 support and then add other protocols as transports behind it.
NIP 46 fixed that by creating a universal (if sub-optimal in terms of latency/privacy) solution.
I was hoping for that too, but unfortunately, that's not happening. No native app does or plans to support being nip46 client, precisely due to latency issues. That's why Amber nip55 was born - to utilize fast platform-specific APIs. This PR does the same, and I decided to work on it when I lost hope of native apps supporting nip46 - if nip46 is basically web-only tech (at least on the client-side) then why not utilize browser-specific APIs? The complexity of client implementation of this PR is just a question of a good library, just like nostr-tools which is used by 90% of web-apps.
Another danger is the introduction of a UI component
This is the biggest concern and uncertainty to me.
This will either become part of the spec, or create a hard dependency on whatever iframe signer is most popular. Other iframe signers will either look wrong, or have to adopt the de-facto standard.
The only hope here is that it's so simple and already in the spec - just a "Continue" button of pre-defined dimentions. I also show nsec.app icon above it, just to signal "this ugly-looking Continue button comes from nsec.app, not from this client".
I'm curious to see what this looks like in practice.
Try it on nostr.band with nsec.app.
It does improve UX in the sense that the user doesn't have to navigate anywhere in order to use it.
Unfortunately, that's not true, there is still a popup, it's just launched by signer's own iframe (so that iframe could talk to top-level signer popup and ask for the keys). The connection UX is not simpler than nip46 - it's up to 1 screen/click longer. What it does improve are a) latency, b) 100% cross-platform, c) privacy.
it's not clear what context is actually being trusted.
I agree in general, the problem is that i.e. Chrome doesn't show address bar in a popup window on desktop, so there are similar issues with nip46 popups. Phishing by malicious clients is possible in both flows, but I agree it's easier with iframes.
aren't manually selecting the signer themselves
They do select their signer, but if client is malicious it might lie to the user and redirect to phishing signer. Bunker-url with a secret without auth_url is immune to this, all other flows are vulnerable.
client developers maintaining a list of trusted signers
I still don't support nip89 to fetch signers in nostr-login precisely because there's no good way to filter phishing signers, so a trusted list with "other/advanced" options is the solution for now. I hope we will keep repeating "WOT solves this" until it somehow does.
Chrome doesn't show address bar in a popup window on desktop
I take it back, Chrome does show the address, not sure where I saw that.
Non-custodial NIP-46 signer suffers from reliability issues - you either keep the signer tab open, or rely on web push which is slow and doesn't work well on iOS.
This NIP explains how web apps might embed such signers as iframes and talk to them directly using browser APIs. This way there's no need to keep a signer tab open, or use relays or web push - it's cross-platform, reliable and instantaneous.
Full text here: https://github.com/brugeman/nips/blob/nip/146/146.md
Try at https://primal.nostrapps.org with https://nsec.app