nips
nips copied to clipboard
NIP-55: Unix Domain Sockets
Example using unix domain sockets with two desktop apps where one is acting as a remote signer: https://twitter.com/chrisatmachine/status/1786549455967154312
@mikedilger
Nice! Let's go!
Why the link to Twitter, though? :)
Thanks @vitorpamplona, also I've had a lot of issues with kind 1 web clients.
A few thoughts:
- Should we define a message structure and encoding? I really like what NIP-46 uses for requests and responses, where they both share a designated kind, and the content field contains a NIP-04 encrypted JSON-RPC 2.0 request or response. When using JSON-RPC 2.0 over byte sockets, we also need a message delineation mechanism. See here for some possible options - I'd vote for the first option, shutdown after every request/response, for its simplicity.
- Building on this, should we have socket namespaces? We could use
/tmp/nip55-kind{kind number}instead of/tmp/nip55. This way there could be more than one server on a single device while also keeping the purpose of each one clear.
Also, here's a reference implementation in Rust containing a working server and client which uses the message structure and encoding mentioned above: https://crates.io/crates/nip-55
You can also use the Android Signer spec as a reference: https://github.com/nostr-protocol/nips/pull/868
The interesting part of the Android spec is that it has two modes: with UI and without it. It always tries to do the operation without transferring the user to the other app and only if it fails, it brings the signer UI up.
Cool.
It's not nostr, because it's not websocket communication through relays.
Maybe nostr should be a layered specification, with the top event layer defined in one spec, relay-client messages in another lower spec, websocket transport in a lower yet spec. In that world, this demo would be using not just a different transport, but a different sub-event protocol.
Maybe nostr should be a layered specification, with the top event layer defined in one spec, relay-client messages in another lower spec, websocket transport in a lower yet spec. In that world, this demo would be using not just a different transport, but a different sub-event protocol.
IMHO, it already is like that. The NIP description is just not up to speed. The real Nostr Protocol is only the event definition/sign/verify. Everything else is layer 2+.
@mikedilger does that call into question the validity of nip-7 since it is not websocket communication through relays? I left the nip relatively open but I'm not necessarily suggesting we should send any and all events over the socket, for now just the utility methods from nip-46 that would provide a similar benefit as nip-7 but outside of a browser context and specifically native to the desktop.
Yeah I think nip-7 and nip-6 too are not really nostr. It doesn't mean we can't put it in a nip, we are sloppy about a lot of things.
Why not just do local http?
@alexgleason one reason is that I don't want to deal with figuring out how to get the server and client to agree on a port.
@mikedilger right, maybe it's worth outlining some place in the future to put things like this nip, nip-7 etc, since standards like this allow more streamlined development for clients and greater security.
Why not just do local http?
I see two reasons:
- For local communication, UDS is simpler and more performant.
- If we want socket namespaces like I mentioned above (
/tmp/nip55-kind{kind number}instead of just/tmp/nip55) then I'm not sure how this would translate to HTTP. With UDS there are effectively port names rather than port numbers which allows for easy extensibility without the need for a discovery mechanism
It looks like Windows has supported UDS since 2017 when they added support for the SOCK_STREAM socket type (see here). We could include Named Pipes as an alternative/fallback for Windows (although I don't think that's necessary - I just figured it's worth mentioning).
SOCK_STREAM is analogous to TCP and is what we'd want to use for JSON-RPC 2.0 as I mentioned here.
I think maybe we should narrow it down to just passing the JSON defined in NIP-46. Maybe in the future other events could be passed via UDS but for now I think this is fine.
I'll think about multi user, I'm open to suggestions here.
This NIP does not apply to non Unix systems.
I'll think about multi user, I'm open to suggestions here.
I would switch /tmp/... to a .nostrsigner.sock in the user's home directory. In that way, system apps can have access to it if you give the right permissions to the file. Otherwise, only the user's apps can interact with it.
@vitorpamplona I think that's probably a good idea to manage it in the users home directory, maybe we could define two standard locations in this nip, one that is system wide and one user specific?
would a concrete implementation in JS or Python be helpful to add to the nip?