nostr-protocol / nips

Nostr Implementation Possibilities
2.39k stars 582 forks source link

NIP-37 - Transport method announcement #1585

Open ArjenStens opened 3 days ago

ArjenStens commented 3 days ago

Motivation

Nostr decouples applications completely from the transportation layer, meaning services no longer have to be designed around a single transportation method, but can be accessible through a plethora of ways. This NIP is meant to act as a lookup system that tells a client which transportation methods can be used to access its services.

Rationale

Similar proposals

There have been NIP proposals that touch the connection between pubkeys and addresses, examples of this are:

NIP-97

I believe NIP-97 is very close to solving the issue of this mapping. However, it attempts to also include human-readable naming into the solution. I believe that human-readable naming of pubkeys/services is inherently different from mapping a pubkey to an address where a user can access that pubkey's services, which may or may not map to a legacy domain name.

I argue that Nostr introduces a new paradigm of addressing services, and that that creates an opportunity to make services accessible through different networks and protocols simultaneously.

Human-readable names are and will always be ambiguous and opinionated. Addressing is not nearly as ambiguous. A location is either controlled by a pubkey, or it is not. A pubkey can quite easily prove that it controls an address. Therefore connecting a name to pubkey to a pubkey should be solved in a separate NIP.

NIP-66

NIP-66 covers discoverability from the client side and can be a very important tool to discern which services are worth connecting to. I think it can act as the feedback mechanism to the proposed event of this NIP. It can be used to build metrics for the various networks a pubkey announces it to be accessible. Things like rtt (round trip time) can also be different for each network and should be measured seperately.

mikedilger commented 3 days ago

Based on the title I thought this was going to decouple nostr from websockets and propose nostr-over-X. But rather it looks like a method to advertise services, although such services don't seem to be "nostr" so I'm not sure why it is here unless it is just leveraging nostr identities.

vitorpamplona commented 3 days ago

I like this.

It is similar (simpler) to the proposed NIP-97. Instead of making references by event address, we make them by pub keys. Here each key can only have one redirection event (kind 11111) and thus we can reference the key directly, instead of each individual "subdomain" of a key on kind 30053 of NIP-97.

vitorpamplona commented 3 days ago

This would help normalize relay URLs while offering multiple IPs/domains for the same relay.

Many relays offer ipv4, ipv6, and onion addresses. If NIP-65 becomes a list of pubkeys instead of the wss:// addresses directly, each client can choose if they want to connect via ipv4, v6, i2p or onion. The receiver, and not the author, decides how to connect.

Granted, it creates another round of requests before using the relay or server.

ArjenStens commented 3 days ago

Based on the title I thought this was going to decouple nostr from websockets and propose nostr-over-X. But rather it looks like a method to advertise services, although such services don't seem to be "nostr" so I'm not sure why it is here unless it is just leveraging nostr identities.

It's about decoupling services from a single network and protocol. A relay could use this to decouple from websockets as well. So nostr-over-X could be served by this. If i would have a relay that's accessible exclusively over Lo-Ra it could look like this:

{
  "kind": 11111,
  "tags": [
    ["lo-ra", "914.3Mhz", "<whatever-protocol-lora-people-use>"]
  ]
}

It is really specifically NOT about advertising the service itself which this pubkey is offering, it's only about addressing. There is too much variety in the types of services that can be offered, which can never be satisfied by having one single 'service announcement' kind. I believe every type of service should have it's own service announcement kind. Ex: One for cashu mints, one for relays, one for proxies, etc...

Here each key can only have one redirection event (kind 11111) and thus we can reference the key directly

Spot on!

Granted, it creates another round of requests before using the relay or server.

That is true, although the owner of the pubkey can include some addresses hints in other announcement events that are specific to the service they offer. "Address-hints", if you will.

One example here: https://github.com/ArjenStens/nostr-epoxy-reverse-proxy/blob/main/NIP-XX.md#example

fiatjaf commented 3 days ago

Just to clarify, is the intent that is used, for example, for a personal website? Like replacing DNS and making my website's IPv4 and IPv6 available? And then also offering the website over Tor?

