Oddbean new post about | logout

Notes by hodlbod | export

 How much demand is there for Kagi to index nostr content?

#Search #AdFree #Privacy #SearchEngine... 
 As an idealistic nostr developer, I'd like to see a relay-based solution, so that we get to keep using a single interface, run queries in parallel, and encourage competition and specialization. 
 Got another blog post out, on why I didn't build Flotilla on NIP 29

nostr:nevent1qvzqqqr4gupzp978pfzrv6n9xhq5tvenl9e74pklmskh4xw6vxxyp3j8qkke3cezqyw8wumn8ghj76r0v3kxymmy9e3k7unpvdkx2tn5dahkcue0qy2hwumn8ghj7un9d3shjtnyv9kh2uewd9hj7qgwwaehxw309ahx7uewd3hkctcpzdmhxue69uhhqatjwpkx2urpvuhx2ue0qythwumn8ghj7ct5d3shxtnwdaehgu3wd3skuep0qqsdzdghkz2tesk28h5hq8ayjv80xnln7klg7m0r5fln5l48kt4hvvguh3a88 
 I got zapped 10k sats for this. Does that constitute Simony?

nostr:nevent1qvzqqqqqqypzp978pfzrv6n9xhq5tvenl9e74pklmskh4xw6vxxyp3j8qkke3cezqyw8wumn8ghj76r0v3kxymmy9e3k7unpvdkx2tn5dahkcue0qy88wumn8ghj7mn0wvhxcmmv9uq32amnwvaz7tmjv4kxz7fwv3sk6atn9e5k7tcprfmhxue69uhhxetwv35hgtnwdaekvmrpwfjjucm0d5hsz9mhwden5te0wfjkccte9cc8scmgv96zucm0d5hsqgpnug2gnj6aj9sy0fmhkuh672hyxnemusfkavadfpdftnug5x7ym5rtpj8d 
 Phew 
 In this episode Rod Dreher mentions the difference between perception and conception (borrowed from who else but Marshal McLuhan) in religion. Perception is the experience of God, conception is the abstraction of that experience. Religion dies when religion gets "stuck in the left brain". The first thing that people do before they lose their faith is stop praying, because that is how we perceive God.

https://fountain.fm/episode/H0pofvutNzUxbJfVwxxH 
 nostr:npub14f0xen78ed7rgvw39v82fwp7tv65yasz2gsgpf4gvxy4q5nlsydsk37k3l  nostr:npub1jlrs53pkdfjnts2... 
 Not that I know of but that would be pretty wild 
 I'd watch that 
 PSA, whenever someone laughs online like this: "hehehe" I hear it in my head as "HEY HEY HEY" 
 yeah, totally agree with it. don't take high risk with low reward. do take a distance to some att... 
 Is this supposed to be an air reply? Whatever client you're using didn't tag Odell's note 
 Ah, ok haha 
 nostr:nprofile1qyw8wumn8ghj76r0v3kxymmy9e3k7unpvdkx2tn5dahkcue0qy88wumn8ghj7mn0wvhxcmmv9uq32amnwv... 
 Ha looks like hodlnaut is more popular than me 
 I don't remember anything that I've put into production lately, but I do have several improvements coming to connection management in the next release. I have a related issue for this as well, auth requests can get quite spammy 
 Awesome. I'm happy for Tony and appreciate his insights. I think he's right about how the things that motivate idealists are not the things that motivate the market. The same sort of risk exists in nostr too. If we want either project to matter, we have to grow up and solve the problems that our real users are feeling. This is super hard, because decentralized technology is way harder to get right than centralized technology, and compromises often have to be made along the way. 
 I was reading Psalm 52 this morning, which says "Your tongue devises destruction, like a sharp razor, working deceitfully." I had to ask myself, how is the tongue like a razor? A razor can do a lot of damage to the body, but the tongue hardly compares.

Normally I think of this in terms of hurting someone's reputation or feelings. But deceit, slander, and malice can do damage even if you're tough enough to not get your feelings hurt, because the body this razor attacks is not that of the individual, but that of the community.

A physical razor can amputate body parts, but a razor made of words can amputate people from one another. Deceit and slander turn people who should be unified against each other. The love and affection forged by years of fellowship can quickly be disrupted by malicious words, even those of a third party.

