nips icon indicating copy to clipboard operation
nips copied to clipboard

NIP-11, add `supported_nips_at` field

Open jimbojw opened this issue 1 year ago • 16 comments

Adding an optional supported_nips_at field to NIP-11 server metadata response. This allows relays to declare which version of the NIPs they support.

Many relays currently declare support for NIPs which no longer exist. For example, here's a recent response from nos.lol:

{
  "contact":"unset",
  "description":"Generally accepts notes, except spammy ones.",
  "name":"nos.lol",
  "software":"git+https://github.com/hoytech/strfry.git",
  "supported_nips": [1,2,4,9,11,12,16,20,22,28,33,40],
  "version":"0.9.6"
}

Note that it declares support for non-existent NIPs 12, 16, 20, 22 and 33.

Adding a supported_nips_at field would allow relays to clarify that they support these NIPs as of a specific time in the past. This will become more important over time as NIPs continue to change.

jimbojw avatar Apr 01 '24 11:04 jimbojw

Adding a new field and applying it to the entire set doesn't give enough meaning to what the NIP actually was at that point in time. It forces the implementer to stay in lockstep with the changes of all NIPs they initially supported. For example, if NIP 1 and NIP 2 change, and I want to support the new change in NIP 1, I'd also have to support the update to NIP 2 when setting a date.

If a versioning was created for NIPs and support thereof, it'd be better to associate on a per NIP basis. This could be done via having the field be a struct or array of arrays to provide additional data like the following

"supported_nips_versions": [
  [ 1, 1711973377, "v1", "v2" ],
  [ 2, 1711973377, "v1" ],
  [ 4, 1711973377, "v1" ],
  [ 9, 1711973377, "v1", "v2" ],
  [ 11, 1711973377, "v1", "v2", "v4" ],
  [ 12, 1711973377, "v1", "v2", "v3" ],
  [ 16, 1711973377, "v1", "v2" ],
  [ 20, 1711973377, "v1", "v2" ],
  [ 22, 1711973377, "v1" ],
  [ 28, 1711973377, "v1" ],
  [ 33, 1711973377, "v1" ],
  [ 40, 1711973377, "v1" ],
]

I'm not necessarily in favor of this either. At some point, NIPs need to be "finalized" and changes expressed as later NIP numbers.

vicariousdrama avatar Apr 01 '24 12:04 vicariousdrama

StrFry's config just needs to be updated in this case.

If you want to build a resilient client, I recommend designing feature support testing schemes in production rather than relying solely on NIP-11 documentation. To check if features like AUTH, NIP-50 Search, Gift Wraps, or NIP-95 are functional just create a payload of each, send it, and observe the response. Use that info to activate or deactivate features for each relay the user wants to use. Trusting NIP-11 descriptors will never be as good as testing if what they claim is true.

vitorpamplona avatar Apr 01 '24 12:04 vitorpamplona

I'm open to alternatives. Adding supported_nips_at was the simplest change I could think of. Ideally, each NIP would have a version number to which relays could pledge support.

Trusting NIP-11 descriptors will never be as good as testing if what they claim is true.

Agreed that clients should implement their own feature detection. Relays may lie---intentionally or not. The problem I'm trying to resolve is relays being made liars by upstream, retroactive changes to NIPs after their implementation.

jimbojw avatar Apr 01 '24 12:04 jimbojw

StrFry's config just needs to be updated in this case.

Every relay continuously needs to be updated in every case is the problem.

jimbojw avatar Apr 01 '24 12:04 jimbojw

Every relay continuously needs to be updated in every case is the problem.

You are expecting NIPs to be centrally controlled forever. Picture how nothing here makes sense if we had 10+ separate, reputable NIP repos out there, each led by different people, with different texts, reusing numbers from one another, each with separate versions and slightly different interpretations of what needs to be done to declare support for something. A truly decentralized protocol.

Even with just one NIP repo, the amount of spec misunderstandings, partial support, bugs, and other mishaps is high to the point that declaring "compliance" really doesn't make much practical sense. We are not designing NIPs in a way that it is easy to declare compliance with.

Right now declaring compliance with NIPs is just a dumb marketing tool to declare how far your relay or client has come. It's reminiscent of the old days where every relay and client was expected to code all NIPs. That's not true anymore. But the marketing BS remains.

vitorpamplona avatar Apr 01 '24 13:04 vitorpamplona

We are not designing NIPs in a way that it is easy to declare compliance with.

This has been my experience, yes.

Right now declaring compliance with NIPs is just a dumb marketing tool

It sounds like the supported_nips field is unhelpful to clients---who nominally ought to be the beneficiaries. If so, this is good to know.

Would it be better for relays to omit this field from the relay metadata response?

jimbojw avatar Apr 01 '24 13:04 jimbojw

Would it be better for relays to omit this field from the relay metadata response?

Not better, nor worse. It serves as an indicator of what the owner or operator tried to do. Users can look for it to reduce their search for the piece of software that can potentially help their use case. But it's just a hint. They will need to test if it actually does what it claims to do. Same for clients that declare compliance with NIPs.

