-
@ dolu
2025-04-30 19:27:41Nostr is a decentralized protocol designed to be censorship-resistant.
However, this resilience can sometimes make data synchronization between relays more difficult—though not impossible.In my opinion, Nostr still lacks a few key features to ensure consistent and reliable operation, especially regarding data versioning.
Profile Versions
When I log in to a new Nostr client using my private key, I might end up with an outdated version of my profile, depending on how the client is built or configured.
Why does this happen?
The client fetches my profile data (kind:0 - NIP 1) from its own list of selected relays.
If I didn’t publish the latest version of my profile on those specific relays, the client will only display an older version.Relay List Metadata
The same issue occurs with the relay list metadata (kind:10002 - NIP 65).
When switching to a new client, it's common that my configured relay list isn't properly carried over because it also depends on where the data is fetched.Protocol Change Proposal
I believe the protocol should evolve, specifically regarding how
kind:0
(user metadata) andkind:10002
(relay list metadata) events are distributed to relays.Relays should be able to build a list of public relays automatically (via autodiscovery), and forward all received
kind:0
andkind:10002
events to every relay in that list.This would create a ripple effect:
``` Relay A relay list: [Relay B, Relay C]
Relay B relay list: [Relay A, Relay C]
Relay C relay list: [Relay A, Relay B]User A sends kind:0 to Relay A
→ Relay A forwards kind:0 to Relay B
→ Relay A forwards kind:0 to Relay C
→ Relay B forwards kind:0 to Relay A
→ Relay B forwards kind:0 to Relay C → Relay A forwards kind:0 to Relay B
→ etc. ```Solution: Event Encapsulation
To avoid infinite replication loops, the solution could be to wrap the user’s signed event inside a new event signed by the relay, using a dedicated
kind
(e.g.,kind:9999
).When Relay B receives a
kind:9999
event from Relay A, it extracts the original event, checks whether it already exists or if a newer version is present. If not, it adds the event to its database.Here is an example of such encapsulated data:
json { "content": "{\"content\":\"{\\\"lud16\\\":\\\"dolu@npub.cash\\\",\\\"name\\\":\\\"dolu\\\",\\\"nip05\\\":\\\"dolu@dolu.dev\\\",\\\"picture\\\":\\\"!(image)[!(image)[https://pbs.twimg.com/profile_images/1577320325158682626/igGerO9A_400x400.jpg]]\\\",\\\"pubkey\\\":\\\"59b96df8d8b5e66b3b95a3e1ba159750a6edd69bcbba1857aeb652a5b208bd59\\\",\\\"npub\\\":\\\"npub1txukm7xckhnxkwu450sm59vh2znwm45mewaps4awkef2tvsgh4vsf7phrl\\\",\\\"created_at\\\":1688312044}\",\"created_at\":1728233747,\"id\":\"afc3629314aad00f8786af97877115de30c184a25a48440a480bff590a0f9ba8\",\"kind\":0,\"pubkey\":\"59b96df8d8b5e66b3b95a3e1ba159750a6edd69bcbba1857aeb652a5b208bd59\",\"sig\":\"989b250f7fd5d4cfc9a6ee567594c81ee0a91f972e76b61332005fb02aa1343854104fdbcb6c4f77ae8896acd886ab4188043c383e32a6bba509fd78fedb984a\",\"tags\":[]}", "created_at": 1746036589, "id": "efe7fa5844c5c4428fb06d1657bf663d8b256b60c793b5a2c5a426ec773c745c", "kind": 9999, "pubkey": "79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798", "sig": "219f8bc840d12969ceb0093fb62f314a1f2e19a0cbe3e34b481bdfdf82d8238e1f00362791d17801548839f511533461f10dd45cd0aa4e264d71db6844f5e97c", "tags": [] }