Beware of those who wield words like weapons, rather than "speaking the truth in love", encouraging others, and building others up. Community is fragile, and needs to be nurtured and protected. 
 100% 
 Correct, in the Church this is called excommunication 
 Excommunication is widely misunderstood. It's very different from shunning, in which the other person is "dead" to you. Excommunication's goal is reconciliation and healing. The nominal separation is only a recognition of what is already true, just as amputation of necrotic flesh is a recognition of cell death. Romans 11:23 talks about this reconciliation in this way: "And if they do not persist in unbelief, they will be grafted in, for God is able to graft them in again." 
 Did the conventions for DVMs change overnight or something? All the content discovery DVMs are ignoring my job requests, so the e-tag filters I'm sending no longer work. However, if I p-tag the DVM I get plenty of stuff back. This seems to have broken nostrudel as well as coracle, but noogle works fine. This is sort of bizarre, if we want pubkey-based feeds then... just follow a pubkey.

What am I missing? nprofile1qyd8wumn8ghj7urewfsk66ty9enxjct5dfskvtnrdakj7qghwaehxw309aex2mrp0yh8qunfd4skctnwv46z7qgnwaehxw309ac82unsd3jhqct89ejhxtcpz4mhxue69uhhyetvv9ujuerpd46hxtnfduhszythwden5te0xy6rqtnxxaazu6t09uqzp75cf0tahv5z7plpdeaws7ex52nmnwgtwfr2g3m37r844evqrr6j2543uu nprofile1qyghwumn8ghj7mn0wd68ytnhd9hx2tcpzfmhxue69uhkummnw3e82efwvdhk6tcprfmhxue69uhhq7tjv9kkjepwve5kzar2v9nzucm0d5hsz8rhwden5te0wdshgetvd35hgefwdpa8yep3xsujucm0d5hsqgpxdq27pjfppharynrvhg6h8v2taeya5ssf49zkl9yyu5gxe4qg55la0jnz nprofile1qyghwumn8ghj7mn0wd68ytnhd9hx2tcpzpmhxue69uhkummnw3ezumt0d5hszxmhwden5te0wfjkccte9ehx7um5wfcxcetzwvhxxmmd9uqzpxdm2kgujytxqruy2yrax8umt83003lqng0lsqhgfuw58kj40jnywhdkjg 
 Actually, looking at it again I'm seeing a correct request/response. I'll keep looking. 
 Ok, so the thing that made my DVMs start working again was adding the relays tag. Which is weird, because adding that tag really shouldn't do anything at all — if you choose the wrong relays in the first place, the DVM isn't going to pick your request up, regardless of what you put in the relays tag. Just put the response back on the relay where the request was found right?