I am having trouble seeing an actual use case here. I can see the relay use case and I won't comment about it, but, aside from that, what else?

If I am using some service's API, for example, I will already be hardcoding their endpoint and transport in my consumer code.

ArjenStens commented 2 days ago

Let me first clarify a bit by making a comparison to DNS:

Legacy DNS (in the way it's used in practice) solved multiple problems: 1) Naming, 2) Identity, 3) Addressing. However, it requires centralized coordination, which is why we don't want to rely on it anymore. Nostr allows us to split these functions of legacy DNS into three parts we can define and solve separately.

1) Naming: Attaching human-readable names to an identity is a consensus/social problem, and should be solved separately from the addressing issue. If people want to have legacy domain names on Nostr it should map the human readable name to a pubkey. 2) Identity is already solved by Nostr out of the box with a pubkey being the identity. 3) Addressing Is the part that this NIP tries to solve. Once trust in an identity (pubkey) is established, you can do a lookup to this event to see where the it should be interacted with, and with which protocol. It can support multiple networks at once, and the addresses can change all the time (for example when dealing with takedowns).

Just to clarify, is the intent that is used, for example, for a personal website? Like replacing DNS and making my website's IPv4 and IPv6 available? And then also offering the website over Tor?

I am having trouble seeing an actual use case here. I can see the relay use case and I won't comment about it, but, aside from that, what else?

The goal is for services to easily define (multiple addresses) and swap out addresses and for clients to still be able to reach them using one simple lookup. So yes, you could make a website available on just an IP address, or 4 different ones, spread over several networks (clearnet/tor/i2p/hyper). Personally I don't think it's main use case will be websites (nsite already helps solve that). It's more useful for services like mints, blossom, relays and whatever else we can come up with.

As an aside: If you'd combine this with encrypting traffic to the pubkey, you could completely subvert the use of centralized domain names AND SSL/TLS with it's single point of failure: the 'Trusted' root certificate authorities.

If I am using some service's API, for example, I will already be hardcoding their endpoint and transport in my consumer code.

I see that that works for a lot of services, but not all. I can see a big need for this by services that might have to move around to avoid takedowns. I think cashu mints might be prone to takedowns and since money is involved, that's a big deal. Currently it's very hard to know which new domain/ip actually belongs to the identity that you trusted and connected to earlier.


What led me to this proposal is the Epoxy project which can proxy to any websocket by just providing it with pubkey. It should be able to see the pubkey's available endpoints on any of the networks it supports (clearnet/i2p/tor/hyper) and connect on whichever one it can reach.

To get there the proxy has to do a lookup, but it doesn't care -and shouldn't have to care- what type of service it's connecting to, it could be another proxy, a relay, or a mint. If there's no single way to do this kind of lookup it would add so much complexity. In this case it might have to check all those service's respective announcement events with their endpoints.

Okay, end of essay 😛

rabble commented 2 days ago

I like this because it would make running Nostr over Tor or other alternative networks easier because you could know there are multiple paths to the same relay and means relays aren't so tied to domain names which might go away.

mikedilger commented 1 day ago

This can't be used for relays because relays aren't known by their pubkey but by their URL. That was sorta defined into nostr from the start.

I think it would be very useful to define both the specific protocols (e.g. tor) that can be used in the tags, but also add another tag that explains what the service is and have a defined list of those values as well. Otherwise it's just a free-for-all and doesn't define anything that anybody can use.

vitorpamplona commented 1 day ago

This can't be used for relays because relays aren't known by their pubkey but by their URL.

The goal is to change that. Don't declare your relays with a wss:// address. That doesn't make any sense. Declare the relay pubkeys and find the current address as needed.

mikedilger commented 1 day ago

That is a great idea @vitorpamplona and I have it listed for nostr-next. But when I look through my codebases, changing the way relays are referred to is far too big of a breaking change.

vitorpamplona commented 1 day ago

far too big of a breaking change.

Nah... it's just a additional ["server-key", <pubkey>] tag on the usual NIP-65. Clients supporting pubkey-based relays can figure itself out. Migration can happen without other clients even knowing.