My point is that declarations can't be trusted. We don't read the documentation of a piece of software and just assume the code is doing that exact thing. We always need to verify that the code and the documentation are aligned before using software. And, most of the time, the documentation is just the surface layer description for a much more complicated set of decisions. And those small decisions become extremely important for highly interoperable systems, like in Nostr.

And if the goal is just to make such declarations, the current NIP-11 array is fine. Your PR here is also fine.

Enhancing the array can bring more information but it is still for humans to read. The only question is: is the extra verbosity needed/worth it or can the humans figure it out by themselves without it? If the StrFry example you gave had versions, would it be any better? Or will it just be wrong anyway? Couldn't a human just look at the file in StrFry's repo, estimate when the last changes were made and look back in the NIP repo to fine the equivalence he/she is looking for? Does that even solve anything? Or is it just more things to do before having to test if the relay does what the human wants it to do?

From my Client hat, I will just keep ignoring these fields.

vitorpamplona avatar Apr 01 '24 13:04 vitorpamplona

If the StrFry example you gave had versions, would it be any better?

I only posted nos.lol, but every relay that I've ping'd has incorrectly listed at least one of NIPs 12, 16, 20, 22 or 33 which no longer exist (in this repo). Based on my limited testing, there are zero relays reporting correctly (for this repo). Here's two more off the top of my head:

$ curl -sH "Accept: application/nostr+json" https://nostr.wine | jq '.supported_nips' -c
[1,2,4,9,11,12,15,16,20,22,28,33,40,42,50]

$ curl -sH "Accept: application/nostr+json" https://eden.nostr.land | jq '.supported_nips' -c
[1,2,4,9,11,12,16,20,22,28,33,40]

Enhancing the array can bring more information but it is still for humans to read.

A human reading a list today will see NIPs such as 20. But when they go to where NIP-20 used to be, they get a 404. The status quo does not pass the "humans can use it" test.

jimbojw avatar Apr 01 '24 14:04 jimbojw

there are zero relays reporting correctly (for this repo)

Yep, that's why I fully ignore NIP-11.

Maybe someone should just design a test suite to run against all relays and output their compliance to varying levels of NIPs. :)

Maybe that output can be in a way that they can easily update their NIP-11s from it.

vitorpamplona avatar Apr 01 '24 14:04 vitorpamplona

Maybe someone should just design a test suite to run against all relays and output their compliance to varying levels of NIPs. :)

This has been on my mind as well. Broadly, I imagine two categories of tests: passive and active. Passive tests only request information. These tests can detect filter limitations, NIP-42 enforcement, error message formatting, EOSE, etc. Active tests post notes to explore whether the relay enforces its stated or unstated limits (such as created_at), replace NIP-33 parameterized notes, faithfully delete per NIP-05, actually check note signatures, check whether new notes show up when searched (e.g. NIP-50), etc. etc.

I was thinking of calling such a command line tool NOstr Relay Probe (norp) in the style of nmap. I have not started implementing such a tool, partly because I've prioritized implementing my own relay.

Back to the discussion at hand. Since supported_nips is irretrievably broken to the point of meaninglessness, perhaps we should just remove it from NIP-11?

jimbojw avatar Apr 01 '24 15:04 jimbojw

This inspired us to update our NIP-11 for nostr.wine - thanks.

I'm not exactly sure what should be included in supported_nips though. Does a relay actually "support" NIP-04?

nostr-wine avatar Apr 09 '24 16:04 nostr-wine

Just FYI from my reading, the following NIPs put a requirement on relays:

1, 4, 9, 11, 26, 29, 40, 42, 45, 50, 59, 65, 94, 96

The following NIPs add no specific relay requirements (beyond NIP-01)

2, 3, 5, 6, 7, 8, 10, 13, 14, 15, 18, 19, 21, 23, 24, 25, 27, 28, 30, 31, 32, 34, 36, 38, 39, 44, 46, 47, 48, 49, 51, 52, 53, 56, 57, 58, 72, 75, 78, 84, 89, 90, 92, 98, 99

mikedilger avatar Apr 09 '24 22:04 mikedilger

I think what's more interesting than what NIPs are supported is what types the relay accepts. From what I understand, the blocking on the relays is being done by the kind, and the connection between NIP and kind is not so clear.

I imagine that having a "white_list" and a "black_list" of kind would be more useful for clients to understand what they can send to each relay.

frbitten avatar Apr 24 '24 13:04 frbitten

@frbitten it would also be easier to automate. I'm working on a feature that shows publish failures, and it gets clogged up because fiatjaf's relay rejects kind 7s.

staab avatar Apr 24 '24 19:04 staab

I think what's more interesting than what NIPs are supported is what types the relay accepts.

I agree. But NIPs do go beyond just types. Deletion, for example. I guess you could just assume if it accepts that type it processes it too.

mikedilger avatar Apr 25 '24 00:04 mikedilger

nostr relays are quickly migrating from I will accept everything to I only accept what I want and block the rest.
If there is no simple way for customers to know, this will greatly complicate customer use. Because the tendency is to have several writing relays for different types.

frbitten avatar Apr 25 '24 09:04 frbitten