Closed fiatjaf closed 3 weeks ago
Also, I support renaming "remote signer" to "bunker". Even though "remote signer" is a correct term (and "bunker" is marketing language), I have gravitated towards using the word "bunker" in my code because I think it's a more human-friendly term that improves clarity and reduces cognitive load. I can't think of a scenario where "bunker" is an incorrect name, eg even with Amber (where keys are self-custodied) and Soapbox (which has a weird reverse-flow while keys are stored in the browser) I think "bunker" is still fine.
Fwiw I have gone the opposite way, towards "remote signer". But there are worse terms than bunker.
Remote signer pubkey
was only introduced to support signup flow, where there's no user pubkey yet, but you can fetch the signer pubkey from nostr.json and talk to it asking for creation of new keys. Signer key is always on the server, even for non-custodial bunker (we can't keep it secret any other way).
That wasn't a problem until now because all nip46 use-cases so far have used the remote-signer-pubkey as an equal to the user-pubkey
No, that's never the case today. Remote signer pubkey is always distinct from user pubkey, and is only used for signup flow. All methods except 'create_account' use user pubkey, not signer pubkey.
Basically, you've confused user pubkey with signer pubkey in your edit. Signer pubkey is in bunker's nostr.json, and is only used for signup.
I believe you've been confused by the following paragraphs, which are vague and confusing:
Note that it's on the user to select the remote signer that is actually managing the remote key that they would like to use in this case. If the remote user pubkey is managed on another remote signer, the connection will fail.
Here the connection might fail not because a wrong remote signer pubkey is used, but because wrong signer relay is used. Client always communicates to user pubkey directly and doesn't care which signer is managing the keys, provided that they use the same relays. The exception is 'create_account' method where user pubkey doesn't yet exist and signer pubkey is needed.
In addition, it's important that clients validate that the pubkey of the announced remote signer matches the pubkey of the
_
entry in the/.well-known/nostr.json
file of the remote signer's announced domain.
This is only applicable to 'create_account', signer pubkey has nothing to do with other methods.
With your edit clients must now discover two pubkeys - user pubkey and signer pubkey. How do they learn signer pubkey? signer/nostr.json?name=_ ? How does non-custodial bunker signal that their user pubkey is always equal to signer pubkey, except for signup?
Also, nostrconnect:// flow is now incomplete because clients don't yet know user pubkey and assume that pubkey of the inbound 'connect reply' message event is the user pubkey, but with your edit we must assume it is signer pubkey and must call getPublicKey to get the user's key.
Strictly speaking every implementation is non-compliant now, and the only reason things will keep working is because everyone will ignore the new version. Anyone implementing this edit from scratch will get stuck at the questions above. We've spent too much effort making existing implementations compliant to old version, and this confusion-based rewrite breaks it heavily, again.
I agree that separating signer from user could allow for interesting key delegation/multisig things, but can we please put more thought into it? Existing implementations shouldn't be declared broken. If a new flow is needed for multi-sig - let it be, it will require both client and bunker changes anyway.
If the old NIP is that unreadable, which I agree with to an extent (and incomplete too), may I try to edit and clarify it, please?
I've spent the last 3 week working on a new thing closely related to this NIP, and I feel like having deep enough recent understanding of the details here to not break much.
Fwiw I have gone the opposite way, towards "remote signer". But there are worse terms than bunker.
buuunker?
for the nip05 based login we should make explicit how to find the bunker pubkey, right now if I login with
test@example.com
it will check the NIP-05 for a nip46.$pubkey = [ <relays-to-use> ]
-- we should either make explicit that the same pubkey should be used, or modify the result to include an object with both relays and bunker pubkey:
{
"names": { "test": "fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52" },
"nip46": {
"fa984bd7dbb282f07e16e7ae87b26a2a7b9b90b7246a44771f0cf5ae58018f52": {
"relays": [ "wss://....." ],
"signer": "<bunker-pubkey>"
}
}
Strictly speaking every implementation is non-compliant now, and the only reason things will keep working is because everyone will ignore the new version. Anyone implementing this edit from scratch will get stuck at the questions above. We've spent too much effort making existing implementations compliant to old version, and this confusion-based rewrite breaks it heavily, again.
Sorry, I don't understand why you're reacting so aggressively. The PR explicitly says remote-signer-pubkey
and user-pubkey
can be the same, and they are the same today in all implementations, so there is nothing wrong or non-compliant with anything. If I broke anything with it that wasn't my intention!
Are you talking specifically about the NIP-05-based login flow? I was thinking only about the bunker://
code. The NIP-05 flow was assumed to keep working with the assumption that user-pubkey
and remote-signer-pubkey
would be the same (although I would like to allow for the possibility of allowing a separate remote-signer-pubkey
there too, that could come in a following PR).
EDIT: I just saw @pablof7z's suggestion above and that may be the fix we need? Or not?
I agree that separating signer from user could allow for interesting key delegation/multisig things, but can we please put more thought into it?
That was the goal of opening the PR, to get more thoughts.
I just think that if we already have the get_public_key
option that fixes everything.
LGTM. Honestly, I don't have a deep understanding of this, but I think it become more clear too.
@erskingardner What do you think as an author of the new version of NIP-46?
@tiero is the original author of NIP-46
(not that who the author is matters tbh)
I've spent the last 3 week working on a new thing closely related to this NIP, and I feel like having deep enough recent understanding of the details here to not break much.
@nostrband is your new thing making use of the NIP-05 flow? Do you have some ideas of how we can transition the NIP-05 flow to the dual-key paradigm without breaking much? Or maybe we can safely break since nsec.app is the only provider using this flow currently?
Sorry, I don't understand why you're reacting so aggressively.
Sorry if it sounded aggressive. I think I was stating the facts, but I might be wrong.
If I broke anything with it that wasn't my intention!
I'm 100% sure that wasn't your intention. I'm reacting intensively because I still remember spending weeks patching existing clients to make existing stuff work, and this rewrite breaks them in at least several ways.
The PR explicitly says remote-signer-pubkey and user-pubkey can be the same.
Signer pubkey used for create_account cannot be the same as user pubkey, because user pubkey does not exist yet.
There's a specific meaning to signer pubkey, it's a key living on the server to facilitate create_account.
What's more, for non-custodial bunker the same server-side signer pubkey cannot be used for other methods, bcs it's not living in users' devices. If we want a different pubkey used for other methods that key must be called differently, and mustn't be confused with create-account-signer-pubkey. RPC-pubkey, transport pubkey, session pubkey? The forth pubkey in this NIP.
Bunker-url flow you mentioned won't work without client upgrade because clients don't call getPublicKey after connect to learn the user pubkey, they assume pubkey in bunker url and pubkey of connect reply event are the user pubkey.
Maybe we could add &transport-pubkey=... to bunker url and non-supporting clients would try a normal connection flow to user pubkey and bunker could reject them with proper explanation, instead of every client assuming transport-pubkey is the user.
Also bunker might lie in getPublicKey - user assumes they connected to their keys and send a private message for encryption, leaking it to malicious bunker.
My suggestion is we don't make an already messy NIP even more messy, and if transport keypair is needed let's make it a separate NIP that doesn't shuffle around the semantics of NIP-46.
Existing NIP:
This edit:
@nostrband is your new thing making use of the NIP-05 flow? Do you have some ideas of how we can transition the NIP-05 flow to the dual-key paradigm without breaking much? Or maybe we can safely break since nsec.app is the only provider using this flow currently?
The problem isn't nsec.app, it's 10+ different clients. I would happily get rid of nip05 flow in favor of nostrconnect:// flow - it's a much better UX. Btw nostrconnect:// is underspecified in the existing NIP - that's what should be improved. But even then upgrading 10+ clients is the problem.
bunker might lie in getPublicKey - user may leak private data.
the user got the connection string from somewhere, so the pubkey of the bunker is pre-authenticated from there, to exploit this the attacker would need to compromise a previous step in the setup.
Same applies if this would be on a NIP-05 login, the attacker would need to compromise the server providing the nostr.json (if we were to add a bunker pubkey to it)
the user got the connection string from somewhere, so the pubkey of the bunker is pre-authenticated from there, to exploit this the attacker would need to compromise a previous step in the setup.
With client-generated nostrconnect:// - no, getPublicKey isn't pre-authenticated.
@nostrband is your new thing making use of the NIP-05 flow? Do you have some ideas of how we can transition the NIP-05 flow to the dual-key paradigm without breaking much? Or maybe we can safely break since nsec.app is the only provider using this flow currently?
The problem isn't nsec.app, it's 10+ different clients. I would happily get rid of nip05 flow in favor of nostrconnect:// flow - it's a much better UX. Btw nostrconnect:// is underspecified in the existing NIP - that's what should be improved. But even then upgrading 10+ clients is the problem.
it's not a breaking change for currently deployed nip46 client<>server pairs, so even if a client doesn't change get the user public key and just assumes bunker pubkey == user pubkey, then for these people it will continue to work
this nip is barely used because it's not good enough yet to have a lower trust model; this minor change that doesn't break existing users unlocks a better trust model.
the user got the connection string from somewhere, so the pubkey of the bunker is pre-authenticated from there, to exploit this the attacker would need to compromise a previous step in the setup.
With client-generated nostrconnect:// - no, getPublicKey isn't pre-authenticated.
that doesn't apply to this discussion
it's not a breaking change for currently deployed nip46 client<>server pairs, so even if a client doesn't change get the user public key and just assumes bunker pubkey == user pubkey, then for these people it will continue to work
User won't see their avatar and username, all feeds will be personalized to transport key, not user pubkey. It breaks a lot.
this nip is barely used because it's not good enough yet to have a lower trust model; this minor change that doesn't break existing users unlocks a better trust model
Adding transport key to nip05 is fine - most clients will ignore it and that's ok.
Changing bunker url to transport pubkey is not fine, &transport=... is ok.
Not separating signer pubkey for create_account vs transport pubkey isn't fine too - NIP text should clearly state there are 4 pubkeys, not 3, and all methods except create_account may be using pubkey #4.
If this change has such a huge potential then let's work on it. Current rewrite breaks a lot of stuff.
I think @nostrband is very confused about what this proposal is even about. This is about the pubkey in the bunker://
URI. It's simply saying clients should actually call get_public_key
and not just pull the key out of the bunker URI. That's it. This doesn't "break everything".
I think @nostrband is very confused about what this proposal is even about. This is about the pubkey in the
bunker://
URI. It's simply saying clients should actually callget_public_key
and not just pull the key out of the bunker URI. That's it. This doesn't "break everything".
+1, I get the exact same impression.
It's simply saying clients should actually call get_public_key and not just pull the key out of the bunker URI.
No client does that, all implementations assume connect reply event's pubkey is user pubkey, not remote-signer-pubkey. Paste a bunker url with remote-signer-pubkey and get logged in as remote-signer-pubkey (not user pubkey) in most (all?) existing clients, with no way to understand what happened - not even an error message anywhere. Every client becomes non-compliant and must be upgraded to support this.
You can't write a new bunker and assume that clients will call getPublicKey, because in practice they don't and your bunker won't work with any client. What we gonna do next after someone builds "multisig bunker" is go around and ask clients to upgrade - @fiatjaf already started that with Coracle. And then clients should upgrade their nip05 handling to be able to talk with new bunkers.
That's all I'm saying. The title is "clarify", instead it's a breaking change. Maybe we should at least wait for a useful multisig bunker before we propose a breaking change?
Bunkers don't have to change. Only clients should change, if they get the user's pubkey out of the Nostr URI instead of calling get_public_key
like they should.
Yes it is kind of a breaking change, between the last version and this version. But what was ever the point of get_public_key
? If you go back and read the original spec, you were always supposed to get the pubkey over RPC. Surely we all knew deep down something was wrong with this version of the spec. And it is a very real problem. Since I started using Amber with Ditto, Ditto feels very broken. I have to force kill Amber on my phone before I can sign events on my laptop again. Amber can stay how it is, but I am making Soapbox generate a new keypair for each session to avoid collisions, lining up with this proposal. It's better for security, too.
You can't write a new bunker and assume that clients will call getPublicKey, because in practice they don't and your bunker won't work with any client.
It looks like in all your comments here you are just stating the facts. The facts are that most clients are not calling get_public_key
. No one has denied that. But these facts are not an argument against this PR.
My assumption is that clients should have been calling get_public_key
and that they just aren't doing that because the NIP is confusing and ambiguous. This PR clarifies the NIP text such that clients can start fixing their implementations.
I've always been confused about which key was which, and I've always thought this NIP was technically broken but that we worked around it somehow in the implementations without fixing the NIP (which seemed actually harder to fix than just fixing all the implementations). So I'm in favor of fixing this NIP... but by now I've forgotten the exact problem I had with it.
But I think this rewrite should be rewritten even further.
After connection setup, then the job of figuring out which user keypair is being requested can be worked out. A lot of other people are weighing in on that point and I'm not confident enough to put in yet another opinion on it especially given that gossip doesn't even distinguish user-keypair from bunker-keypair.
So to be clear, the changes in this PR seem to be:
1) Bunker URL now contains signer pubkey (not user pubkey), and client p-tags signer pubkey (not user pubkey). As a result, it is not clear which user keypair is to be used.
2) Clients now have to call get_public_key() to verify the signer and client are in agreement about which user signing is happening for.
3) In some cases the result will not be as expected, and I presume in those cases the client then needs to call connect() to tell the signer it should be using a different key?
All of these changes are client-side changes. No changes on the bunker side.
My assumption is that clients should have been calling get_public_key and that they just aren't doing that because the NIP is confusing and ambiguous. This PR clarifies the NIP text such that clients can start fixing their implementations
No, you assumption can't be correct. Calling getPublicKey would only be necessary if user pubkey wasn't equal to signer pubkey. But signer pubkey was only introduced 1+ year into the life of this NIP to support create_account. This method was most likely introduced to be symmetrical with nip07, but it was useless, and everyone ignored it, as they should have - a meaningless sentence in a spec won't make everyone waste their time on it.
And just calling getPublicKey doesn't fix much. All of clients assume user pubkey is signer pubkey, (many don't even support signup where signer pubkey was supposed to be used). Now they have to introduce new state to store signer pubkey, they should remember to switch from one signer pubkey to another after signup, etc.
This is not a clarification. This is new functionality. Clarification would be to deprecate getPublicKey.
I re-read the original spec.
The only connection flow was nostrconnect:// generated by client that doesn't yet know user pubkey. Signer was supposed to scan it and send 'connect' message to client with user pubkey as payload:
The Signer will send a message to ACK the connect request, along with his public key
So client was supposed to discover the user pubkey from connect reply (there wasn't "ack" string, there was pubkey as payload of connect).
Later on the spec became explicit that user pubkey was used for transport, and getPublicKey became even more useless.
Anyways, we're arguing whether we should declare every client broken and ask to upgrade or not. It only makes sense if that brings some benefits.
I haven't seen any useful code that would benefit from hours of time to be spent by half-dozen client devs. Can we wait until a great multisig bunker comes along? I will be the first in line to patch every single client if something awesome is introduced. Otherwise we're just messing around with a thing that works.
In some cases the result will not be as expected, and I presume in those cases the client then needs to call connect() to tell the signer it should be using a different key?
Why not? They will always be as expected. Whatever the bunker returns is the public key you want. The first argument to connect
is useless and we should get rid of it.
So client was supposed to discover the user pubkey from connect reply (there wasn't "ack" string, there was pubkey as payload of connect).
There was a get_public_key
method since the beginning. But, well, the spec was ambiguous and confusing since the beginning.
SKIP THE NEXT PARAGRAPH
Then later @pablof7z introduced the npub...#secret
format along with the reverse flow, which bothered me because it assumed the bunker would always use the same keypair as the user, and then I assumed that the change to bunker://
-- which I believe was a syntax being used by @v0l (now I am not sure, I don't know who actually created this syntax) -- would fix that, or at least I think now that that was my primary motivation for preferring that (the secondary motivation was not having a hard dependency on bech32, but that was silly). When the bunker://
syntax was added to the NIP it wasn't specifying what pubkey would be used there, again the NIP text was bad and ambiguous. Only later after a period of intense drama @erskingardner solved it with a big rewrite, but the rewrite was so big and the drama was so intense I believe no one managed to get a full clear picture of everything, at least I know I was very confused so that detail missed me and I later even implemented it the same way as everybody.
Anyway, this is my justification. Ultimately of this matters, but I wanted to write anyway.
I only came back to this NIP because of the multisig signer I'm working on and when I realized that my assumptions about the NIP were incorrect and the text was implying that the bunker and user pubkey are to always be the same. So I'm proposing this change. It is a change, for sure, but a positive one and one that doesn't break anything that is already working.
and then I assumed that the change to
bunker://
-- which I believe was a syntax being used by @v0l (now I am not sure, I don't know who actually created this syntax) -- would fix that, or at least I think now that that was my primary motivation for preferring that
I created that syntax but that was to login into the administrative UI of an nsecbunker, this is irrelevant history that might only be interesting for a museum of nostr's history a hundred years from now. The URI format was provided when you would create a new nsecbunker instance (which could host an unlimited number of user keys)
Then I think someone confused the administrative interface (and it's kind number which was NostrConnect + 1) as part of how NIP-46 works.
Again, I think this is irrelevant, but that's the context, the npub#secret
is a worse format and I'm glad we coalesced around the URI format for clients.
I only came back to this NIP because of the multisig signer I'm working on and when I realized that my assumptions about the NIP were incorrect and the text was implying that the bunker and user pubkey are to always be the same. So I'm proposing this change. It is a change, for sure, but a positive one and one that doesn't break anything that is already working.
This is the key; current users on current clients using the assumption that signer pubkey == user pubkey will continue to work.
Ditto is now calling get_public_key
before saving the connection details in the database: https://gitlab.com/soapbox-pub/ditto/-/merge_requests/568
Latest version of NDK now calls get_public_key
.
All NDK-based applications immediately support this since they already needed to call blockUntilReady()
which would result the user's pubkey, now it will do get_public_key
under the hood and return that.
Finally found the time to read this discussion, and I think @nostrband is right. This is a breaking change, it only isn't if current bunkers maintain the (no longer specced) invariant that the signer pubkey is equal to the user pubkey except when calling create_account
. With the change, new bunker implementations will implement the much clearer and more reasonable behavior of separating the user and signer keys, breaking clients that have not yet implemented the get_public_key
change.
Another weird thing is that the secret is still described as optional, which is currently the only way a bunker can know which user it's supposed to be signing for (unless it uses a different bunker key per user. But that might break the nip46 flow for user signup?)
I think there is so much historical baggage to this NIP that we should probably just create an entirely new standard that doesn't overload everything, and covers the most common user flows. This would solve the nip44 migration too, incidentally. My main question related to that though is: do users care that a particular signer responds to their requests? It's nice that the current spec allows you to be connected to multiple signers at once since you're addressing your own pubkey in the requests, but I'm not clear if that would ever actually be useful. If you're on your phone, you'd want to use your mobile signer, if you're on desktop you'd want to use your desktop signer. But maybe it enables advanced things like multisig or hardware signers.
Also, does this change break the multi-signer use case? If you're connecting to a particular bunker, now that's the only bunker that can reply. Whereas I remember @pablof7z saying that the reason we were p-tagging the user was so that any online signer (e.g. phone vs desktop) could reply, depending on what was most convenient for the user.
Also, does this change break the multi-signer use case? If you're connecting to a particular bunker, now that's the only bunker that can reply. Whereas I remember @pablof7z saying that the reason we were p-tagging the user was so that any online signer (e.g. phone vs desktop) could reply, depending on what was most convenient for the user.
The same thing can still be achieved if the bunker has the same private key.
It's (I think) a cool trick, but ultimately far less important than a multisig signer which requires this change.
Another weird thing is that the secret is still described as optional
Yes, the connect
call is wrong. The parameters want [pubkey, secret]
, but we don't know the user's pubkey yet. Therefore our only option is to put the signer's pubkey (which we pulled out of the bunker URI) as the pubkey, which is pretty pointless since you're already p-tagging the same pubkey in the event. But we can't remove it because it's in position 0.
I agree, the optional secret is insanity. However when the signer's pubkey is randomly generated for the connection, as this PR describes, it can be considered enough of a secret on its own. But I still think we should always include a secret for consistency.
So I think we should leave the connect
call alone. It will contain the same pubkey that is being p-tagged, for historical reasons, and we should basically always include a secret in either case.
I think there is so much historical baggage to this NIP that we should probably just create an entirely new standard that doesn't overload everything
God no. You know what the perfect NIP was? The original NIP-46 :sob: Making a new version will not result in any less drama. It will be exactly the same process but take even longer. After all the push and pull, the idea of it is basically solid now. This one change in this PR fixes basically everything wrong with NIP-46:
get_public_key
actually make sense in the context of the document. Only connect
is harmed. But that's because it was bastardized in the first place.Basically I think aside from the connect
call and the fact we're still using nip04, this MR fixes everything wrong with nip46. I'm not convinced we could make it any simpler than it already is.
BTW, yes it's a breaking change, but here's why I think it's a gray area: I did not modify my NConnectSigner class in my Nostrify library at all. I modified Ditto (the caller) to call getPublicKey()
on it. The semantics of the connect flow itself have not changed, what has changed is an assumption about where to get the public key from. In other words, it's a change to my documentation rather than a change to my library.
Every change can be "breaking" depending on the definition. Let's say this is a "soft-fork". Bitcoin soft-forks are generally understood to not be "breaking" changes, i.e. they are backwards-compatible and do not require existing implementations to update, they can continue to work.
And yet if you are relying on some anyone-can-spend technique that happened to use some opcode that is repurposed during the soft-fork then in this case things you will break.
Better do the breaking change while you can.
I agree with much of @alexgleason remarks above, except for this:
Basically I think aside from the connect call and the fact we're still using nip04, this MR fixes everything wrong with nip46. I'm not convinced we could make it any simpler than it already is.
Unfortunately, this doesn't fix everything wrong with nip46, and new signer key logic must be clarified in several places.
Clarifications needed:
create_account
and one used for all other methods will almost always be different - create_account key is static, announced in nostr.json, can't be same for other methods in non-custodial bunkers. This should be made explicit, as the flow is already complex to implement.create_account
returns the newly created user pubkey - client just make calls to user-pubkey. Now how will they discover the signer pubkey of the newly created user? create_account should probably return signer pubkey instead of user pubkey, and then clients would call getPublicKeyOther fixes I'd propose are mostly around nostrconnect:// flow. I recently switched to nostrconnect:// as primary login method in nostr-login (instead of nip05) because it's much better UX. But this method is not covered well in the spec:
nostrconnect_url: "https://signer.com/<nostrconnect>"
and in their 31990 event. @mikedilger does/can gossip support handling nostrconnect:// uris? Amber already does.
Should create_account
even be a part of nip46? I think it shouldn't be.
Should
create_account
even be a part of nip46? I think it shouldn't be.
I'm all for killing it; only centralized/centralizing entities seem to like it and I know think it's a terrible idea that shouldn't exist.
As the resident fed, I like both nip 05 login and create_account. They provide a familiar redirect-based flow for login, but especially signup. I'd like to see a design that introduces users to keys and remote signers without using domains or create_account. Such a thing could exist, but I have a hard time imagining it not being supported by a wall of text and an insane amount of friction.
@staab It could exist, but does it really belong in nip46? This is a remote signer. nip07 doesn't have any "create account" functionality. The actions are "getPublicKey", "signEvent", and "encrypt/decrypt". We need a separation of concerns. Especially for something that's already struggling.
We need a separation of concerns.
Ok, yes, I do agree with that. create_account is annoying and makes the whole thing more complex. It would also be fine to just wire in a proprietary redirect to https://nsec.app/signup?username=bob
. That same pattern could also be used with the nip05 hack. The problem is that it brings us back to square one for a flow I'm trying to rely on in both coracle and flotilla.
Should create_account even be a part of nip46? I think it shouldn't be.
I am fine with moving it to a separate spec, and/or replacing it with redirect to a pre-declared endpoint. We could then move nip05 there too, until we hopefully ditch it one day.
I'm all for killing it; only centralized/centralizing entities seem to like it
There's nothing inherently centralizing with create_account - real centralized entities host their own custodial bunker and implement signup in their own custom way. I would also add import_account flow, but I guess that will be happening in a different document.
As the resident fed, I like both nip 05 login
Did you try nostrconnect:// login? Check it out on nostr.band or npub.pro - it's also redirect-based, but is much better UX.
Only nsec.app is using the NIP-05 flow, so if @nostrband wants to remove it I think we can kill it immediately. Later we can come up with a better spec for that if we think so.
May I merge this and later @nostrband can make a new PR removing NIP-05, updating nostrconnect://
and moving create_account
elsewhere?
The problem is that it brings us back to square one for a flow I'm trying to rely on in both coracle and flotilla.
What is the flow?
I would also add import_account flow
What about a new event kind:10046
that any pubkey can publish detailing where their bunker is located? It could even have multiple bunkers.
{
"kind": 10046,
"tags": [
["bunker", "<remote-signer-pubkey>", "<relay>", "<relay>"],
["bunker", "<remote-signer-pubkey>", "<relay>"]
]
}
Then you can use either nip05 or just an npub to login. The bunker may respond with an auth URL or just accept the connection based on previously registered client-keys.
What about a new event kind:10046 that any pubkey can publish detailing where their bunker is located?
A bigger question would be - who should choose the relay used for the connection? Currently it's the bunker - relay is in nostr.json and bunker-url. This allows bunker to choose/update/customize relay properly, bunker can even be built into the relay to save latency. So bunker relay declaration should probably stay in nostr.json and 31990 event (nip89). Bunkers that let users choose different relay could do that through bunker-url they generate - it will be advanced use case anyway.
Users could announce their bunker app id using 31989 event, then the same flow of 'paste npub to login' becomes possible. Although I still believe nostrconnect:// is superior - no need to reveal your bunker app or signer key to the public.
May I merge this and later @nostrband can make a new PR removing NIP-05, updating nostrconnect:// and moving create_account elsewhere?
Sounds ok. I would also add a "Changes" section, i.e. "Signer key is introduced, signer pubkey is passed in bunker url, clients must store signer pubkey separately from user pubkey, must call getPublicKey after connect". Can be removed later when most clients are upgraded.
My understanding was that the remote-signer (aka "bunker" -- I wanted to rename
remote-signer
tobunker
in the NIP text, but was unsure) pubkey could be different than the user pubkey, but the NIP doesn't make this distinction clear and probably because of that there are many implementations out there that consider both to be the same (including mine were also like that because I was super confused).I believe these keys were always meant to be possibly distinct otherwise the existence of the
user-pubkey
parameter given to theconnect
method and the existence of theget_public_key
method entirely would make no sense.That wasn't a problem until now because all nip46 use-cases so far have used the
remote-signer-pubkey
as an equal to theuser-pubkey
, which is fine and should continue to work, but other interesting multisig signer implementations and other stuff can be supported if we explicitly allow distinguishing between the two key roles.This PR tries to clarify that a little more, and it also deletes a bunch of text that I felt wasn't helping and was mostly getting in the way by increasing the number of words of the NIP and making it less likely to be read.