As a sidenote, I've noticed that a lot of the new primal DVMs don't have kind 10002's, so it's impossible to know where to look for them (apart from hardcoding primal's relay). 
 it's been a glorious week or two here on nostr. 

new apps launched: Olas, Flotilla, Chachi
major... 
 Business as usual 
 I can't emphasize how much nprofile1qythwumn8ghj7un9d3shjtnwdaehgu3wvfskuep0qy88wumn8ghj7mn0wvhxcmmv9uq32amnwvaz7tmjv4kxz7fwv3sk6atn9e5k7tcpzamhxue69uhhyetvv9ujuurjd9kkzmpwdejhgtcpzamhxue69uhky6t5vdhkjmn9wgh8xmmrd9skctcpzamhxue69uhhyetvv9ujuvrcvd5xzapwvdhk6tcprdmhxue69uhhxmmrd9skctnswfhhs7tdv9hxztnwv46z7qgnwaehxw309ac82unsd3jhqct89ejhxtcpremhxue69uhkxmmdd46ku6t50yh8qun00puk6ctwvyhxuet59uqzpte8562wrm20dljp9yqnnfypnvvzmsumalvas40hrq5923km5ly0dt0kwx helped me put out a good initial release of flotilla. They gave me extremely detailed feedback over the course of weeks. Thanks you!

nostr:nevent1qvzqqqqqqypzpte8562wrm20dljp9yqnnfypnvvzmsumalvas40hrq5923km5ly0qythwumn8ghj7cnfw33k76twv4ezuum0vd5kzmp0qy08wumn8ghj7cm0d4kh2mnfw3ujuurjdau8jmtpdesjumn9wshszymhwden5te0wp6hyurvv4cxzeewv4ej7qghwaehxw309aex2mrp0yhxummnw3ezucnpdejz7qghwaehxw309aex2mrp0yh8qunfd4skctnwv46z7qpqswt8xpx4p6765gaekz4y5afd76y94yu9nm4es36klqq2f9gvue5sqtl3pe 
 26 members on relay.nostrtalk.org and counting... join us at nostrtalk.org  or flotilla.social 
 DMs use 10050 relay selections, everything else is exclusively sent to the relay you're using 
 No need to update relay selections, flotilla works by selecting a relay — but you have to use flotilla.social 
 nostr:npub1jlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qdjynqn, who wrote the design for c... 
 That would be Derek Powazek 
 Stoked to see you here! Your search engine is super high quality, and aligns really well with the nostr community's ethos. I even wear the shirt you sent me. 
 Check out the recent nprofile1qqsdluwc0qu62t3el7nxl93387gmppe56jkvm88vcuwh3lpw4fcevwsc4as3x in which I interview nprofile1qy2hwumn8ghj7un9d3shjtnyv9kh2uewd9hj7qghwaehxw309a3xjarrda5kuetj9eek7cmfv9kz7qg6waehxw309ajxzumg9ekk7cmtd9hxw7t0w5hxxmmd9uq3samnwvaz7tmwdaehgu3wdpjkc6t0v3jhstnrvchszxnhwden5te0wpskjepwdehhxarjd9nxjety9ehhyee0qyfhwumn8ghj7ur4wfcxcetsv9njuetn9uq3wamnwvaz7tmjv4kxz7fwwpexjmtpdshxuet59uqzpycvemcjxuka9utq2l8u2ncdhk2rxhvt2x6wyumjx6cqe2m33lxe890qdt of Pubky/PKARR/Synonym fame. I really enjoy talking to developers from other protocols. There's lots we can learn from each other. 

Listen here: https://fountain.fm/episode/HXQpcOdQU9Tnxa9BQO2v 
 Do I care about eth: no
Do I support eth nostr client: yes
Do I care if eth addy in your profile:... 
 What you did was common sense. Don't worry about it. 
 I would really recommend nostr:npub12vkcxr0luzwp8e673v29eqjhrr7p9vqq8asav85swaepclllj09sylpugg im... 
 Please nprofile1qy2hwumn8ghj7un9d3shjtnzda6x2a3wwdmz7qgnwaehxw309ac82unsd3jhqct89ejhxtcppemhxue69uhkummn9ekx7mp0qythwumn8ghj7un9d3shjtnwdaehgu3wvfskuep0qywhwumn8ghj7mn0wd68ytnzd96xxmmfdejhytnnda3kjctv9uq32amnwvaz7tmjv4kxz7fwdehhxarj9e3xwtcpr9mhxue69uhhqun9d45h2mfwwpexjmtpdshxuet59uq3wamnwvaz7tmjv4kxz7fwwpexjmtpdshxuet59uq32amnwvaz7tmjv4kxz7fwv3sk6atn9e5k7tcqyrtp7w79k045gq80mtnpdxjuzl9t7vjxk52rv80f888y5xsd5mh55m5yn5w, Coracle is dropping NIP 04 support in the next release 
 I'll soon set up my Flotilla group nostr:nprofile1qqsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c... 
 I will try not to break it 😂 let me know if you need any help setting up or working through bugs 
 nostr:nprofile1qyw8wumn8ghj7un9d3shjtngd9nksmrfva58getj9e3k7mf0qyd8wumn8ghj7um9dejxjapwdehhxenvv9ex2tnrdakj7qgkwaehxw309amk7apwdehhxarj9ecxzun50yhsz9nhwden5te0v4jx2m3wdehhxarj9ekxzmny9uqsuamnwvaz7tmwdaejumr0dshsqgrr3xlxfy08k6f7numgan5glng5turuq6xjcxa6usj8hx677suaxg9qzzfw  thanks for the flotilla shoutout today 
 Tomorrow, Monday, Tuesday are all free 
 #Nostr. We need to have a serious conversation about follow lists. 

People I follow keep droppin... 
 First and only. Hopefully other devs add support eventually 
 You can save the lists then base a feed iff the list for quick access. More stepa but also more composable 
 Got a minor NIP PR out, planning to merge it in the next day or two if no one objects: https://github.com/nostr-protocol/nips/pull/1591/files

It's backwards compatible, but a slight change in the semantics associated with some events used in #nip29, since I'm hoping to be able to adopt the same event kinds in flotilla. 
 nprofile1qythwumn8ghj7enjv4h8xtnwdaehgu339e3k7mf0qy88wumn8ghj7mn0wvhxcmmv9uq3samnwvaz7tmxd9k8getj9ehx7um5wgh8w6twv5hsqgrl54h466tz4v0re4pyuavvxqptsejl0vxcmnhfl60z3rth2xkpjsag59mm nprofile1qy2hwumn8ghj7un9d3shjtnyv9kh2uewd9hj7qgwwaehxw309ahx7uewd3hkctcqyra4jk2dr769dekxxpzsceunsyqmeu6hsk420s2u9w4url5rpazfyedga2m nprofile1qy2hwumn8ghj7un9d3shjtnyv9kh2uewd9hj7qghwaehxw309aex2mrp0yh8qunfd4skctnwv46z7qgnwaehxw309ac82unsd3jhqct89ejhxtcppemhxue69uhkummn9ekx7mp0qqsgvu37sslr6pdmndnhegzkvsadrhumvqw84s7uz4qd2zkx54hxqwg073ds0 
 Is this better?
https://video.nostr.build/88e6fb235e851fcd5dcbdff4e5ea62c931d8f5466da333b98f818421558ec84c.mp4
nostr:nevent1qvzqqqqqqypzp978pfzrv6n9xhq5tvenl9e74pklmskh4xw6vxxyp3j8qkke3cezqyw8wumn8ghj76r0v3kxymmy9e3k7unpvdkx2tn5dahkcue0qy88wumn8ghj7mn0wvhxcmmv9uq32amnwvaz7tmjv4kxz7fwv3sk6atn9e5k7tcprpmhxue69uhkzmrjw5crwtnwdaehgu339e3k7mf0qywhwumn8ghj7ct8v4h8gmmjv9hxwefwdehhxarjxyhxxmmd9uqzpvhzxa7skan7cqt0r9anmqmxtxm9ttv07rgmx6z9y652ey3d29j9p8alku 
 Responded to your DM via NIP 17, but it looks like you don't have any outbox relays 
 *DM relays 
 Funny, I was just going that direction 
 These are all customized except for the first two. It's currently a dropdown, but nobody ever notices it 
 Logged into #Flotilla remotely on my desktop using my Amber app by scanning a QR code.

THIS IS T... 
 I'm glad my blood sweat and tears paid off 
 It's-a me 
 Happy ATH again 
 Gm,

Merging pronouns into our protocol spec as a joke is demonstrating that maybe we aren't seri... 
 I support this message, if only because NIPs should have 2+ implementations before merge. 
 Eh, nips are for documenting common practices. If clients want to let users virtue signal, it's good to agree on how to do it 
 I have issues with pronouns 😂. But do you mean that defining fields in kind 0 affects nostr negatively? 
 😂 
 Because they came to nostr for their kind of speech, and didn't realize that in order to keep it they have to let other people talk too. Many such cases. 
 I wish we had an amber equivalent signer on iOS 😢 
 Thank goodness, I was just about to start building a signer 
 Releasing Flotilla has demonstrated just how much I've learned in the last two years about building user experiences. It's so nice to see my skills improve.

For reference, coracle version 1:

https://v1-coracle-social.onrender.com/notes 
 Sad but true 
 I sincerely wish you could mash both those buttons 
 I'll write a blog post this week. My thoughts have crystallized a lot since I failed to explain my position to you 
 👀👀👀 
 I agree. I only used different kinds/tags to avoid stepping on toes. They can be reconciled, but I still have some big reservations about 29 
 Part of the problem is that there are 10 or so problems being solved, but they're all coupled to the core paradigm of what constitues a group. If that can't be reconciled, we may be able to get some small wins on common event kinds, but the two specs will still be doing incompatible things. 
 Here's an attempt: https://github.com/nostr-protocol/nips/pull/1591

Minimal (no) changes required of NIP 29 clients, although it's going to be a pain for me. The one addition to the semantics is that shallow reply hierarchies be explicitly encouraged, since I don't want people missing replies as a result of which client they're using.

This is just a first step toward merging the two specs. This is the easiest place to start. Maybe rooms can be merged with h tags later, although I'm less optimistic about that one. 
 I am pleased to announce the release of the 0.1.0 release of Flotilla, a new client for communities.

This is NOT a NIP 29 client. More details to come on why, but for now, give it a try at flotilla.social.

If you're not sure which group to start with, try one of these:

https://flotilla.social/spaces/wss%3A%2F%2Frelay.nostrtalk.org%2F
https://flotilla.social/spaces/wss%3A%2F%2Fbucket.coracle.social%2F 
 Can't do stuff if you don't want to do stuff 
 NIP 55 is supported, are you not seeing the Amber login method? It looks like this:
https://coracle-media.us-southeast-1.linodeobjects.com/nip55.png 
 Thanks, I'll take a look. If the bunker flow didn't work, try the nostrconnect flow. Also, if you're using Amber, nip 46 basically doesn't work. 
 Thank you for all your very detail-oriented help with testing! I would not have been able to put out a release at this level of quality without you. 
 Are you running it from the browser/pwa or the apk? Web apps can't use amber unfortunately. 
 So I have this cool new product, which for about two weeks has been ready to release, if I could just solve one thing. I have recently moved away from storing user keys in my apps due to the ease with which they could (and have) been put at risk. In doing so, I've discovered that despite its downsides, pasting your nsec into an app is a pretty straightforward operation which even non-technical people can pull off. In contrast, pretty much no other key management solution is.

Just to state the obvious, and to kick off this survey of nostr key management options, let me just state that asking users to paste their nsec into your app is a *bad idea*. However good your intentions, this opens your users up to all kinds of attack vectors, including clipboard hijacking attacks, exposing keys to insecure communication channels, exposing keys to many different apps, supply chain attacks, XSS attacks, and yes, bugs that cause your software to send keys to analytics or error reporting backends.

The era of nsec-pasting is over.

I've committed to embracing the pain and removing nsec login from Coracle, and I encourage other devs to do the same. The sooner we treat key management with the urgency it deserves, the sooner we can come up with a secure *and* convenient key management solution.

As an aside, `ncryptsec` is a great innovation for securely *transporting* keys, but it still doesn't protect against exposure to apps that need to *use* keys. It has its place though; in fact I'm of the opinion that `nsec` and seed words should be deprecated, and support for them should be removed. Giving friendly names and human-readable representations to data that is essentially private is a really bad idea (unless you're memorizing your key). But I digress.

# Signer Comparisons

Let's go through a few existing options for key management, and compare their relative merits. I've tried to list them in the order they appeared on the scene, which also helps to clarify the logic of how signers have evolved. Throughout, I will be focusing on what kinds of user experience each approach unlocks for *non-technical users*, since my goal is to build products that work for regular people.

## Extension Signers

The first signer application (that I know of) was nos2x, by fiatjaf. As I understand it, this was a proof-of-concept of how users might protect their keys without releasing custody of them. And it works really well! In fact, even though there have been many forks and imitators, I still use nos2x when using nostr on my desktop browser.

Extension signers offer a great user experience, along a narrow happy path. Setting up a browser extension is a relatively familiar process for normal users, and once it's done you don't really have to think about it. In theory, extensions can also include their own onboarding process and key backup strategies as well, allowing users to get started in a single place. Plus, there's very little latency involved in making calls to the signer extension.

This positive experience breaks down quickly though once a user wants to use a desktop or mobile application. When this happens, users have to start over essentially from scratch. Nothing they did to set up the extension helps them move to another signer application.

While it's *technically* possible to use extension signers on mobile via e.g. the Kiwi browser, this doesn't work for native apps or apps installed as PWAs. Instead, you either have to revert to pasting keys, or use some other solution.

One slight permutation of extension signers is browser signers, like Spring. Instead of adding a signer to your browser, Spring allows you to install a browser that holds your keys and allows you to use any nostr web application. But this has all the same basic limitations that extension signers do.

## Hardware Signers

Hardware signers came around shortly after extension signers. I'm not going to spend much time talking about them here, because although they're about as far along the spectrum towards security as you can go, they're also not very convenient. Non-technical users aren't going to onboard by buying (or building) a device which they have to connect to their desktop via USB whenever they want to sign a message. Hardware signers have their place, but onboarding isn't it.

The only hardware signer I'm aware of (although I'm sure I've heard of others) is from [LNBits](https://github.com/lnbits/nostr-signing-device), and is usually used via a browser extension like [horse](https://github.com/lnbits/horse). This of course means that it has all the same limitations that browser extensions have, and then some (although mobile and desktop apps would likely be able to find a way to talk directly to the signer).

## Hosted Signers

Remote signers (aka "bunkers") use the Nostr Connect protocol (also known as NIP 46) for remote signing.

Hosted signers in particular are one example of a NIP 46 remote signer, which lives on "somebody else's computer". Because they use a legacy web architecture, they can be built to be very familiar and convenient to users. It's trivial to build a hosted signer that offers email/password login along with 2FA, password resets, session revokation, the whole shebang. But they have one fatal flaw, which is that they are custodial. This means that not only do users have to relinquish exclusive control over their keys, but hosted signers also can become a target for hackers.

## Desktop Signers

Several projects exist which allow users to run their own bunker, on their own hardware. These include nostr clients like Gossip, as well as command-line utilities like nak. This approach is mostly an improvement over extension signers, because it widens the scope of applications that can conveniently access the signer from those that run in the browser to those that run on the desktop computer the signer lives on. The downside is that they have to communicate via relays, which either introduces latency or requires an additional component to be running locally.

While it's technically possible to use desktop signers to log in on other computers or mobile apps, I don't think that's going to be very practical for most people. Mobile apps by definition are more portable than regular computers. Anyone who wants to access their nostr account on more than one device will have to either set up separate solutions, or go with another kind of remote signer. This isn't a huge obstacle for people highly invested in nostr, but it's a significant amount of friction for a new user.

## Mobile Signers

Mobile signers solve the problem introduced by desktop signers of not always having access to your signer (or of your signer not having access to you, due to being powered down or disconnected from the internet). Mobile devices are generally more available than desktop devices, and also have better push notifications. This means that users can approve signer requests from any device as easily as tapping a notification.

Mobile signers on Android can also upgrade their UX by taking advantage of NIP 55 to avoid the round trip to relays, reducing latency and making it possible to sign things offline. [Amber](https://github.com/greenart7c3/Amber) has been a pioneer in this area, and other projects like [Nostrum](https://github.com/nostr-connect/nostrum) and [Alby's nostr-signer](https://github.com/getAlby/nostr-signer) have been prototyped.

To date, there unfortunately haven't been any signer applications released for iOS, which leaves the mobile signer story incomplete. In my opinion, this is probably the most promising solution for end users, although it's currently under-developed.

## Web Signers

One interesting alternative that combines the benefits of hosted, desktop, and mobile wallets is [nsec.app](https://nsec.app). This is a web application frontend which keeps keys in the browser, so that they are never shared with a third party. Using web push notifications and a healthy sprinkle of black magic, nsec.app is able to respond to signer requests by opening itself in a browser window.

This works generally pretty well for desktop web applications, less well on android, still less well for android PWAs, and (to my understanding) not at all on iOS. Artur from nostr.band is working on these problems using a variety of approaches, one of which is embedding nsec.app in an iframe and communicating using `postMessage`.

This approach also makes it possible to sync keys between your phone and desktop, simulating a hosted UX by making them accessible from either location by signing in to nsec.app. This is done by encrypting user keys and storing them on the nsec.app server. In theory this should be secure, but it's something to consider.

I'm cautiously optimistic about this approach. If successful, it would enable a single brand to exist on every platform, which is important to reduce unnecessary configuration and cognitive overhead for users.

## Multisig Signers

Another experimental approach is multi-sig. [Promenade](https://git.fiatjaf.com/promenade) is a project by fiatjaf exploring this possibility. This would allow users to split their keys across different custodians and require all (or some majority of them) to approve an event signature before it would be valid.

The downsides of this are an increase in complexity (more moving parts for users to deal with) and latency (more parties to coordinate with to sign events). I'm also not clear on whether encryption is possible using multi-signature keys. If not, that would preclude not only existing direct messages (which will hopefully end up on MLS eventually anyway), but also things like private lists, mutes, and application settings. I think multi-signature signers are promising, but are definitely a long-term project.

## Self-Hosted Signers

Coming nearly full circle, self-hosted signers are a special case of hosted signers, but, you know, self-hosted. These signers might live on a home server like a Start9 and be accessible for signer request approvals via tor, or they might live on a server run by the user (or an Uncle Jim). This would be an extremely convenient approach for anyone willing to deal with the complexities of hosting the infrastructure.

A good candidate for NIP 46 support might be AlbyHub, which is already one of the easiest self-hosted wallets to set up and use. Adding signer suppport to AlbyHub would allow users to have their wallet and nostr keys stored in the same place, and accessible anywhere either via the web interface or via AlbyGo.

## Omniplatform Signers

This leads me to, finally, "omniplatform" signers. This isn't really a new architecture, but a combination of several. User choice is great, but nostr has a very tight complexity budget when onboarding new users. If a brand can manage to get new users set up with a very simple but sub-optimal solution, then grow them into a more complete integration into the nostr ecosystem, that would be a huge win.

I think Alby has a great shot at doing this, if it's something they want to prioritize. Bitwarden would also be a great candidate, since they already have apps on every platform, as well as a self-hosted option (Vaultwarden). If users could start with a mobile app, and incrementally set up a browser extension, self-hosted vault, and hardware signer as needed, that I think would be an ideal path.

# Nostr Connect: broken, but promising

If you can't tell from the above comparison, I'm partial to NIP 46 as the best, most flexible way to build high-quality user experiences. Remote key management means a reduction in moving keys, hosting keys, and software installation and administration. If we can get users to the point where their keys live in only two places (their password manager and their signer), we'll be doing good.

There are however many ways to implement NIP 46. Implementing all of them in a single client (or signer) would be burdensome for developers, and introduce a lot of UI complexity to users. Here's a quick survey of flows that currently exist.

## Signer -> Client

The simplest way to connect a client and a bunker is for a user to explicitly authorize the connection by copying a `bunker://` URL from their signer application to their client. This allows the bunker to generate and validate a secret embedded in the URL without the client having to do anything other than pass it along in the initial `connect` request.

This is a great UX for people who know what they're doing, but isn't at all friendly to newcomers. Someone signing in for the first time isn't going to know what a bunker link is, and even if they do they're immediately confronted with the problem of picking a signer, setting it up, and finding out where in that app they can obtain a bunker link. This can be marginally smoothed out using things like protocol handlers and QR codes, but these won't apply in all (or even most) cases.

## Client -> Signer

The reverse flow is similar. This relies on the user to explicitly authorize the connection by copying a `nostrconnect://` url from the client into the signer app. In technical terms, this requires one fewer step, since in NIP 46 the connection is always initiated by the client. In this case, the pasting of the URL replaces the `connect` request. The client listens for a response containing a client-generated secret embedded in the `nostrconnect://` url. This step isn't currently supported by all signer apps, some of which return an `ack` instead. This can result in session hijacking, where an attacker can intercept signing requests (although they can't do anything that would require the user's key, like decrypting messages).

While at first glance `nostrconnect` seems functionally identical to `bunker` links, the UX has the potential to be much better. The reason for this has to do with how people use which devices, and where a client or signer application is most likely to be run. This requires making some assumptions, but in my mind the most common scenario is that a user will want to host their signer on their phone, since that is the device that is most universally available for authorizations (apart from an always-online hosted signer on the open internet). In other words, users generally have their phones with them when they're using their computer, but often don't have a desktop available when using their phone. This idea is validated by (for example) the prevalence of SMS-based 2FA, which assumes the presence of a phone.

Assuming the signer is on the user's phone, QR-scan flows for client authorization make a lot more sense if the client is the one generating the link, since they can simply scan a code generated on another device with their camera, or copy/paste or use a protocol handler for a client on the same device. In contrast, when using a `bunker` link users might find themselves in the awkward position of having to copy a link from their phone to their desktop. Whether this is done via QR code or by sending yourself a link via DM/text/email, it's an awkward flow most people aren't really prepared for.

## Auto-Connect

Some enhancements have been made to the bunker flow which allow clients to send an initial `connect` request without asking the user to copy links between apps. These allow clients to do away with opaque magic strings entirely and provide the idealized "just one click" flow. However, after trying to make this flow work over the course of a couple weeks, I've come to the opinion that the additional complexity involved in automating the flow just isn't worth it.

There are a few variants of this "auto-connect" flow:

- Signer NIP-05: Signers can register a NIP 05 address for a user's pubkey on their domain, allowing users to enter their address rather than their pubkey on login. Unfortunately, this address has no relation to their actual NIP 05 address, which can result in a lot of confusion.
- User NIP-05: To solve this problem, fiatjaf has proposed [a new version](https://github.com/nostr-protocol/nips/pull/1578) which allows users to enter their own NIP 05 in at login instead of the one provided by the signer. The client would then look up the user's `10046` event and follow the signer pubkey listed there.
- Nostrconnect handler: Signers may publish a NIP 89 handler which includes a handler url that clients can send `nostrconnect` urls to. This isn't currently specified anywhere, but it is supported by nsec.app. This bypasses the NIP 05 address requirement entirely, allowing users to simply pick a signer and click a button.

Each of these flows have their own strengths and weaknesses, but all of them share a dependency on some external source of truth for routing a user to the correct bunker.

In the first case, this is done by remembering the NIP 05 address assigned by the signer, which relies on DNS and on users to not forget which address they're using.

In the second case, this is done by relying on the user having done a significant amount of configuration (setting up a NIP 05, adding it to their kind 0, and having published a `10046` event) which may or may not exist. This forces clients to gracefully degrade to some alternative login method anyway, and adds UX friction since users have to choose which interface will work for them.

The final method bypasses the need for users to remember their NIP 05 address, but it does require either the client or the user to select a trusted signer. If poorly implemented, this could result in users choosing an untrustworthy signer on signup (risking their keys), or the wrong signer on login resulting in a broken session.

For all these reasons, I've opted to go with the vanilla bunker/nostrconnect flow, which allows me to display a simple interface to users. Presenting a QR code without comment assumes that users know what to do with it, but the benefit is that it makes explicit the signer selection step which the auto-connect flows try to paper over. This is actually a good thing, because instead of using heuristics like addresses or lists of signers presented by a client to make the decision, users can choose based on which app they actually have installed, which is a richer mnemonic device.

# Making NIP 46 Work

The bottom line here is that while NIP 46 is the best baseline for signer support, it doesn't currently work very well at all. There are a variety of reasons for this:

- The specification itself isn't clear, and is constantly changing. This leads to incompatibilities between apps and signers (or explosive complexity in trying to handle every case).
- Extensions to the basic bunker flow (both in terms of signer implementation and signer discovery) are worth researching, but each one creates another dimension of possible incompatibility. Signers will be incentivized to support every possible login flow, creating complexity for users and increasing attack surface area. Clients will have to implement fallbacks to their preferred signup flows, again resulting in UX complexity.
- Clients don't currently deal well with latency. In order for NIP 46 to work smoothly, clients will have to implement better loading, debouncing, optimistic updates, publish status, and "undo". There are downsides to this, but many of these features endu up being built by mature software products anyway, so supporting these patterns may actually improve rather than degrade UX.
- There's currently no easy and secure way for users to store keys in a single signer which they can access anywhere. This means that users have to set up multiple bunkers depending where they're sitting, or resort to alternative login methods like NIP 07 or 55. These are great upgrades, since they reduce latency and bandwidth use, but shouldn't be required for new users to learn.
- There's no unified experience across platforms. If a user signs up on their desktop, how do they safely transfer their keys to their Android signer app? If they're given seed words, how can they import them as an nsec? Consensus on best practices would be an improvement, but I think only a unified UX across platforms for a single signer can really solve this.
- As nice as it might be to bypass app stores and built-in push notifications, shunning traditional platforms drastically increases the friction for users. To my knowledge, no signer app currently exists in traditional app stores, or supports built-in push notifications. If we want nostr to be accessible to non-technical folks, we can't ask them to start by downloading Obtanium or zap.store and a UnifiedPush distributor for their platform.

As I mentioned above, I don't think NIP 46 will ever be the only solution for signers. But I do think it's a great baseline on which to build a kind of "progressive enhancement" approach. For example, clients should support at least nostrconnect/bunker links, and encourage users once they've logged in to upgrade to NIP 55 or NIP 07 signers. Signers should exist in the mainstream app store and use native push notifications, with an option to install elsewhere or opt-in to UnifiedPush.

The goal here is to balance user experience and security. The number one rule for this is to reduce attack vectors for obtaining user keys. This points to (ideally) a single non-custodial signer, easily accessible to the user, and a simple protocol for using that signer from any app. Progressive enhancement is fine, but we should always be able to fall back to this baseline.
 
 I'm not sure that would ever happen, since if they have a mobile signer they will choose nip 55 right? Which I want to encourage, so friction here seems good. 
 Ah, I see. Sure, that's reasonable. I just wanted to keep the ui uncluttered of extra confusing text boxes and stuff 
 I wouldn't say iOS is the only problem. Here's how nsec.app usually works for me, at least on Coracle (which admittedly spams decrypts)
https://video.nostr.build/f44e00f7879d23b494e4dc698794a517e3e425ac558813540092b64647d68920.mp4