<rss
      xmlns:atom="http://www.w3.org/2005/Atom"
      xmlns:media="http://search.yahoo.com/mrss/"
      xmlns:content="http://purl.org/rss/1.0/modules/content/"
      xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
      xmlns:dc="http://purl.org/dc/elements/1.1/"
      version="2.0"
    >
      <channel>
        <title><![CDATA[hodlbod]]></title>
        <description><![CDATA[Christian Bitcoiner and developer of the coracle.social nostr client.
Learn more at https://coracle.tools]]></description>
        <link>https://hodlbod.npub.pro/tag/relays/</link>
        <atom:link href="https://hodlbod.npub.pro/tag/relays/rss/" rel="self" type="application/rss+xml"/>
        <itunes:new-feed-url>https://hodlbod.npub.pro/tag/relays/rss/</itunes:new-feed-url>
        <itunes:author><![CDATA[ hodlbod]]></itunes:author>
        <itunes:subtitle><![CDATA[Christian Bitcoiner and developer of the coracle.social nostr client.
Learn more at https://coracle.tools]]></itunes:subtitle>
        <itunes:type>episodic</itunes:type>
        <itunes:owner>
          <itunes:name><![CDATA[ hodlbod]]></itunes:name>
          <itunes:email><![CDATA[ hodlbod]]></itunes:email>
        </itunes:owner>
            
      <pubDate>Fri, 22 Nov 2024 22:14:03 GMT</pubDate>
      <lastBuildDate>Fri, 22 Nov 2024 22:14:03 GMT</lastBuildDate>
      
      <itunes:image href="https://i.nostr.build/AZ0L.jpg" />
      <image>
        <title><![CDATA[hodlbod]]></title>
        <link>https://hodlbod.npub.pro/tag/relays/</link>
        <url>https://i.nostr.build/AZ0L.jpg</url>
      </image>
      <item>
      <title><![CDATA[Why not NIP 29?]]></title>
      <description><![CDATA[Why I didn't use NIP 29 to build Flotilla... and why I still might.]]></description>
             <itunes:subtitle><![CDATA[Why I didn't use NIP 29 to build Flotilla... and why I still might.]]></itunes:subtitle>
      <pubDate>Fri, 22 Nov 2024 22:14:03 GMT</pubDate>
      <link>https://hodlbod.npub.pro/post/1732313518416/</link>
      <comments>https://hodlbod.npub.pro/post/1732313518416/</comments>
      <guid isPermaLink="false">naddr1qqxnzdenxgenzve4xyurgvfkqgsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgsrqsqqqa28szj7a7</guid>
      <category>nostr</category>
      
        <media:content url="https://image.nostr.build/c627d8da39158bac9e1ac4c4e163028f5cd4249f1622c78398d738937e49a093.jpg" medium="image"/>
        <enclosure 
          url="https://image.nostr.build/c627d8da39158bac9e1ac4c4e163028f5cd4249f1622c78398d738937e49a093.jpg" length="0" 
          type="image/jpeg" 
        />
      <noteId>naddr1qqxnzdenxgenzve4xyurgvfkqgsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgsrqsqqqa28szj7a7</noteId>
      <npub>npub1jlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qdjynqn</npub>
      <dc:creator><![CDATA[ hodlbod]]></dc:creator>
      <content:encoded><![CDATA[<p>This week I finally released Flotilla, a discord/slack-like client I've been working on for about three months. This project began as a NIP 29 client, and after 3 PRs, lots of discussion, a podcast, and a partial implementation, I decided to go my own way.</p>
<p>This of course means that I broke compatibility with all the NIP 29 group clients out there, but I did it for good reasons. In this post I hope to explain those reasons, and speculate on how best to move forward with "relay-based" groups on nostr.</p>
<p>To give you some quick context, NIP 29 and my approach to groups (which I'll dub "relays-as-groups" for clarity) are very similar, with a fundamental difference. Both have chat, join requests, group metadata, membership, moderation, etc. However, the basic unit of a NIP 29 group is a random group id string, while the basic unit of a Flotilla group is a relay itself.</p>
<p>I believe this design difference emerged in part because of what we were attempting to build. NIP 29 groups tend to be more telegram-like, where groups function more like chat rooms, and users join each one individually. On flotilla, groups function more like Discord servers, or Slack workspaces, and users join an entire group of chat rooms at once.</p>
<p>"Relays as groups" has four major advantages over "groups hosted by relays".</p>
<h1>Decentralization</h1>
<p>First, using relays as groups supports decentralization better than hosting user-managed groups on relays.</p>
<p>(To be clear here, I'm not referring to client-managed groups, which is a whole different approach that we've experimented with in the past, both with NIP 72 communities and with <a href="https://github.com/nostr-protocol/nips/pull/875">NIP 87</a> encrypted groups. Both NIP 29 and relays-as-groups solve many of the consistency problems associated with attempting to have a linear, synchronous conversation across multiple relays. While both alternatives have a story for migrating or mirroring a group, both rely heavily on the host relay to not censor user messages.)</p>
<p>I know what you're thinking. How can <em>reducing</em> the number of relays <em>improve</em> decentralization? Relays were originally introduced in order to create redundancy and spread trust across many actors, creating censorship resistance. This model was difficult for many bitcoiners to wrap their heads around, because it's a very different kind of decentralization than what a blockchain delivers.</p>
<p>Communities are an essentially different use case from a broadcast network where content is delivered based on author or recipient relay selections. Every message to a community would have to be delivered to all members of the community. Sending each message to all members' personal inbox relays just doesn't make sense; there has to be some other inbox for the community to work off of.</p>
<p>Additionally, online communities almost always have moderators and admins. This is even true of very public, open types of communities, like subreddits. The only type of community that doesn't have moderators is one that emerges naturally from social clustering. And even in that case there is loose consensus about who is in and who isn't, based on the actions/follows/mutes of the participants, whether these clusters are huge or tiny. Socially-emergent groups are served well by chat applications or broadcast networks.</p>
<p>But the subset of online communities that do prefer to confer moderator status on certain members are <em>essentially centralized</em>. In other words, centralization and control is a feature, not a bug.</p>
<p>Now, that doesn't mean there don't need to be considerations around credible exit and removing/adding moderators over time. But the fact is that moderator-led communities are always under the oversight of the moderators at any given time, even if the identity of those moderators changes and their power is limited.</p>
<p>What this implies is that decentralization for moderator-led groups looks very different from decentralization for a broadcast network. There is nothing at all wrong with giving moderators full control over the group's communications (qua the group; DMs and public broadcast content between group members should happen outside the group's infrastructure, just as people also exist outside the communities they are a part of). What is important is that no one has control over groups that they aren't nominally the admin of.</p>
<p>In concrete terms, what this all means is that community moderators should self-host their infrastructure. This is the same principle as motivates self-custody and home servers, but applied to communities. If community leaders manage their own relays, this means that no hosting company or relay admin can de-platform their community. Centralization of network infrastructure in this case aligns with the trust structure of the group.</p>
<p>Applying this to our group dilemma, it's easy to see that NIP 29 groups are more vulnerable to censorship or data harvesting attacks by malicious relay admins, since many unrelated groups might live on a single relay. In contrast, if you treat relays as groups themselves, every group is forced to live on a separate relay, spreading risk across more hosting providers.</p>
<p>Now, this doesn't necessarily mean that many "relays" aren't "virtual relays" managed by the same hosting provider. So I'll admit that even "relay-based" groups don't completely solve this problem. But I think it will tend to nudge community organizers toward thinking about community infrastructure in a more self-sovereign (or community-sovereign) way.</p>
<h1>Investment in Relays</h1>
<p>While both NIP 29 and relays-as-groups rely heavily on relays to implement the features that support each specification, there's an important difference between the feature sets. In NIP 29, relay support is specific only to groups, and isn't applicable to other use cases. In contrast, every protocol feature added to support the "relays as groups" can be re-purposed for other types of relays.</p>
<p>Take join requests for example. NIP 29's kind <code>9021</code> events allow users to request access to a group, and that's all. <a href="https://github.com/nostr-protocol/nips/pull/1079">Kind <code>28934</code> join requests</a> on the other hand allow users to request access to relays. Which in the relays-as-groups model means group access, but it also means custom feed access, inbox relay access, maybe even blossom server access. In fact, kind <code>28934</code> was originally proposed at the beginning of this year in order to support a different version of hosted groups, but remains as relevant as it ever was despite iteration on groups.</p>
<p>The orthogonality of features added to relays to any specific use case will long-term result in simpler specs, and more interesting relay-based use cases being possible. Join requests are only one example. The same is true of 1984-based moderation, the proposed LIMITS command, AUTH, NIP 11 relay metadata, etc.</p>
<p>We already have web of trust relays, feed relays, archival relays, and <a href="https://github.com/nostr-protocol/nips/issues/1282">many more</a>. Being able to request access to closed versions of these is useful. Being able to signal federation between multiple instances of these, run by different people, is useful. And of course, relay metadata, reports, and LIMITS are self-evidently useful for normal relays, since they pre-date Flotilla.</p>
<p>I've always said that relays are some of the coolest and most under-appreciated parts of nostr. This doesn't mean that we should add every possible feature to them, but features related to data curation and access control fit really well with what relays are good for. For more on the role of relays and what features should be added to them, see my nostrasia talk <a href="https://www.youtube.com/watch?v=R-5DHymkfzw">Functional Relays</a>.</p>
<h1>Declarative vs Imperative</h1>
<p>A common paradigm in programming is that of declarative vs imperative programming. Imperative programming focuses on "how" to achieve a given result, leaving "what" the code is doing to be inferred by the programmer. Declarative programming instead focuses on the "what", and allows some underlying implementation to solve the how. A good balance between these paradigms (and knowing when to use one over the other) allows programmers to work faster, make fewer mistakes, and produce less code.</p>
<p>Another way to look at this is that a specification should contain as much ambiguity as possible, but without compromising the system attributes the specification is supposed to guarantee. It can get complex when figuring out what attributes are core to the specification, since sometimes the "how" does actually matter a lot.</p>
<p>However, nostr in particular falls pretty far along the "declarative" end of this spectrum because of its decentralized nature. The only person who can say anything with any authority is the person who signs an event. This event is a "declaration", and any effects it has are necessarily up to the relays, clients, and people interpreting the event. However, what others do with an event is an expectation that must be taken into account by the publisher, forming a feedback loop. This dialectic is what creates stability in the protocol.</p>
<p>In more concrete terms, no one can "tell" anyone else what they have to do by publishing an event like you might in a traditional, centralized RPC-type system. Any event whose semantics are a "command" rather than a "fact" or "request" is broken unless the counter party is fully committed to carrying out the command. An example of a "command" scenario on nostr is NIP 46 remote signing, in which the bunker is the agent of the user making the request. If the bunker implementation fails to carry out a valid command initiated by the user, its interpretation of that event is objectively incorrect.</p>
<p>NIP 29 applies this same paradigm to relays, particularly in the area of moderation, membership edits, and group metadata. In other words, there are several "commands" which instruct the relay to do something.</p>
<p>This isn't necessarily a bad thing, but it does increase the number of things the interface between the client and relay have to agree on. A regular relay may accept an <code>add-user</code> request, but then do nothing with it, violating the contract it has implicitly accepted with the user. The solution to this is feature detection, which is a whole other API to be specified and implemented.</p>
<p>My ideal solution to this problem is to shift the semantics of events away from "commands" to "facts" - in other words, to make the interface more declarative.</p>
<p>In fact, we already have an interface for moderation that works like this. Many clients support kind <code>1984</code> "report" events. Users sending these reports have no expectations about how they will be used. They are a "fact", a declaration of opinion with certain semantics. Other actors in the network may choose whether or not to pay attention to these.</p>
<p>This same model is easily applied to communities. Without having to implement any feature detection (either for the relay's implementation, or for the user's role on that relay), anyone can simply send a "report". This goes into the black hole of the relay, and may subsequently be ignored, broadcasted, or acted on.</p>
<p>The really nice thing about this model is that because there is no expectation for "how" reports are to be interpreted, any approach to moderation can be used depending on relay policy or client implementation. In NIP 29, if you issue a <code>delete-event</code>, it either happens or it doesn't and if it doesn't, you have to explain the failure to the user somehow.</p>
<p>In the relays-as-groups model, e-tagging an event in a kind <code>1984</code> requires no user feedback, and therefore it can be interpreted however the relay prefer. This can result in insta-banning, manual review, thresholds based on number of reporters, a leaky-bucket social score algorithm, shadow banning, temporary banning, soft-moderation by allowing clients to request reports and respond to them by changing user interface elements, or anything else you can think of.</p>
<p>The reason I think this is important is that community moderation is a <em>very</em> hard problem, and baking certain semantics into the specification can result in the complete failure of the spec. NIP 72 should be considered an example of what not to do. Some NIP 72 communities have survived due to the dedication of the moderators, but many more have failed because of the rigid moderation model. We should try not to make the same mistake again.</p>
<h1>Conclusion</h1>
<p>Now, having said all that, I think there is actually a lot of value to NIP 29. What finally clicked for me this week after releasing Flotilla is that the two approaches are actually complementary to one another. One of the most common feature requests I've already heard for flotilla is to have more complete support for rooms, which are currently implemented as not much more than hashtags. Better rooms (i.e., "nested groups") would require: authentication, membership, moderation, and pretty much everything else that exists for the top-level group.</p>
<p>As much as I believe the relays-as-groups approach is superior to NIP 29 for top-level groups, it doesn't make any sense to try to "nest" relays to create sub-groups. Something like NIP 29 is needed in order to fully support rooms anyway, so I think the convergence of the two approaches is all but inevitable. In fact, fiatjaf has already merged a <a href="https://github.com/nostr-protocol/nips/pull/1591">PR</a> which will allow me to use the same event kinds in flotilla as exist already in NIP 29 clients.</p>
<p>There are just a few more changes that are necessary in order for me to fully adopt NIP 29 in Flotilla:</p>
<ul>
<li><a href="https://github.com/nostr-protocol/nips/pull/1604">NIP 29 feature detection</a></li>
<li><a href="https://github.com/nostr-protocol/nips/pull/1603">Opaque ids for unmanaged groups prevent unmanaged groups from having human-readable names</a></li>
<li><a href="https://github.com/nostr-protocol/nips/pull/1602">We need a mechanism for building membership lists without relay support</a></li>
<li><a href="https://github.com/nostr-protocol/nips/pull/1601">Better handling for <code>9021</code> group join requests</a></li>
</ul>
<p>I've opened PRs for each of these (linked above). Hopefully we can work through these issues and combine our powers to become the Captain Planet of group implementations.</p>
]]></content:encoded>
      <itunes:author><![CDATA[ hodlbod]]></itunes:author>
      <itunes:summary><![CDATA[<p>This week I finally released Flotilla, a discord/slack-like client I've been working on for about three months. This project began as a NIP 29 client, and after 3 PRs, lots of discussion, a podcast, and a partial implementation, I decided to go my own way.</p>
<p>This of course means that I broke compatibility with all the NIP 29 group clients out there, but I did it for good reasons. In this post I hope to explain those reasons, and speculate on how best to move forward with "relay-based" groups on nostr.</p>
<p>To give you some quick context, NIP 29 and my approach to groups (which I'll dub "relays-as-groups" for clarity) are very similar, with a fundamental difference. Both have chat, join requests, group metadata, membership, moderation, etc. However, the basic unit of a NIP 29 group is a random group id string, while the basic unit of a Flotilla group is a relay itself.</p>
<p>I believe this design difference emerged in part because of what we were attempting to build. NIP 29 groups tend to be more telegram-like, where groups function more like chat rooms, and users join each one individually. On flotilla, groups function more like Discord servers, or Slack workspaces, and users join an entire group of chat rooms at once.</p>
<p>"Relays as groups" has four major advantages over "groups hosted by relays".</p>
<h1>Decentralization</h1>
<p>First, using relays as groups supports decentralization better than hosting user-managed groups on relays.</p>
<p>(To be clear here, I'm not referring to client-managed groups, which is a whole different approach that we've experimented with in the past, both with NIP 72 communities and with <a href="https://github.com/nostr-protocol/nips/pull/875">NIP 87</a> encrypted groups. Both NIP 29 and relays-as-groups solve many of the consistency problems associated with attempting to have a linear, synchronous conversation across multiple relays. While both alternatives have a story for migrating or mirroring a group, both rely heavily on the host relay to not censor user messages.)</p>
<p>I know what you're thinking. How can <em>reducing</em> the number of relays <em>improve</em> decentralization? Relays were originally introduced in order to create redundancy and spread trust across many actors, creating censorship resistance. This model was difficult for many bitcoiners to wrap their heads around, because it's a very different kind of decentralization than what a blockchain delivers.</p>
<p>Communities are an essentially different use case from a broadcast network where content is delivered based on author or recipient relay selections. Every message to a community would have to be delivered to all members of the community. Sending each message to all members' personal inbox relays just doesn't make sense; there has to be some other inbox for the community to work off of.</p>
<p>Additionally, online communities almost always have moderators and admins. This is even true of very public, open types of communities, like subreddits. The only type of community that doesn't have moderators is one that emerges naturally from social clustering. And even in that case there is loose consensus about who is in and who isn't, based on the actions/follows/mutes of the participants, whether these clusters are huge or tiny. Socially-emergent groups are served well by chat applications or broadcast networks.</p>
<p>But the subset of online communities that do prefer to confer moderator status on certain members are <em>essentially centralized</em>. In other words, centralization and control is a feature, not a bug.</p>
<p>Now, that doesn't mean there don't need to be considerations around credible exit and removing/adding moderators over time. But the fact is that moderator-led communities are always under the oversight of the moderators at any given time, even if the identity of those moderators changes and their power is limited.</p>
<p>What this implies is that decentralization for moderator-led groups looks very different from decentralization for a broadcast network. There is nothing at all wrong with giving moderators full control over the group's communications (qua the group; DMs and public broadcast content between group members should happen outside the group's infrastructure, just as people also exist outside the communities they are a part of). What is important is that no one has control over groups that they aren't nominally the admin of.</p>
<p>In concrete terms, what this all means is that community moderators should self-host their infrastructure. This is the same principle as motivates self-custody and home servers, but applied to communities. If community leaders manage their own relays, this means that no hosting company or relay admin can de-platform their community. Centralization of network infrastructure in this case aligns with the trust structure of the group.</p>
<p>Applying this to our group dilemma, it's easy to see that NIP 29 groups are more vulnerable to censorship or data harvesting attacks by malicious relay admins, since many unrelated groups might live on a single relay. In contrast, if you treat relays as groups themselves, every group is forced to live on a separate relay, spreading risk across more hosting providers.</p>
<p>Now, this doesn't necessarily mean that many "relays" aren't "virtual relays" managed by the same hosting provider. So I'll admit that even "relay-based" groups don't completely solve this problem. But I think it will tend to nudge community organizers toward thinking about community infrastructure in a more self-sovereign (or community-sovereign) way.</p>
<h1>Investment in Relays</h1>
<p>While both NIP 29 and relays-as-groups rely heavily on relays to implement the features that support each specification, there's an important difference between the feature sets. In NIP 29, relay support is specific only to groups, and isn't applicable to other use cases. In contrast, every protocol feature added to support the "relays as groups" can be re-purposed for other types of relays.</p>
<p>Take join requests for example. NIP 29's kind <code>9021</code> events allow users to request access to a group, and that's all. <a href="https://github.com/nostr-protocol/nips/pull/1079">Kind <code>28934</code> join requests</a> on the other hand allow users to request access to relays. Which in the relays-as-groups model means group access, but it also means custom feed access, inbox relay access, maybe even blossom server access. In fact, kind <code>28934</code> was originally proposed at the beginning of this year in order to support a different version of hosted groups, but remains as relevant as it ever was despite iteration on groups.</p>
<p>The orthogonality of features added to relays to any specific use case will long-term result in simpler specs, and more interesting relay-based use cases being possible. Join requests are only one example. The same is true of 1984-based moderation, the proposed LIMITS command, AUTH, NIP 11 relay metadata, etc.</p>
<p>We already have web of trust relays, feed relays, archival relays, and <a href="https://github.com/nostr-protocol/nips/issues/1282">many more</a>. Being able to request access to closed versions of these is useful. Being able to signal federation between multiple instances of these, run by different people, is useful. And of course, relay metadata, reports, and LIMITS are self-evidently useful for normal relays, since they pre-date Flotilla.</p>
<p>I've always said that relays are some of the coolest and most under-appreciated parts of nostr. This doesn't mean that we should add every possible feature to them, but features related to data curation and access control fit really well with what relays are good for. For more on the role of relays and what features should be added to them, see my nostrasia talk <a href="https://www.youtube.com/watch?v=R-5DHymkfzw">Functional Relays</a>.</p>
<h1>Declarative vs Imperative</h1>
<p>A common paradigm in programming is that of declarative vs imperative programming. Imperative programming focuses on "how" to achieve a given result, leaving "what" the code is doing to be inferred by the programmer. Declarative programming instead focuses on the "what", and allows some underlying implementation to solve the how. A good balance between these paradigms (and knowing when to use one over the other) allows programmers to work faster, make fewer mistakes, and produce less code.</p>
<p>Another way to look at this is that a specification should contain as much ambiguity as possible, but without compromising the system attributes the specification is supposed to guarantee. It can get complex when figuring out what attributes are core to the specification, since sometimes the "how" does actually matter a lot.</p>
<p>However, nostr in particular falls pretty far along the "declarative" end of this spectrum because of its decentralized nature. The only person who can say anything with any authority is the person who signs an event. This event is a "declaration", and any effects it has are necessarily up to the relays, clients, and people interpreting the event. However, what others do with an event is an expectation that must be taken into account by the publisher, forming a feedback loop. This dialectic is what creates stability in the protocol.</p>
<p>In more concrete terms, no one can "tell" anyone else what they have to do by publishing an event like you might in a traditional, centralized RPC-type system. Any event whose semantics are a "command" rather than a "fact" or "request" is broken unless the counter party is fully committed to carrying out the command. An example of a "command" scenario on nostr is NIP 46 remote signing, in which the bunker is the agent of the user making the request. If the bunker implementation fails to carry out a valid command initiated by the user, its interpretation of that event is objectively incorrect.</p>
<p>NIP 29 applies this same paradigm to relays, particularly in the area of moderation, membership edits, and group metadata. In other words, there are several "commands" which instruct the relay to do something.</p>
<p>This isn't necessarily a bad thing, but it does increase the number of things the interface between the client and relay have to agree on. A regular relay may accept an <code>add-user</code> request, but then do nothing with it, violating the contract it has implicitly accepted with the user. The solution to this is feature detection, which is a whole other API to be specified and implemented.</p>
<p>My ideal solution to this problem is to shift the semantics of events away from "commands" to "facts" - in other words, to make the interface more declarative.</p>
<p>In fact, we already have an interface for moderation that works like this. Many clients support kind <code>1984</code> "report" events. Users sending these reports have no expectations about how they will be used. They are a "fact", a declaration of opinion with certain semantics. Other actors in the network may choose whether or not to pay attention to these.</p>
<p>This same model is easily applied to communities. Without having to implement any feature detection (either for the relay's implementation, or for the user's role on that relay), anyone can simply send a "report". This goes into the black hole of the relay, and may subsequently be ignored, broadcasted, or acted on.</p>
<p>The really nice thing about this model is that because there is no expectation for "how" reports are to be interpreted, any approach to moderation can be used depending on relay policy or client implementation. In NIP 29, if you issue a <code>delete-event</code>, it either happens or it doesn't and if it doesn't, you have to explain the failure to the user somehow.</p>
<p>In the relays-as-groups model, e-tagging an event in a kind <code>1984</code> requires no user feedback, and therefore it can be interpreted however the relay prefer. This can result in insta-banning, manual review, thresholds based on number of reporters, a leaky-bucket social score algorithm, shadow banning, temporary banning, soft-moderation by allowing clients to request reports and respond to them by changing user interface elements, or anything else you can think of.</p>
<p>The reason I think this is important is that community moderation is a <em>very</em> hard problem, and baking certain semantics into the specification can result in the complete failure of the spec. NIP 72 should be considered an example of what not to do. Some NIP 72 communities have survived due to the dedication of the moderators, but many more have failed because of the rigid moderation model. We should try not to make the same mistake again.</p>
<h1>Conclusion</h1>
<p>Now, having said all that, I think there is actually a lot of value to NIP 29. What finally clicked for me this week after releasing Flotilla is that the two approaches are actually complementary to one another. One of the most common feature requests I've already heard for flotilla is to have more complete support for rooms, which are currently implemented as not much more than hashtags. Better rooms (i.e., "nested groups") would require: authentication, membership, moderation, and pretty much everything else that exists for the top-level group.</p>
<p>As much as I believe the relays-as-groups approach is superior to NIP 29 for top-level groups, it doesn't make any sense to try to "nest" relays to create sub-groups. Something like NIP 29 is needed in order to fully support rooms anyway, so I think the convergence of the two approaches is all but inevitable. In fact, fiatjaf has already merged a <a href="https://github.com/nostr-protocol/nips/pull/1591">PR</a> which will allow me to use the same event kinds in flotilla as exist already in NIP 29 clients.</p>
<p>There are just a few more changes that are necessary in order for me to fully adopt NIP 29 in Flotilla:</p>
<ul>
<li><a href="https://github.com/nostr-protocol/nips/pull/1604">NIP 29 feature detection</a></li>
<li><a href="https://github.com/nostr-protocol/nips/pull/1603">Opaque ids for unmanaged groups prevent unmanaged groups from having human-readable names</a></li>
<li><a href="https://github.com/nostr-protocol/nips/pull/1602">We need a mechanism for building membership lists without relay support</a></li>
<li><a href="https://github.com/nostr-protocol/nips/pull/1601">Better handling for <code>9021</code> group join requests</a></li>
</ul>
<p>I've opened PRs for each of these (linked above). Hopefully we can work through these issues and combine our powers to become the Captain Planet of group implementations.</p>
]]></itunes:summary>
      <itunes:image href="https://image.nostr.build/c627d8da39158bac9e1ac4c4e163028f5cd4249f1622c78398d738937e49a093.jpg"/>
      </item>
      
      <item>
      <title><![CDATA[What is the Outbox Model?]]></title>
      <description><![CDATA[An explainer on the Outbox Model, including what it is, where it came from, and why it's integral to making nostr work.]]></description>
             <itunes:subtitle><![CDATA[An explainer on the Outbox Model, including what it is, where it came from, and why it's integral to making nostr work.]]></itunes:subtitle>
      <pubDate>Thu, 29 Aug 2024 00:50:27 GMT</pubDate>
      <link>https://hodlbod.npub.pro/post/8yjqxm4sky-tauwjoflxs/</link>
      <comments>https://hodlbod.npub.pro/post/8yjqxm4sky-tauwjoflxs/</comments>
      <guid isPermaLink="false">naddr1qq2nskt2w9vx6dznfdvj64rpw4mk5nmxf3v9xq3qjlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qxpqqqp65wzfj8s4</guid>
      <category>nostr</category>
      
        <media:content url="https://yakihonne.s3.ap-east-1.amazonaws.com/97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322/files/1724892627307-YAKIHONNES3.jpg" medium="image"/>
        <enclosure 
          url="https://yakihonne.s3.ap-east-1.amazonaws.com/97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322/files/1724892627307-YAKIHONNES3.jpg" length="0" 
          type="image/jpeg" 
        />
      <noteId>naddr1qq2nskt2w9vx6dznfdvj64rpw4mk5nmxf3v9xq3qjlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qxpqqqp65wzfj8s4</noteId>
      <npub>npub1jlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qdjynqn</npub>
      <dc:creator><![CDATA[ hodlbod]]></dc:creator>
      <content:encoded><![CDATA[<p>Nostr is a mess. It always has been and will always be. That's part of the appeal! But it's important that users be able to navigate the rolling seas of this highly partition-tolerant network of kaleidoscopically-interwoven people, bots, topics, relays, clients, events, recommendations, lists, feeds, micro-apps, macro-apps, Chinese spam, and "GM"s.</p>
<p>In order to do this, users must be able to articulate "what" they are looking for, and clients must be able to articulate "how" to find that thing. This "how" is divided into two parts: building a request that will match the desired content (very easy), and selecting a relay that is able to serve that content to the user requesting it (very very hard).</p>
<h1>Why guessing isn't good enough</h1>
<p>As a concrete example, let's say the user wants to find everyone in their "network" who is using a particular topic. The process would look something like this:</p>
<ol>
<li>The user clicks the "network" tab and types in the topic they want to browse. This is the "what".</li>
<li>The client then translates the term "network" to a list of public keys using whatever definition they prefer (Follows? WoT? Grapevine?), and builds a filter that might look something like this: <code>[{"authors": pubkeys, "#t": ["mytopic"]}]</code>. Any relay will happily accept, understand, and respond to that filter.</li>
<li>The client then has to decide which relays it should send that filter to. This is the <code>???</code> stage of the outbox model, which immediately precedes:</li>
<li>Profit</li>
</ol>
<p>It may not be immediately obvious why selecting the correct relays might be difficult. Most people post to relay.damus.io, and most people read from relay.damus.io, so in most cases you should be good, right?</p>
<p>This approach to relay selection has historically worked "well enough", but it depends on a flawed definition of success. If you only want to find 90% of the content that matches your query, using the top 10 relays will suffice. But nostr is intended to be censorship-resistant. What if those 10 hubs have banned a particular public key? Nostr clients should (at least in theory) be 100% successful in retrieving requested content. Even if someone only posts to their self-hosted relay, you should be able to find their notes if their account is set up properly.</p>
<h1>A naive solution to fixing the FOMO</h1>
<p>A 90% hit rate results in a feeling of flakiness, even if users aren't completely aware of what isn't working. Feeds will be incomplete, quoted notes will be missing, replies will be orphaned, user profiles won't load. The natural response to the FOMO this creates is for users to "try harder" by adding more relays.</p>
<p>On the read side, this means clients open more connections, resulting in much higher data transfer requirements, with massively diminishing returns, since there's no reason to expect that a randomly chosen relay will have a substantially different data set.</p>
<p>One the publish side, this means that clients end up publishing more copies of their data to more relays. This approach has been automated in the past by services like Blastr, which don't store a copy of events published to the relay, but instead forward events to the top 300 relays in the network. This results in a two-orders-of-magnitude increase in storage required, and only makes the read side of the problem worse, since it reduces the uniqueness of the data set each relay stores. This in turn means that more duplicates are retrieved when querying relays.</p>
<p>Both halves of this approach are equivalent to guessing. On the read side, users are guessing which relays will have any arbitrary content they might ask for in the future. On the write side, users are guessing which relays other people might use to find their notes. It is a brute-force method for finding content.</p>
<h1>Randomness results in centralization</h1>
<p>In theory, random relay selection would result in a perfect distribution of content across all relays in the network. But in practice, this method of selection isn't random at all, but is strongly influenced by user bias in what constitutes a "good" relay. While some users may check <a href="https://nostr.watch">nostr.watch</a> for ping times, geographical proximity, or uptime, most will choose relays based on familiar names or other people's recommendations.</p>
<p>In either case, these biases are entirely orthogonal to achieving a higher content retrieval hit rate, <em>except when bias in relay selection results in clustering</em> — i.e., centralization. In other words, the kind of randomness exhibited by users when selecting relays actually results in pretty much everyone picking the same few relays. We see this same effect when people try to come up with passwords or seed phrases — human-provided randomness is anything but random.</p>
<p>Clustering improves the hit rate when requesting events (slightly), but it results in nearly as much centralization as if only a single relay was used —&nbsp;and a lot more duplicate events.</p>
<h1>Something (anything) other than randomness</h1>
<p>In early 2023, Mike Dilger <a href="https://github.com/nostr-protocol/nips/pull/218">introduced NIP 65</a> (now known as the "Outbox Model") with a problem statement in the spirit of the original description of nostr: "Nostr should scale better. People should be able to find what they want."</p>
<p><em>Historical note: NIP 65 was formerly known as the "Gossip Model", derived from the name of Mike's <a href="https://github.com/mikedilger/gossip">desktop nostr client</a>, called "Gossip". This unfortunately created a lot of confusion, since <a href="https://en.wikipedia.org/wiki/Gossip_protocol">gossip protocols</a> work very differently from how nostr tends to work, hence the re-brand.</em></p>
<p>Before NIP 65, an informal standard existed in which <code>kind 3</code> user contact lists also included a list of relays that clients could use as something similar to Mastodon's "home servers". This list included the option to only read or write from a given relay. Unfortunately, it wasn't really clear what the semantics of this relay list were, so different clients handled them differently (and many clients ignored them). Usually this amounted to user-provided static relay configurations, which resulted in the naive relay selection approach described above.</p>
<p>NIP 65 used a very similar format (a list of relay urls with optional "read" or "write" directives), but with a very important semantic difference: relays listed in a user's <code>kind 10002</code> were intended to "advertise to others, not for configuring one's client." In other words, these relay selections were intended as a signal to other users that they should use certain relays when attempting to communicate with the author of the relay list.</p>
<p>I highly recommend reading the <a href="https://github.com/nostr-protocol/nips/blob/master/65.md">entire NIP</a>, which is very short and easy to read. But the mechanics of the spec are very simple:</p>
<blockquote>
<p>When seeking events&nbsp;<strong>from</strong>&nbsp;a user, Clients SHOULD use the WRITE relays of the user's&nbsp;<code>kind:10002</code>.</p>
<p>When seeking events&nbsp;<strong>about</strong>&nbsp;a user, where the user was tagged, Clients SHOULD use the READ relays of the user's&nbsp;<code>kind:10002</code>.</p>
<p>When broadcasting an event, Clients SHOULD:</p>
<ul>
<li>Broadcast the event to the WRITE relays of the author</li>
<li>Broadcast the event to all READ relays of each tagged user</li>
</ul>
</blockquote>
<p>For the first time, we had a way to differentiate relays in terms of <em>what content could be found where</em>.</p>
<p>When looking for a note by a particular user, a client could now look up the author's <code>write</code> relays according to their <code>kind 10002</code> event, and send its query there. The result is a much higher hit rate with much lower data transfer requirements, and fewer connections per query.</p>
<h1>Making Outbox Work</h1>
<p>There are of course some assumptions required to make this work. </p>
<p>First, the user must know which author they're looking for. This isn't always true when looking up a quote or parent note, but context and <a href="https://github.com/nostr-protocol/nips/pull/1171">pubkey hints</a> solve this difficulty in most cases.</p>
<p>The author must also publish a <code>kind 10002</code> event. This may not always be the case, but clients should prompt users to set up their relay list correctly. This isn't really a flaw in the Outbox Model, just in implementations of it.</p>
<p>Additionally, the user's client must be able to find the author's <code>kind 10002</code> event. This is the "bootstrapping" phase of the Outbox Model, during which the mechanisms the system provides for finding events aren't available. This requires us to fall back to randomly guessing which relays have the content we're looking for, which as we saw above doesn't work very well.</p>
<p>Other than guessing, there are a few different ways a client might find the relay selection event in question, each of which is applicable in different circumstances. In most cases, using one of a handful of indexer relays like <a href="wss://purplepag.es">purplepag.es</a> or <a href="wss://relay.nostr.band">relay.nostr.band</a> is a simple and efficient way to find user profiles and relay selections.</p>
<p>However, if an author's content has been aggressively purged from these indexers due to censorship, they obviously can't be relied upon. Even though the author in question hasn't been deplatformed from nostr itself (since he can always self-host a publicly accessible relay to store his content), he has been effectively shadow-banned.</p>
<p>To get around this, relay selections have to be communicated in some other way. Nostr has a few different mechanisms for this:</p>
<ul>
<li>If the author's NIP 05 address is known and properly configured (it may not be), clients can look up the author's NIP 05 endpoint to find some reasonable relay hints. Unfortunately, these are often neglected, and usually custodial, so they can run into the same problems.</li>
<li>If the author's pubkey is found in another signed event found on nostr, <a href="https://github.com/nostr-protocol/nips/blob/fade0164f52033314bf0a5ef9bd63c2483afae9b/10.md#marked-e-tags-preferred">relay hints</a> can be a way to propagate relay selections through the network. This relies on implementations picking reliable relay hints which can be difficult, and hints do tend to become less reliable over time. However, this strategy is very effective in resisting censorship because it makes banning viral — if a relay wants to completely purge a particular pubkey from their database, they have to purge every event that references it, since events are tamper-proof.</li>
<li>In extremis, relay recommendations can always be communicated out-of-band. This can be done using manual input, QR codes, DHTs, jsonl torrents full of <code>kind 10002</code> events, or any other mechanism client developers choose to resort to.</li>
</ul>
<p>Another, more technical assumption is that any given query can be fulfilled by few enough relays that a client can actually make all the connections needed, without running into resource limits. If you're trying to request content from 10,000 users across 1,000 relays, you're going to have a bad time. This was <a href="https://coracle.social/nevent1qythwumn8ghj76twvfhhstnwdaehgu3wwa5kuef0qyv8wumn8ghj7cm9d3kxzu3wdehhxarj9emkjmn99uq3samnwvaz7tmrwfjkzarj9ehx7um5wgh8w6twv5hsqgrn7l6zj7ht6ruyk76vvvtkfs4xrhyzc3tm64l3eyfvd40y26sz0gshmunh">pointed out</a> to me by Mazin of <a href="https://nostr.wine">nostr.wine</a>. He makes a good point, and it's definitely something to keep in mind. There are some mitigating factors though.</p>
<p>The first is that the current topology of the network probably won't persist forever. Because nostr is largely populated by self-hosting enthusiasts, the number of "tiny" relays is proportionally much higher than it will be if adoption picks up, even if the total number of relays grows. The trajectory is that nostr will drift toward fewer, larger relays, reducing the number of connections needed to fulfill any given query.</p>
<p>This is "centralizing", but it's important to understand that this isn't necessarily a bad thing. As long as there are more than one or two large hubs, there is user choice. And as long as it's possible to run a new relay, there is always an escape hatch. Nostr, like bitcoin, has no hard dependency on the biggest player in the network.</p>
<p>The other thing to consider is that there are lots of other techniques we can use to overcome the limits of the lowest-common denominator's limitations (mobile browser clients), including self hosted or third-party relay proxies. The trade-off here is that a little trust (aka centralization) can go a long way to reducing resource requirements needed to fulfill queries using the Outbox model.</p>
<p>If you're interested in more details on this topic, see <a href="https://habla.news/u/hodlbod@coracle.social/sfwV1rNaoQXd65PbIMYgm">this blog post</a>.</p>
<p>That was a long digression, but there is one other thing that the Outbox model assumes to be the case. Even if the correct relays are found and connected to, they still may not return all desired content, either because they don't have it, or because they refuse to return it to the user requesting it.</p>
<p>This can happen if the publishing client isn't following the Outbox Model, if the author had migrated from one relay set to another without copying their notes over, or if the relay in question chose not to retain the author's content for some reason.</p>
<p>The first two issues can be fixed by improving implementations, but the question of policy is a little more interesting.</p>
<h1>Relativistic relays</h1>
<p>The Outbox Model is a mechanical process; it's only as useful as user relay selections are. In order for it to work, users have to be able to make intelligent relay selections.</p>
<p>Every relay has trade-offs, depending on its policy. <a href="wss://140.f7z.io">140.f7z.io</a> would not be useful for long-form content, for example. Some relays might have a content retention policy that changes depending on whether you're a paying user. If you don't pay, you might find out too late that your content has been deleted from the relay.</p>
<p>So what makes a relay "good" for a particular use case? Well, it's complicated. Here are a few factors that go into that calculus:</p>
<ul>
<li>Is the relay in the same geographical as the user? Proximity reduces latency, but jurisdictional arbitrage might be desired. Users should probably have a variety of relays that fit different profiles.</li>
<li>Will the relay ban the user? Do the operators have a history of good behavior? Is the relay focused on particular types of content? Is the relay's focus consistent with the user's goal in adding that relay to their list?</li>
<li>What are the relay's retention policies? A user might want to set up an archival relay for her old content, or a multi-availability-zone relay so her notes are immediately accessible to the rest of the network.</li>
<li>Does the relay require payment? Paid relays are more aligned with their users, but obviously come at a financial cost.</li>
<li>Does the relay have policies for read-protecting content? If so, other users might not be able to find your posts published to that relay. On the other hand, some relays are configured to work as inboxes for direct messages, which can help preserve privacy.</li>
<li>Does the relay request that users authenticate? Authentication can help manage spam, but it also allows relays to correlate content requests with users, reducing user privacy.</li>
<li>Is the relay you use hosted by your client's developer? If so, you're in danger of getting banned from your client and your relay at the same time.</li>
<li>Is the relay a hub? Using hubs can help smooth out rough areas in Outbox Model implementations, at the cost of centralization.</li>
<li>Is the relay used by anyone else? One-off relays can be useful for archival purposes, but often won't be used by clients following the Outbox Model, depending on how they optimize requests.</li>
</ul>
<p>There are lots of ways to approach the problem of helping users select relays, but it's an inherently complex problem which very few people will have the patience to properly address on their own. Relay selection is a multi-dimensional problem, and requires satisfying multiple constraints with a limited number of relay selections.</p>
<p>In the future, special-purpose clients might be used to help people build relay sets. Clients also might provide curated "relay kits" that users can choose and customize. Or, we might see an increase in hybrid solutions, like smarter relay proxies or client-local relays that synchronize using other protocols or platforms.</p>
<h1>The Limitations of Outbox</h1>
<p>Outbox is not a complete solution, not because of any of the caveats listed above, but because NIP 65 per se only addresses the question of how to index content by pubkey in a broadcast social media context. But there are many other scenarios for relay selection that Outbox does not solve:</p>
<ul>
<li>Community, chat, and group posts might be best posted to relays dedicated to that context.</li>
<li>Direct messages shouldn't follow the same contours as public social media content.</li>
<li>Topic-oriented relays, or relays serving a custom feed might be useful independent of who uses them.</li>
<li>Relays focused on serving a particular kind of event, like music, long-form content, or relay selections, are useful independent of who reads from or writes to them.</li>
<li>Certain clients might need to fulfill particular use cases by using relays that support certain protocol features, like search, count, or sync commands.</li>
<li>Some events might not make sense to publish to relays, but should instead be shared only directly, out of band.</li>
</ul>
<p>Some of these use cases might be solved by new specifications similar to Outbox that prescribe where certain data belongs&nbsp;— for example, <a href="https://github.com/nostr-protocol/nips/blob/master/17.md">NIP 17</a> requires users to publish a different relay list before they can receive direct messages, while <a href="https://github.com/nostr-protocol/nips/blob/master/72.md">NIP 72</a> places community relay recommendations directly into the group's metadata object. A reasonably complete list of different relay types can be found in <a href="https://github.com/nostr-protocol/nips/issues/1282">this PR</a>, very few of which have a canonical way to manage selections.</p>
<p>Other use cases might be supported more informally, either by relays advertising their own value proposition, or via third-party <a href="https://github.com/nostr-protocol/nips/pull/230">NIP 66</a> metadata. Still others might be supported by scoping the network down to only certain relays through explicit relay selection — this is how white-labeled <a href="https://coracle.tools/">Coracle instances</a> work.</p>
<p>The basic idea here is that there are categories of events that don't have anything to do with where a particular person puts his or her "tweets". For every "what" on nostr, there should be a "how".</p>
<h1>Keep nostr weird</h1>
<p>Whatever additional systems we end up adopting for helping with relay selection, one thing is certain — people will continue to discover new, creative uses for relays, and we will always be playing catch up. This is one of the coolest things about nostr!</p>
<p>But it does mean that users will have to adapt their expectations to a network that partitions, re-configures, and evolves over time. Nostr is not a "worse" experience than legacy social media, but it is a version of social media that has itself been set free from the stagnant walled-garden model. Nostr is in many ways a living organism — we should be careful not to impose our expectations prematurely, leaving room to discover what this thing actually is, or can be.</p>
<p>If you enjoyed this post but want more take a look at the talk I gave at <a href="https://www.youtube.com/live/Nz15SyiwQFk?t=2751s">Nostrasia</a> last year. I also wrote up a <a href="https://habla.news/u/hodlbod@coracle.social/1700155417145">blog post</a> at about the same time that addresses some of the same issues, but focuses more on privacy concerns around relays and nostr groups. Finally, I recently wrote <a href="https://github.com/nostrability/nostrability/issues/69#issuecomment-2310524841">this comment</a>, which includes some details about challenges I've faced putting Outbox into Coracle.</p>
]]></content:encoded>
      <itunes:author><![CDATA[ hodlbod]]></itunes:author>
      <itunes:summary><![CDATA[<p>Nostr is a mess. It always has been and will always be. That's part of the appeal! But it's important that users be able to navigate the rolling seas of this highly partition-tolerant network of kaleidoscopically-interwoven people, bots, topics, relays, clients, events, recommendations, lists, feeds, micro-apps, macro-apps, Chinese spam, and "GM"s.</p>
<p>In order to do this, users must be able to articulate "what" they are looking for, and clients must be able to articulate "how" to find that thing. This "how" is divided into two parts: building a request that will match the desired content (very easy), and selecting a relay that is able to serve that content to the user requesting it (very very hard).</p>
<h1>Why guessing isn't good enough</h1>
<p>As a concrete example, let's say the user wants to find everyone in their "network" who is using a particular topic. The process would look something like this:</p>
<ol>
<li>The user clicks the "network" tab and types in the topic they want to browse. This is the "what".</li>
<li>The client then translates the term "network" to a list of public keys using whatever definition they prefer (Follows? WoT? Grapevine?), and builds a filter that might look something like this: <code>[{"authors": pubkeys, "#t": ["mytopic"]}]</code>. Any relay will happily accept, understand, and respond to that filter.</li>
<li>The client then has to decide which relays it should send that filter to. This is the <code>???</code> stage of the outbox model, which immediately precedes:</li>
<li>Profit</li>
</ol>
<p>It may not be immediately obvious why selecting the correct relays might be difficult. Most people post to relay.damus.io, and most people read from relay.damus.io, so in most cases you should be good, right?</p>
<p>This approach to relay selection has historically worked "well enough", but it depends on a flawed definition of success. If you only want to find 90% of the content that matches your query, using the top 10 relays will suffice. But nostr is intended to be censorship-resistant. What if those 10 hubs have banned a particular public key? Nostr clients should (at least in theory) be 100% successful in retrieving requested content. Even if someone only posts to their self-hosted relay, you should be able to find their notes if their account is set up properly.</p>
<h1>A naive solution to fixing the FOMO</h1>
<p>A 90% hit rate results in a feeling of flakiness, even if users aren't completely aware of what isn't working. Feeds will be incomplete, quoted notes will be missing, replies will be orphaned, user profiles won't load. The natural response to the FOMO this creates is for users to "try harder" by adding more relays.</p>
<p>On the read side, this means clients open more connections, resulting in much higher data transfer requirements, with massively diminishing returns, since there's no reason to expect that a randomly chosen relay will have a substantially different data set.</p>
<p>One the publish side, this means that clients end up publishing more copies of their data to more relays. This approach has been automated in the past by services like Blastr, which don't store a copy of events published to the relay, but instead forward events to the top 300 relays in the network. This results in a two-orders-of-magnitude increase in storage required, and only makes the read side of the problem worse, since it reduces the uniqueness of the data set each relay stores. This in turn means that more duplicates are retrieved when querying relays.</p>
<p>Both halves of this approach are equivalent to guessing. On the read side, users are guessing which relays will have any arbitrary content they might ask for in the future. On the write side, users are guessing which relays other people might use to find their notes. It is a brute-force method for finding content.</p>
<h1>Randomness results in centralization</h1>
<p>In theory, random relay selection would result in a perfect distribution of content across all relays in the network. But in practice, this method of selection isn't random at all, but is strongly influenced by user bias in what constitutes a "good" relay. While some users may check <a href="https://nostr.watch">nostr.watch</a> for ping times, geographical proximity, or uptime, most will choose relays based on familiar names or other people's recommendations.</p>
<p>In either case, these biases are entirely orthogonal to achieving a higher content retrieval hit rate, <em>except when bias in relay selection results in clustering</em> — i.e., centralization. In other words, the kind of randomness exhibited by users when selecting relays actually results in pretty much everyone picking the same few relays. We see this same effect when people try to come up with passwords or seed phrases — human-provided randomness is anything but random.</p>
<p>Clustering improves the hit rate when requesting events (slightly), but it results in nearly as much centralization as if only a single relay was used —&nbsp;and a lot more duplicate events.</p>
<h1>Something (anything) other than randomness</h1>
<p>In early 2023, Mike Dilger <a href="https://github.com/nostr-protocol/nips/pull/218">introduced NIP 65</a> (now known as the "Outbox Model") with a problem statement in the spirit of the original description of nostr: "Nostr should scale better. People should be able to find what they want."</p>
<p><em>Historical note: NIP 65 was formerly known as the "Gossip Model", derived from the name of Mike's <a href="https://github.com/mikedilger/gossip">desktop nostr client</a>, called "Gossip". This unfortunately created a lot of confusion, since <a href="https://en.wikipedia.org/wiki/Gossip_protocol">gossip protocols</a> work very differently from how nostr tends to work, hence the re-brand.</em></p>
<p>Before NIP 65, an informal standard existed in which <code>kind 3</code> user contact lists also included a list of relays that clients could use as something similar to Mastodon's "home servers". This list included the option to only read or write from a given relay. Unfortunately, it wasn't really clear what the semantics of this relay list were, so different clients handled them differently (and many clients ignored them). Usually this amounted to user-provided static relay configurations, which resulted in the naive relay selection approach described above.</p>
<p>NIP 65 used a very similar format (a list of relay urls with optional "read" or "write" directives), but with a very important semantic difference: relays listed in a user's <code>kind 10002</code> were intended to "advertise to others, not for configuring one's client." In other words, these relay selections were intended as a signal to other users that they should use certain relays when attempting to communicate with the author of the relay list.</p>
<p>I highly recommend reading the <a href="https://github.com/nostr-protocol/nips/blob/master/65.md">entire NIP</a>, which is very short and easy to read. But the mechanics of the spec are very simple:</p>
<blockquote>
<p>When seeking events&nbsp;<strong>from</strong>&nbsp;a user, Clients SHOULD use the WRITE relays of the user's&nbsp;<code>kind:10002</code>.</p>
<p>When seeking events&nbsp;<strong>about</strong>&nbsp;a user, where the user was tagged, Clients SHOULD use the READ relays of the user's&nbsp;<code>kind:10002</code>.</p>
<p>When broadcasting an event, Clients SHOULD:</p>
<ul>
<li>Broadcast the event to the WRITE relays of the author</li>
<li>Broadcast the event to all READ relays of each tagged user</li>
</ul>
</blockquote>
<p>For the first time, we had a way to differentiate relays in terms of <em>what content could be found where</em>.</p>
<p>When looking for a note by a particular user, a client could now look up the author's <code>write</code> relays according to their <code>kind 10002</code> event, and send its query there. The result is a much higher hit rate with much lower data transfer requirements, and fewer connections per query.</p>
<h1>Making Outbox Work</h1>
<p>There are of course some assumptions required to make this work. </p>
<p>First, the user must know which author they're looking for. This isn't always true when looking up a quote or parent note, but context and <a href="https://github.com/nostr-protocol/nips/pull/1171">pubkey hints</a> solve this difficulty in most cases.</p>
<p>The author must also publish a <code>kind 10002</code> event. This may not always be the case, but clients should prompt users to set up their relay list correctly. This isn't really a flaw in the Outbox Model, just in implementations of it.</p>
<p>Additionally, the user's client must be able to find the author's <code>kind 10002</code> event. This is the "bootstrapping" phase of the Outbox Model, during which the mechanisms the system provides for finding events aren't available. This requires us to fall back to randomly guessing which relays have the content we're looking for, which as we saw above doesn't work very well.</p>
<p>Other than guessing, there are a few different ways a client might find the relay selection event in question, each of which is applicable in different circumstances. In most cases, using one of a handful of indexer relays like <a href="wss://purplepag.es">purplepag.es</a> or <a href="wss://relay.nostr.band">relay.nostr.band</a> is a simple and efficient way to find user profiles and relay selections.</p>
<p>However, if an author's content has been aggressively purged from these indexers due to censorship, they obviously can't be relied upon. Even though the author in question hasn't been deplatformed from nostr itself (since he can always self-host a publicly accessible relay to store his content), he has been effectively shadow-banned.</p>
<p>To get around this, relay selections have to be communicated in some other way. Nostr has a few different mechanisms for this:</p>
<ul>
<li>If the author's NIP 05 address is known and properly configured (it may not be), clients can look up the author's NIP 05 endpoint to find some reasonable relay hints. Unfortunately, these are often neglected, and usually custodial, so they can run into the same problems.</li>
<li>If the author's pubkey is found in another signed event found on nostr, <a href="https://github.com/nostr-protocol/nips/blob/fade0164f52033314bf0a5ef9bd63c2483afae9b/10.md#marked-e-tags-preferred">relay hints</a> can be a way to propagate relay selections through the network. This relies on implementations picking reliable relay hints which can be difficult, and hints do tend to become less reliable over time. However, this strategy is very effective in resisting censorship because it makes banning viral — if a relay wants to completely purge a particular pubkey from their database, they have to purge every event that references it, since events are tamper-proof.</li>
<li>In extremis, relay recommendations can always be communicated out-of-band. This can be done using manual input, QR codes, DHTs, jsonl torrents full of <code>kind 10002</code> events, or any other mechanism client developers choose to resort to.</li>
</ul>
<p>Another, more technical assumption is that any given query can be fulfilled by few enough relays that a client can actually make all the connections needed, without running into resource limits. If you're trying to request content from 10,000 users across 1,000 relays, you're going to have a bad time. This was <a href="https://coracle.social/nevent1qythwumn8ghj76twvfhhstnwdaehgu3wwa5kuef0qyv8wumn8ghj7cm9d3kxzu3wdehhxarj9emkjmn99uq3samnwvaz7tmrwfjkzarj9ehx7um5wgh8w6twv5hsqgrn7l6zj7ht6ruyk76vvvtkfs4xrhyzc3tm64l3eyfvd40y26sz0gshmunh">pointed out</a> to me by Mazin of <a href="https://nostr.wine">nostr.wine</a>. He makes a good point, and it's definitely something to keep in mind. There are some mitigating factors though.</p>
<p>The first is that the current topology of the network probably won't persist forever. Because nostr is largely populated by self-hosting enthusiasts, the number of "tiny" relays is proportionally much higher than it will be if adoption picks up, even if the total number of relays grows. The trajectory is that nostr will drift toward fewer, larger relays, reducing the number of connections needed to fulfill any given query.</p>
<p>This is "centralizing", but it's important to understand that this isn't necessarily a bad thing. As long as there are more than one or two large hubs, there is user choice. And as long as it's possible to run a new relay, there is always an escape hatch. Nostr, like bitcoin, has no hard dependency on the biggest player in the network.</p>
<p>The other thing to consider is that there are lots of other techniques we can use to overcome the limits of the lowest-common denominator's limitations (mobile browser clients), including self hosted or third-party relay proxies. The trade-off here is that a little trust (aka centralization) can go a long way to reducing resource requirements needed to fulfill queries using the Outbox model.</p>
<p>If you're interested in more details on this topic, see <a href="https://habla.news/u/hodlbod@coracle.social/sfwV1rNaoQXd65PbIMYgm">this blog post</a>.</p>
<p>That was a long digression, but there is one other thing that the Outbox model assumes to be the case. Even if the correct relays are found and connected to, they still may not return all desired content, either because they don't have it, or because they refuse to return it to the user requesting it.</p>
<p>This can happen if the publishing client isn't following the Outbox Model, if the author had migrated from one relay set to another without copying their notes over, or if the relay in question chose not to retain the author's content for some reason.</p>
<p>The first two issues can be fixed by improving implementations, but the question of policy is a little more interesting.</p>
<h1>Relativistic relays</h1>
<p>The Outbox Model is a mechanical process; it's only as useful as user relay selections are. In order for it to work, users have to be able to make intelligent relay selections.</p>
<p>Every relay has trade-offs, depending on its policy. <a href="wss://140.f7z.io">140.f7z.io</a> would not be useful for long-form content, for example. Some relays might have a content retention policy that changes depending on whether you're a paying user. If you don't pay, you might find out too late that your content has been deleted from the relay.</p>
<p>So what makes a relay "good" for a particular use case? Well, it's complicated. Here are a few factors that go into that calculus:</p>
<ul>
<li>Is the relay in the same geographical as the user? Proximity reduces latency, but jurisdictional arbitrage might be desired. Users should probably have a variety of relays that fit different profiles.</li>
<li>Will the relay ban the user? Do the operators have a history of good behavior? Is the relay focused on particular types of content? Is the relay's focus consistent with the user's goal in adding that relay to their list?</li>
<li>What are the relay's retention policies? A user might want to set up an archival relay for her old content, or a multi-availability-zone relay so her notes are immediately accessible to the rest of the network.</li>
<li>Does the relay require payment? Paid relays are more aligned with their users, but obviously come at a financial cost.</li>
<li>Does the relay have policies for read-protecting content? If so, other users might not be able to find your posts published to that relay. On the other hand, some relays are configured to work as inboxes for direct messages, which can help preserve privacy.</li>
<li>Does the relay request that users authenticate? Authentication can help manage spam, but it also allows relays to correlate content requests with users, reducing user privacy.</li>
<li>Is the relay you use hosted by your client's developer? If so, you're in danger of getting banned from your client and your relay at the same time.</li>
<li>Is the relay a hub? Using hubs can help smooth out rough areas in Outbox Model implementations, at the cost of centralization.</li>
<li>Is the relay used by anyone else? One-off relays can be useful for archival purposes, but often won't be used by clients following the Outbox Model, depending on how they optimize requests.</li>
</ul>
<p>There are lots of ways to approach the problem of helping users select relays, but it's an inherently complex problem which very few people will have the patience to properly address on their own. Relay selection is a multi-dimensional problem, and requires satisfying multiple constraints with a limited number of relay selections.</p>
<p>In the future, special-purpose clients might be used to help people build relay sets. Clients also might provide curated "relay kits" that users can choose and customize. Or, we might see an increase in hybrid solutions, like smarter relay proxies or client-local relays that synchronize using other protocols or platforms.</p>
<h1>The Limitations of Outbox</h1>
<p>Outbox is not a complete solution, not because of any of the caveats listed above, but because NIP 65 per se only addresses the question of how to index content by pubkey in a broadcast social media context. But there are many other scenarios for relay selection that Outbox does not solve:</p>
<ul>
<li>Community, chat, and group posts might be best posted to relays dedicated to that context.</li>
<li>Direct messages shouldn't follow the same contours as public social media content.</li>
<li>Topic-oriented relays, or relays serving a custom feed might be useful independent of who uses them.</li>
<li>Relays focused on serving a particular kind of event, like music, long-form content, or relay selections, are useful independent of who reads from or writes to them.</li>
<li>Certain clients might need to fulfill particular use cases by using relays that support certain protocol features, like search, count, or sync commands.</li>
<li>Some events might not make sense to publish to relays, but should instead be shared only directly, out of band.</li>
</ul>
<p>Some of these use cases might be solved by new specifications similar to Outbox that prescribe where certain data belongs&nbsp;— for example, <a href="https://github.com/nostr-protocol/nips/blob/master/17.md">NIP 17</a> requires users to publish a different relay list before they can receive direct messages, while <a href="https://github.com/nostr-protocol/nips/blob/master/72.md">NIP 72</a> places community relay recommendations directly into the group's metadata object. A reasonably complete list of different relay types can be found in <a href="https://github.com/nostr-protocol/nips/issues/1282">this PR</a>, very few of which have a canonical way to manage selections.</p>
<p>Other use cases might be supported more informally, either by relays advertising their own value proposition, or via third-party <a href="https://github.com/nostr-protocol/nips/pull/230">NIP 66</a> metadata. Still others might be supported by scoping the network down to only certain relays through explicit relay selection — this is how white-labeled <a href="https://coracle.tools/">Coracle instances</a> work.</p>
<p>The basic idea here is that there are categories of events that don't have anything to do with where a particular person puts his or her "tweets". For every "what" on nostr, there should be a "how".</p>
<h1>Keep nostr weird</h1>
<p>Whatever additional systems we end up adopting for helping with relay selection, one thing is certain — people will continue to discover new, creative uses for relays, and we will always be playing catch up. This is one of the coolest things about nostr!</p>
<p>But it does mean that users will have to adapt their expectations to a network that partitions, re-configures, and evolves over time. Nostr is not a "worse" experience than legacy social media, but it is a version of social media that has itself been set free from the stagnant walled-garden model. Nostr is in many ways a living organism — we should be careful not to impose our expectations prematurely, leaving room to discover what this thing actually is, or can be.</p>
<p>If you enjoyed this post but want more take a look at the talk I gave at <a href="https://www.youtube.com/live/Nz15SyiwQFk?t=2751s">Nostrasia</a> last year. I also wrote up a <a href="https://habla.news/u/hodlbod@coracle.social/1700155417145">blog post</a> at about the same time that addresses some of the same issues, but focuses more on privacy concerns around relays and nostr groups. Finally, I recently wrote <a href="https://github.com/nostrability/nostrability/issues/69#issuecomment-2310524841">this comment</a>, which includes some details about challenges I've faced putting Outbox into Coracle.</p>
]]></itunes:summary>
      <itunes:image href="https://yakihonne.s3.ap-east-1.amazonaws.com/97c70a44366a6535c145b333f973ea86dfdc2d7a99da618c40c64705ad98e322/files/1724892627307-YAKIHONNES3.jpg"/>
      </item>
      
      <item>
      <title><![CDATA[Relays, Encryption, and Groups]]></title>
      <description><![CDATA[On relays, encryption, and how they work together to create a "good enough" private group solution.]]></description>
             <itunes:subtitle><![CDATA[On relays, encryption, and how they work together to create a "good enough" private group solution.]]></itunes:subtitle>
      <pubDate>Thu, 16 Nov 2023 17:45:27 GMT</pubDate>
      <link>https://hodlbod.npub.pro/post/1700155417145/</link>
      <comments>https://hodlbod.npub.pro/post/1700155417145/</comments>
      <guid isPermaLink="false">naddr1qqxnzdesxqcn2df5xymnzdp4qgsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgsrqsqqqa28q3wd45</guid>
      <category>nostr</category>
      
        <media:content url="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-lAQRH4mCyl4-unsplash.jpeg" medium="image"/>
        <enclosure 
          url="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-lAQRH4mCyl4-unsplash.jpeg" length="0" 
          type="image/jpeg" 
        />
      <noteId>naddr1qqxnzdesxqcn2df5xymnzdp4qgsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgsrqsqqqa28q3wd45</noteId>
      <npub>npub1jlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qdjynqn</npub>
      <dc:creator><![CDATA[ hodlbod]]></dc:creator>
      <content:encoded><![CDATA[<p>As everyone knows by now, I am working on adding private groups to Coracle using the new NIP-44 encryption standard currently being audited. I wanted to share why I think this is a viable approach, and how combining relays and encryption can help make it happen.</p>
<p>This discussion gets complicated very quickly, so to begin, I thought I'd cover the two components that everyone <em>thinks</em> they understand first (relays and encryption), and move on to the one that combines the existing primitives in new and exciting ways (groups).</p>
<h1>What even are relays, anyway?</h1>
<p>If you saw <a href="https://www.youtube.com/live/Nz15SyiwQFk?si=FmLCoTWL1ZFhnY3K&amp;t=2751">my talk at Nostrasia</a>, this section is just a re-iteration of it. In fact, I wrote this blog post before the conference to help me with my presentation. So hello, from the past.</p>
<p>Relays are dumb. They're just servers, which speak a particular protocol, and which implement some minimal logic to support that protocol. Relays have to be interoperable, which is why it's important to design new parts of the nostr protocol in such a way as to be backwards-compatible, and simple to implement.</p>
<p>As a result, relay development has historically focused on performance to the exclusion of new functionality. You can see this with the success of strfry and Will's adaptation of the underlying technique to nostrdb.</p>
<p>One of my favorite programming talks is <a href="https://www.youtube.com/watch?v=SxdOUGdseq4">Simple Made Easy</a> by Rich Hickey, the author of Clojure. One of the points he makes in that talk is that object-oriented programming is such a mess because it "complects" behavior and state. Hickey's solution to this problem is to use functions and values rather than methods and state.</p>
<p>I think that this same mistake is one we are at risk of making with nostr relays. I'll come back to this in a bit, but keep that distinction in the back of your mind: separating data and behavior can lead to a much simpler and more robust system.</p>
<p>Despite the emphasis on interoperability, relays shouldn't all be exact clones. There are a few different ways relays can differentiate themselves, either by providing specific functionality, by storing different sets of events, or by exposing a different interface.</p>
<h2>Added functionality</h2>
<p>Some implementations have pushed features forward, for example rbr.bio which implemented the COUNT verb from NIP 45 early on. However, these efforts are usually either supported by special clients (like nostr.band or primal's caching service), or fail to gain wide adoption and are eventually abandoned. The result is that NIPs specifying optional functionality tend to die without sufficient user demand.</p>
<p>The reason for this is that if you're building a client that selects relays based on user preferences, it can't rely on functionality that doesn't exist on the majority of relays. Without widespread support, search results or feeds requested based on Primal's special syntax will be incomplete or fail entirely. As a result, clients often build proprietary solutions to these problems, increasing centralization risk.</p>
<h2>Subtracted functionality</h2>
<p>Relays are able to helpfully differentiate themselves however, by offering a <em>subset</em> of protocol functionality. For example, purplepag.es is a reliable source for profile data and relay preferences, but it doesn't require clients to do anything different in order to be useful. Instead, users can simply add purplepag.es to their relay list and instantly get a better experience. A similar approach many commodity relays take is blocking certain event kinds, for example 1059 gift wraps or NIP 94 image headers. This fortifies their particular purpose, which is to <em>not</em> support more exotic protocol features.</p>
<p>Other kinds of relays don't support this guarantee, for example relay.noswhere.com only supports search if the search term is not accompanied by a filter, responding to standard requests with "filters: not planned (non-search queries)". This can still be useful, but it is <em>not</em> a relay, because it requires clients to special case how it's used.</p>
<h2>Data relevance</h2>
<p>There is a different kind of differentiation relays can implement, based not on functionality, but on content. This is what I mean when I talk about "relay de-commodification". The value proposition this type of relay offers is not "we can do something no one else does", but "we have the information you're looking for".</p>
<p>There are two ways to accomplish this: content curation and access controls. The difference being that content curation is context-independent, and might be based on topic, keyword, or LLM analysis, while access controls only accepts content published by certain accounts. Several relay implementations and hosting providers (for example relay.tools) support both of these approaches, and of course it's easy to combine them.</p>
<p>Likewise, there are two ways for a relay to gain access to the desired data, leading to two different value propositions.</p>
<p>A relay that focuses on topical data might scrape the wider nostr network in order to ensure it is able to reliably serve everything relevant to its niche. This might be done using any number of heuristics, including filtering by pubkey, topic, or sentiment, but in any case the relay is not intended primarily to be written to, but to be read from. This is primarily an additive model, focusing on offering a complete view of the given topic.</p>
<p>Another approach is to let the data come to you instead of scraping it from the wider network by only accepting events published by certain people, or being the go-to relay for a certain topic. In order for this model to work though, there needs to be some way for the relay to keep this data to itself by preventing scraper-powered relays from harvesting its data. This effectively means that these relays will not only have policies for who can write to them, but also who can read from them. These might be the same set of people (for example with a community relay), or more people might be allowed to read from the relay than are able to write to it, as in the case of content producers who want a paywalled private social media enclave.</p>
<h2>Keep relays weird</h2>
<p>Most relay implementations expose their data over websockets in line with the spec, but this isn't actually inherent to the function of a relay. We've already seen several projects implement relays in-app for caching purposes. These relays don't usually go through the ceremony of spec adherence, but some (e.g. nostrdb) do.</p>
<p>Different transport mechanisms and hosting options are possible for relays, and would only require clients to use a specific adapter to get at them. Some examples:</p>
<ul>
<li>A relay running on your phone as a service that other nostr clients can share to reduce data storage requirements</li>
<li>A relay running on a LAN, only accessible from a particular location</li>
<li>A relay running via any other transport, for example radio or carrier pigeon</li>
</ul>
<p>The idea I'm trying to get across here is that relays aren't necessarily websocket servers. More abstractly, they are a name attached to a set of events that can be accessed in a standard way.</p>
<h2>So, what are relays?</h2>
<p>To recap, here's my definition of a relay:</p>
<ol>
<li>They correctly support standard functionality</li>
<li>They should only support additional functionality related to curating their data set</li>
<li>They may restrict the data types they accept and serve</li>
<li>They may restrict the data they accept and serve based on content or pubkey</li>
</ol>
<p>One additional feature that isn't currently standard but ought to be is strfry's negentropy synchronization feature. This is the opposite of AUTH, which protects a relay's own dataset, in that it allows relays to more efficiently share their data with peers. A nice bonus is that it also allows clients to use their local cache more effectively as well.</p>
<h2>Simple Made Easy</h2>
<p>Going back to Rich Hickey's talk, separating behavior and state allows you to work directly with your data, freely implementing new behavior whenever you need to. This applies to sets of events stored on relays just as much as it applies to in-memory data.</p>
<p>One thing that makes this possible is cryptographic hash functions, which cleanly transform state into values - the difference being that "state" couples a name with data that may change, while a hash is a compact representation of immutable data. If two hashes of event ids don't match, they're not the same set of events.</p>
<p>How does this apply to relays? Instead of adding new behavior to relays directly ("methods"), we can instead call "functions" on a relay's data.</p>
<p>This function can be anything - a centralized server, client code, or a DVM - that takes REQ filters as input. The function gathers the needed data (maybe from a cache, maybe using a sync command, maybe from multiple relays for completeness), performs the transformation, and returns it. The result is that relays become simple, interoperable repositories for data, without limiting what server-side computation can be applied to events.</p>
<p>While huge search indexes and centralized servers have a cost in terms of centralization, I think DVMs solve this problem brilliantly - the common interface for this augmented behavior is open, and can admit anyone who wants to start competing for search, counting, recommendations, or anything else you might want to do with events.</p>
<p>As Alan Perlis said, "It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures."</p>
<h1>Encrypted Messages</h1>
<p>Nostr DMs were a huge mistake, and I want to do it again.</p>
<p>NIP 04 has some obvious problems, most notably metadata leakage. The cryptography also hasn't been audited, and has some potential theoretical attack vectors. I've been working with some other nostr devs on a new cryptographic primitive, which will be audited and hopefully result in a better foundation for future work.</p>
<p>But fixing the cryptography still doesn't fix DMs. Nostr is not really the right architecture for secure private messaging, because ratchets require state. Nostr is designed such that there are no hard dependencies between events, which are replicated across multiple relays. This makes it very hard to manage the kind of state that protocols like SimpleX or Signal require.</p>
<p>Even apart from the difficulty of implementing stateful messaging protocols on nostr, we have two other problems to contend with: metadata leaks and spotty deliverability. Both of these problems come from the reliance of nostr on relays, which generally are not trustworthy or reliable.</p>
<h2>Metadata Leakage</h2>
<p>NIP 04 is really bad. Anyone can see who you corresponded with, when, how frequently, and how much you said just by looking at the event. Vitor's NIP 24 chat proposal aims to fix this with gift wraps, which use ephemeral keys to obscure the sender, padding to obscure message size, timestamp randomization to obscure timing, and double-wrapping to prevent leakage of the signed message.</p>
<p>This is a big improvement, but there are other forms of metadata that are still visible. To start, the recipient is still visible, along with how many messages they have received and their general size. So you can tell if someone sends lots of messages, or not a lot, but that's about it.</p>
<p>If we don't assume relays are trustworthy though, there are all kinds of implicit metadata that can be used to infer information about the sender, including:</p>
<ul>
<li>Client fingerprinting</li>
<li>Relay selection for publishing and queries</li>
<li>IP address collection</li>
<li>First seen timestamp</li>
<li>Identification of users by AUTH</li>
<li>Correlation of the event with other messages sent/received during a session</li>
</ul>
<p>These issues are much harder to solve, because they are part of the process of delivering the message, rather than just constructing it.</p>
<h2>Transport and deliverability</h2>
<p>The key feature of nostr that makes it work is relays. Relays provide storage redundancy and heterogeneity of purpose with a common interface shared by all instances. This is great for censorship resistance, but everything comes with a tradeoff.</p>
<p>Completeness and consistency are not guaranteed on nostr. This is ok in a social media context, because there's no way to keep up with everything everyone you follow says anyway, and you can rely on interactions and algorithmic tools to catch you up on anything important you missed.</p>
<p>But with private messages, every payload counts. Receiving messages out of order, with a delay, or not at all can severely disrupt conversations between two people, leading to misunderstandings and worse. This is a common experience on nostr; even fiatjaf has expressed skepticism about the viability of private messages on nostr.</p>
<p>This flakiness comes from a combination of low relay quality and poor relay selection on the part of clients. Relays can't deliver messages if they can't keep up with clients, go offline, or drop messages (accidentally or deliberately). Likewise, clients can't find messages if they look for them in the wrong place.</p>
<h2>Relays fixes this</h2>
<p>Let me just put things into perspective really quick. Twitter DMs are not e2e encrypted, and weren't encrypted at all until earlier this year. Mastodon messages are not encrypted - instance admins can read everything. Facebook has e2ee messages, but only between normal users, not in communities, groups, business chats, or marketplace chats.</p>
<p>So while nostr's architecture is not sufficient to make secure encrypted communication a value proposition of the protocol in itself, there is a lot we can do to improve on the status quo. Because nostr has no admins, the only option for privacy of any kind is end-to-end encryption. Metadata leakage notwithstanding, nostr messages can be "good enough" for some definition of that phrase.</p>
<p>It's important to not just punt on making DMs available in a standard way, because there is an expectation that a complete social media solution will have a way to establish a private communication channel with someone else in the network. Otherwise you're stuck with public correspondence and link sharing in order to hop to another protocol.</p>
<p>Let's just assume that you agree with me at this point, and that until there is a javascript SDK for SimpleX or MLS, we're stuck with nostr DMs of some kind. So how can we reduce metadata leakage and improve deliverability?</p>
<h2>Fixing Flakiness</h2>
<p>Let's start with deliverability first. NIP 65's inbox/outbox model is great. While it doesn't fix deliverability on its own, if every relay recommended was in fact reliable, and reliably followed by clients, there would be a very clear indication of where a particular user's messages could be found. Neither of these things is really true right now, but I do think clients are moving in this direction. Hopefully we can educate users better on how to pick good relays.</p>
<p>There are some limits to this model of course. For example, if you want to read notes from 1000 pubkeys at once, your client will likely end up connecting to hundreds of relays unless it has a cap, in which case it will miss a lot of notes.</p>
<p>One clean solution to this problem is relay proxies. There are a few implementations, but the one I run at mux.coracle.social is a stateless proxy that uses a wrapper protocol so clients can still select and dispatch to relays. I originally built this to improve mobile data use by deduplicating events on the server, and it does that pretty well, although it currently does it in the most naive way possible.</p>
<p>Multiplextr currently does not qualify as a "real" relay based on my four rules, since it uses a wrapper protocol. However, a smarter implementation would be able to route requests and events effectively by relying on client authentication and filter analysis, without changing the protocol. This would also allow clients to completely offload the complex business of relay selection to its proxy. Clients would also be able to combine multiple proxies just like they combine relays - because proxies are relays!</p>
<h2>Proxying Privacy</h2>
<p>Another downside of NIP 65 is that it encourages clients to connect indiscriminately to hundreds of different relays based on tag hints, other users' preferences, and relays baked into bech32 identifiers. This is not only bad for battery life and performance, but also allows attackers to easily trick your client into to connecting to their relay so they can start analyzing your traffic.</p>
<p>The best way to defend yourself against nosy relays is to not connect to them at all. And the easiest way to do that is to only connect to relays you control (or trust), and let them do the dirty work for you.</p>
<p>With a proxy, even if you don't control it, you can reduce the number of parties who can snoop on your traffic by orders of magnitude. And since other people use the proxy too, your traffic gets mixed with theirs, making it much harder to analyze. Of course, the downside of using a public proxy is that the proxy sees all messages you send and receive, and the relays you select for each request. Even worse, an untrusted multiplexer can hijack an authenticated session, exfiltrating private data from protected relays.</p>
<p>A proxy you control (or trust, either via social relationships or economic ones) is the best of both worlds. This proxy could also do some smart things for you to improve privacy as well, for example:</p>
<ul>
<li>Delayed publishing of gift wrapped messages so relays can't guess as easily when the event was first seen.</li>
<li>Closing and re-opening connections to reduce the number of messages sent over an AUTH'd session.</li>
<li>It could block suspicious messages on the fly, for example spam or notes with phishing links.</li>
<li>If an abundance of options are available for relay selections, it could randomize which relays are used, or avoid using less reputable ones.</li>
</ul>
<p>So I guess what I'm saying here, is "run a node". But not just any node - in the early days of nostr there were a lot of people spinning up relays because they thought it helped decentralization. Well, as it turns out, just like in bitcoin you have to <em>use</em> your node in order for it to be useful.</p>
<h1>Beyond DMs</h1>
<p>I'm not done yet, though. What's the point of all this? Why put all this effort into "good enough" DMs when we could spend the effort adopting SimpleX or MLS (said Semisol, who lives rent free in my head)?</p>
<p>Well, because there isn't a single "best" DM option. As I've dug into the topic, I've discovered that a ton of tradeoffs exist between complexity, privacy, and scale. The way I understand it, there are three basic options here:</p>
<ul>
<li>One-to-one encryption. This is how both SimpleX and Vitor's group message draft works. It allows for things like ratchets to be added on top, and is fairly simple - but fails to scale because every message has to be encrypted separately for every group member, resulting in <code>n*m</code> messages, where <code>n</code> is the number of group members, and <code>m</code> is the number of messages sent.</li>
<li>Encryption via shared key. This is how WhatsApp works, and it scales really well because messages don't have to be duplicated. And while it does support forward secrecy, it does not support post-compromise security, so it is significantly less secure.</li>
<li>MLS has a unique hierarchical approach to managing keys, which improves the complexity of one-to-one encryption so that it's logarithmic rather than exponential. However, MLS is highly stateful and still has scaling limitations.</li>
</ul>
<p>My takeaway is that there is no perfect solution. Ratchets are the gold standard, but can't really be implemented using nostr relays, since they frequently require servers to have very specific characteristics, like the ability to deliver messages in order.</p>
<p>The fact remains though, that social media needs encrypted messaging of some kind, even if we encourage users to bail to a more complete solution if they want to be truly private. And encryption is useful beyond small group chats - think of Facebook groups, which scale to millions of people and whose users have a much lower expectation of privacy. This is what nostr is good at - social data, whether encrypted or in plaintext.</p>
<h2>Belt and Suspenders</h2>
<p>For a long time I have waffled between two visions of how private groups ought to work. Should they be encrypted messages sprinkled across the nostr network like confetti? Or should they live on one or two relays in plaintext, protected by AUTH?</p>
<p>Both of these options have issues. Sprinkling encrypted messages across the network almost guarantees deliverability problems, since already many commodity relays block gift wraps. And that's ok! They have no obligation to store your encrypted messages.</p>
<p>Storing group messages in plaintext is also sub-optimal, even if it's on a dedicated relay. Of course we're not going for military-grade secrecy here, but it would be trivially easy through a bug, or even a client that doesn't know how to deal with groups, to re-broadcast events that should stay private. We could do something wacky, like strip the signature from events hosted on a relay, but if we're going to do something non-standard, we might as well do the best we can.</p>
<p>So why not both? Group messages should be encrypted, and they should be stored on a particular set of relays. Again, assuming the relays used are trustworthy, this fixes both privacy and deliverability problems, because it's very clear where messages posted to the group should go.</p>
<p>Promoting relays to trusted status has some nice, unintended benefits too. One common objection to using encrypted content is that it becomes hard to filter. But if a relay is trusted to store a group's messages, it can also be trusted to be admitted as a member to the group. This would allow the relay to decrypt events and filter them to respond to requests by authenticated group members.</p>
<p>Of course, this would violate rule <a href='/tag/1/'>#1</a> for relays, since they would no longer be supporting standard functionality, but a guy can dream, can't he?</p>
<h1>Conclusion</h1>
<p>When I started working on nostr I had no idea it would end up being this complex to accomplish what I set out to do. Building a twitter clone was only a first step to an MVP, but I always had my eye on the prize of serving my local church community, which doesn't give a sat about social media per se.</p>
<p>Private groups are important to me not because I'm setting out to support political dissidents or journalists (although I hope they find nostr useful too), but because I want to get my friends off of Facebook, and the only way to do that is to create private marketplaces, calendars, communties, and more.</p>
]]></content:encoded>
      <itunes:author><![CDATA[ hodlbod]]></itunes:author>
      <itunes:summary><![CDATA[<p>As everyone knows by now, I am working on adding private groups to Coracle using the new NIP-44 encryption standard currently being audited. I wanted to share why I think this is a viable approach, and how combining relays and encryption can help make it happen.</p>
<p>This discussion gets complicated very quickly, so to begin, I thought I'd cover the two components that everyone <em>thinks</em> they understand first (relays and encryption), and move on to the one that combines the existing primitives in new and exciting ways (groups).</p>
<h1>What even are relays, anyway?</h1>
<p>If you saw <a href="https://www.youtube.com/live/Nz15SyiwQFk?si=FmLCoTWL1ZFhnY3K&amp;t=2751">my talk at Nostrasia</a>, this section is just a re-iteration of it. In fact, I wrote this blog post before the conference to help me with my presentation. So hello, from the past.</p>
<p>Relays are dumb. They're just servers, which speak a particular protocol, and which implement some minimal logic to support that protocol. Relays have to be interoperable, which is why it's important to design new parts of the nostr protocol in such a way as to be backwards-compatible, and simple to implement.</p>
<p>As a result, relay development has historically focused on performance to the exclusion of new functionality. You can see this with the success of strfry and Will's adaptation of the underlying technique to nostrdb.</p>
<p>One of my favorite programming talks is <a href="https://www.youtube.com/watch?v=SxdOUGdseq4">Simple Made Easy</a> by Rich Hickey, the author of Clojure. One of the points he makes in that talk is that object-oriented programming is such a mess because it "complects" behavior and state. Hickey's solution to this problem is to use functions and values rather than methods and state.</p>
<p>I think that this same mistake is one we are at risk of making with nostr relays. I'll come back to this in a bit, but keep that distinction in the back of your mind: separating data and behavior can lead to a much simpler and more robust system.</p>
<p>Despite the emphasis on interoperability, relays shouldn't all be exact clones. There are a few different ways relays can differentiate themselves, either by providing specific functionality, by storing different sets of events, or by exposing a different interface.</p>
<h2>Added functionality</h2>
<p>Some implementations have pushed features forward, for example rbr.bio which implemented the COUNT verb from NIP 45 early on. However, these efforts are usually either supported by special clients (like nostr.band or primal's caching service), or fail to gain wide adoption and are eventually abandoned. The result is that NIPs specifying optional functionality tend to die without sufficient user demand.</p>
<p>The reason for this is that if you're building a client that selects relays based on user preferences, it can't rely on functionality that doesn't exist on the majority of relays. Without widespread support, search results or feeds requested based on Primal's special syntax will be incomplete or fail entirely. As a result, clients often build proprietary solutions to these problems, increasing centralization risk.</p>
<h2>Subtracted functionality</h2>
<p>Relays are able to helpfully differentiate themselves however, by offering a <em>subset</em> of protocol functionality. For example, purplepag.es is a reliable source for profile data and relay preferences, but it doesn't require clients to do anything different in order to be useful. Instead, users can simply add purplepag.es to their relay list and instantly get a better experience. A similar approach many commodity relays take is blocking certain event kinds, for example 1059 gift wraps or NIP 94 image headers. This fortifies their particular purpose, which is to <em>not</em> support more exotic protocol features.</p>
<p>Other kinds of relays don't support this guarantee, for example relay.noswhere.com only supports search if the search term is not accompanied by a filter, responding to standard requests with "filters: not planned (non-search queries)". This can still be useful, but it is <em>not</em> a relay, because it requires clients to special case how it's used.</p>
<h2>Data relevance</h2>
<p>There is a different kind of differentiation relays can implement, based not on functionality, but on content. This is what I mean when I talk about "relay de-commodification". The value proposition this type of relay offers is not "we can do something no one else does", but "we have the information you're looking for".</p>
<p>There are two ways to accomplish this: content curation and access controls. The difference being that content curation is context-independent, and might be based on topic, keyword, or LLM analysis, while access controls only accepts content published by certain accounts. Several relay implementations and hosting providers (for example relay.tools) support both of these approaches, and of course it's easy to combine them.</p>
<p>Likewise, there are two ways for a relay to gain access to the desired data, leading to two different value propositions.</p>
<p>A relay that focuses on topical data might scrape the wider nostr network in order to ensure it is able to reliably serve everything relevant to its niche. This might be done using any number of heuristics, including filtering by pubkey, topic, or sentiment, but in any case the relay is not intended primarily to be written to, but to be read from. This is primarily an additive model, focusing on offering a complete view of the given topic.</p>
<p>Another approach is to let the data come to you instead of scraping it from the wider network by only accepting events published by certain people, or being the go-to relay for a certain topic. In order for this model to work though, there needs to be some way for the relay to keep this data to itself by preventing scraper-powered relays from harvesting its data. This effectively means that these relays will not only have policies for who can write to them, but also who can read from them. These might be the same set of people (for example with a community relay), or more people might be allowed to read from the relay than are able to write to it, as in the case of content producers who want a paywalled private social media enclave.</p>
<h2>Keep relays weird</h2>
<p>Most relay implementations expose their data over websockets in line with the spec, but this isn't actually inherent to the function of a relay. We've already seen several projects implement relays in-app for caching purposes. These relays don't usually go through the ceremony of spec adherence, but some (e.g. nostrdb) do.</p>
<p>Different transport mechanisms and hosting options are possible for relays, and would only require clients to use a specific adapter to get at them. Some examples:</p>
<ul>
<li>A relay running on your phone as a service that other nostr clients can share to reduce data storage requirements</li>
<li>A relay running on a LAN, only accessible from a particular location</li>
<li>A relay running via any other transport, for example radio or carrier pigeon</li>
</ul>
<p>The idea I'm trying to get across here is that relays aren't necessarily websocket servers. More abstractly, they are a name attached to a set of events that can be accessed in a standard way.</p>
<h2>So, what are relays?</h2>
<p>To recap, here's my definition of a relay:</p>
<ol>
<li>They correctly support standard functionality</li>
<li>They should only support additional functionality related to curating their data set</li>
<li>They may restrict the data types they accept and serve</li>
<li>They may restrict the data they accept and serve based on content or pubkey</li>
</ol>
<p>One additional feature that isn't currently standard but ought to be is strfry's negentropy synchronization feature. This is the opposite of AUTH, which protects a relay's own dataset, in that it allows relays to more efficiently share their data with peers. A nice bonus is that it also allows clients to use their local cache more effectively as well.</p>
<h2>Simple Made Easy</h2>
<p>Going back to Rich Hickey's talk, separating behavior and state allows you to work directly with your data, freely implementing new behavior whenever you need to. This applies to sets of events stored on relays just as much as it applies to in-memory data.</p>
<p>One thing that makes this possible is cryptographic hash functions, which cleanly transform state into values - the difference being that "state" couples a name with data that may change, while a hash is a compact representation of immutable data. If two hashes of event ids don't match, they're not the same set of events.</p>
<p>How does this apply to relays? Instead of adding new behavior to relays directly ("methods"), we can instead call "functions" on a relay's data.</p>
<p>This function can be anything - a centralized server, client code, or a DVM - that takes REQ filters as input. The function gathers the needed data (maybe from a cache, maybe using a sync command, maybe from multiple relays for completeness), performs the transformation, and returns it. The result is that relays become simple, interoperable repositories for data, without limiting what server-side computation can be applied to events.</p>
<p>While huge search indexes and centralized servers have a cost in terms of centralization, I think DVMs solve this problem brilliantly - the common interface for this augmented behavior is open, and can admit anyone who wants to start competing for search, counting, recommendations, or anything else you might want to do with events.</p>
<p>As Alan Perlis said, "It is better to have 100 functions operate on one data structure than to have 10 functions operate on 10 data structures."</p>
<h1>Encrypted Messages</h1>
<p>Nostr DMs were a huge mistake, and I want to do it again.</p>
<p>NIP 04 has some obvious problems, most notably metadata leakage. The cryptography also hasn't been audited, and has some potential theoretical attack vectors. I've been working with some other nostr devs on a new cryptographic primitive, which will be audited and hopefully result in a better foundation for future work.</p>
<p>But fixing the cryptography still doesn't fix DMs. Nostr is not really the right architecture for secure private messaging, because ratchets require state. Nostr is designed such that there are no hard dependencies between events, which are replicated across multiple relays. This makes it very hard to manage the kind of state that protocols like SimpleX or Signal require.</p>
<p>Even apart from the difficulty of implementing stateful messaging protocols on nostr, we have two other problems to contend with: metadata leaks and spotty deliverability. Both of these problems come from the reliance of nostr on relays, which generally are not trustworthy or reliable.</p>
<h2>Metadata Leakage</h2>
<p>NIP 04 is really bad. Anyone can see who you corresponded with, when, how frequently, and how much you said just by looking at the event. Vitor's NIP 24 chat proposal aims to fix this with gift wraps, which use ephemeral keys to obscure the sender, padding to obscure message size, timestamp randomization to obscure timing, and double-wrapping to prevent leakage of the signed message.</p>
<p>This is a big improvement, but there are other forms of metadata that are still visible. To start, the recipient is still visible, along with how many messages they have received and their general size. So you can tell if someone sends lots of messages, or not a lot, but that's about it.</p>
<p>If we don't assume relays are trustworthy though, there are all kinds of implicit metadata that can be used to infer information about the sender, including:</p>
<ul>
<li>Client fingerprinting</li>
<li>Relay selection for publishing and queries</li>
<li>IP address collection</li>
<li>First seen timestamp</li>
<li>Identification of users by AUTH</li>
<li>Correlation of the event with other messages sent/received during a session</li>
</ul>
<p>These issues are much harder to solve, because they are part of the process of delivering the message, rather than just constructing it.</p>
<h2>Transport and deliverability</h2>
<p>The key feature of nostr that makes it work is relays. Relays provide storage redundancy and heterogeneity of purpose with a common interface shared by all instances. This is great for censorship resistance, but everything comes with a tradeoff.</p>
<p>Completeness and consistency are not guaranteed on nostr. This is ok in a social media context, because there's no way to keep up with everything everyone you follow says anyway, and you can rely on interactions and algorithmic tools to catch you up on anything important you missed.</p>
<p>But with private messages, every payload counts. Receiving messages out of order, with a delay, or not at all can severely disrupt conversations between two people, leading to misunderstandings and worse. This is a common experience on nostr; even fiatjaf has expressed skepticism about the viability of private messages on nostr.</p>
<p>This flakiness comes from a combination of low relay quality and poor relay selection on the part of clients. Relays can't deliver messages if they can't keep up with clients, go offline, or drop messages (accidentally or deliberately). Likewise, clients can't find messages if they look for them in the wrong place.</p>
<h2>Relays fixes this</h2>
<p>Let me just put things into perspective really quick. Twitter DMs are not e2e encrypted, and weren't encrypted at all until earlier this year. Mastodon messages are not encrypted - instance admins can read everything. Facebook has e2ee messages, but only between normal users, not in communities, groups, business chats, or marketplace chats.</p>
<p>So while nostr's architecture is not sufficient to make secure encrypted communication a value proposition of the protocol in itself, there is a lot we can do to improve on the status quo. Because nostr has no admins, the only option for privacy of any kind is end-to-end encryption. Metadata leakage notwithstanding, nostr messages can be "good enough" for some definition of that phrase.</p>
<p>It's important to not just punt on making DMs available in a standard way, because there is an expectation that a complete social media solution will have a way to establish a private communication channel with someone else in the network. Otherwise you're stuck with public correspondence and link sharing in order to hop to another protocol.</p>
<p>Let's just assume that you agree with me at this point, and that until there is a javascript SDK for SimpleX or MLS, we're stuck with nostr DMs of some kind. So how can we reduce metadata leakage and improve deliverability?</p>
<h2>Fixing Flakiness</h2>
<p>Let's start with deliverability first. NIP 65's inbox/outbox model is great. While it doesn't fix deliverability on its own, if every relay recommended was in fact reliable, and reliably followed by clients, there would be a very clear indication of where a particular user's messages could be found. Neither of these things is really true right now, but I do think clients are moving in this direction. Hopefully we can educate users better on how to pick good relays.</p>
<p>There are some limits to this model of course. For example, if you want to read notes from 1000 pubkeys at once, your client will likely end up connecting to hundreds of relays unless it has a cap, in which case it will miss a lot of notes.</p>
<p>One clean solution to this problem is relay proxies. There are a few implementations, but the one I run at mux.coracle.social is a stateless proxy that uses a wrapper protocol so clients can still select and dispatch to relays. I originally built this to improve mobile data use by deduplicating events on the server, and it does that pretty well, although it currently does it in the most naive way possible.</p>
<p>Multiplextr currently does not qualify as a "real" relay based on my four rules, since it uses a wrapper protocol. However, a smarter implementation would be able to route requests and events effectively by relying on client authentication and filter analysis, without changing the protocol. This would also allow clients to completely offload the complex business of relay selection to its proxy. Clients would also be able to combine multiple proxies just like they combine relays - because proxies are relays!</p>
<h2>Proxying Privacy</h2>
<p>Another downside of NIP 65 is that it encourages clients to connect indiscriminately to hundreds of different relays based on tag hints, other users' preferences, and relays baked into bech32 identifiers. This is not only bad for battery life and performance, but also allows attackers to easily trick your client into to connecting to their relay so they can start analyzing your traffic.</p>
<p>The best way to defend yourself against nosy relays is to not connect to them at all. And the easiest way to do that is to only connect to relays you control (or trust), and let them do the dirty work for you.</p>
<p>With a proxy, even if you don't control it, you can reduce the number of parties who can snoop on your traffic by orders of magnitude. And since other people use the proxy too, your traffic gets mixed with theirs, making it much harder to analyze. Of course, the downside of using a public proxy is that the proxy sees all messages you send and receive, and the relays you select for each request. Even worse, an untrusted multiplexer can hijack an authenticated session, exfiltrating private data from protected relays.</p>
<p>A proxy you control (or trust, either via social relationships or economic ones) is the best of both worlds. This proxy could also do some smart things for you to improve privacy as well, for example:</p>
<ul>
<li>Delayed publishing of gift wrapped messages so relays can't guess as easily when the event was first seen.</li>
<li>Closing and re-opening connections to reduce the number of messages sent over an AUTH'd session.</li>
<li>It could block suspicious messages on the fly, for example spam or notes with phishing links.</li>
<li>If an abundance of options are available for relay selections, it could randomize which relays are used, or avoid using less reputable ones.</li>
</ul>
<p>So I guess what I'm saying here, is "run a node". But not just any node - in the early days of nostr there were a lot of people spinning up relays because they thought it helped decentralization. Well, as it turns out, just like in bitcoin you have to <em>use</em> your node in order for it to be useful.</p>
<h1>Beyond DMs</h1>
<p>I'm not done yet, though. What's the point of all this? Why put all this effort into "good enough" DMs when we could spend the effort adopting SimpleX or MLS (said Semisol, who lives rent free in my head)?</p>
<p>Well, because there isn't a single "best" DM option. As I've dug into the topic, I've discovered that a ton of tradeoffs exist between complexity, privacy, and scale. The way I understand it, there are three basic options here:</p>
<ul>
<li>One-to-one encryption. This is how both SimpleX and Vitor's group message draft works. It allows for things like ratchets to be added on top, and is fairly simple - but fails to scale because every message has to be encrypted separately for every group member, resulting in <code>n*m</code> messages, where <code>n</code> is the number of group members, and <code>m</code> is the number of messages sent.</li>
<li>Encryption via shared key. This is how WhatsApp works, and it scales really well because messages don't have to be duplicated. And while it does support forward secrecy, it does not support post-compromise security, so it is significantly less secure.</li>
<li>MLS has a unique hierarchical approach to managing keys, which improves the complexity of one-to-one encryption so that it's logarithmic rather than exponential. However, MLS is highly stateful and still has scaling limitations.</li>
</ul>
<p>My takeaway is that there is no perfect solution. Ratchets are the gold standard, but can't really be implemented using nostr relays, since they frequently require servers to have very specific characteristics, like the ability to deliver messages in order.</p>
<p>The fact remains though, that social media needs encrypted messaging of some kind, even if we encourage users to bail to a more complete solution if they want to be truly private. And encryption is useful beyond small group chats - think of Facebook groups, which scale to millions of people and whose users have a much lower expectation of privacy. This is what nostr is good at - social data, whether encrypted or in plaintext.</p>
<h2>Belt and Suspenders</h2>
<p>For a long time I have waffled between two visions of how private groups ought to work. Should they be encrypted messages sprinkled across the nostr network like confetti? Or should they live on one or two relays in plaintext, protected by AUTH?</p>
<p>Both of these options have issues. Sprinkling encrypted messages across the network almost guarantees deliverability problems, since already many commodity relays block gift wraps. And that's ok! They have no obligation to store your encrypted messages.</p>
<p>Storing group messages in plaintext is also sub-optimal, even if it's on a dedicated relay. Of course we're not going for military-grade secrecy here, but it would be trivially easy through a bug, or even a client that doesn't know how to deal with groups, to re-broadcast events that should stay private. We could do something wacky, like strip the signature from events hosted on a relay, but if we're going to do something non-standard, we might as well do the best we can.</p>
<p>So why not both? Group messages should be encrypted, and they should be stored on a particular set of relays. Again, assuming the relays used are trustworthy, this fixes both privacy and deliverability problems, because it's very clear where messages posted to the group should go.</p>
<p>Promoting relays to trusted status has some nice, unintended benefits too. One common objection to using encrypted content is that it becomes hard to filter. But if a relay is trusted to store a group's messages, it can also be trusted to be admitted as a member to the group. This would allow the relay to decrypt events and filter them to respond to requests by authenticated group members.</p>
<p>Of course, this would violate rule <a href='/tag/1/'>#1</a> for relays, since they would no longer be supporting standard functionality, but a guy can dream, can't he?</p>
<h1>Conclusion</h1>
<p>When I started working on nostr I had no idea it would end up being this complex to accomplish what I set out to do. Building a twitter clone was only a first step to an MVP, but I always had my eye on the prize of serving my local church community, which doesn't give a sat about social media per se.</p>
<p>Private groups are important to me not because I'm setting out to support political dissidents or journalists (although I hope they find nostr useful too), but because I want to get my friends off of Facebook, and the only way to do that is to create private marketplaces, calendars, communties, and more.</p>
]]></itunes:summary>
      <itunes:image href="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-lAQRH4mCyl4-unsplash.jpeg"/>
      </item>
      
      <item>
      <title><![CDATA[Building Relay Browsing Into Client Interfaces]]></title>
      <description><![CDATA[How should clients represent relays in user interfaces? Are they dimensions? coordinates? layers? buttons? checkboxes? topics? people? I don't know.]]></description>
             <itunes:subtitle><![CDATA[How should clients represent relays in user interfaces? Are they dimensions? coordinates? layers? buttons? checkboxes? topics? people? I don't know.]]></itunes:subtitle>
      <pubDate>Fri, 07 Apr 2023 16:03:19 GMT</pubDate>
      <link>https://hodlbod.npub.pro/post/1680874316525/</link>
      <comments>https://hodlbod.npub.pro/post/1680874316525/</comments>
      <guid isPermaLink="false">naddr1qqxnzd3cxqurwdpnxymr2v34qgsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgsrqsqqqa28fqd9z9</guid>
      <category>nostr</category>
      
        <media:content url="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-5k_RL3Zc6G0-unsplash.jpeg" medium="image"/>
        <enclosure 
          url="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-5k_RL3Zc6G0-unsplash.jpeg" length="0" 
          type="image/jpeg" 
        />
      <noteId>naddr1qqxnzd3cxqurwdpnxymr2v34qgsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgsrqsqqqa28fqd9z9</noteId>
      <npub>npub1jlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qdjynqn</npub>
      <dc:creator><![CDATA[ hodlbod]]></dc:creator>
      <content:encoded><![CDATA[<p>Yesterday I was browsing bountsr and discovered a <a href="https://bountsr.org/relay-browsing/">new bounty</a> by fiatjaf for adding "relay browsing" to clients. This is the bounty Coracle was born to claim! However, it's a problem I've been putting off for some time now, because it's a very hard problem requiring some real creativity. In this post I'll survey the state of the art, try to articulate my vague ideas about what needs to be done, and sketch some next steps toward realizing this goal.</p>
<h1>The problem of relays</h1>
<p>Relays are a problem. They are simultaneously an implementation detail that users don't understand and don't want to deal with, and the very soul of Nostr. So far, no client has unleashed the power of Nostr's architecture, instead focusing on ease of adoption by starting users off with a hard-coded set of relays. Users are then left to dig through their settings to change which relays they want to connect to. Others, like Primal, attempt to elide the concept of relays altogether and provide a unified view of the entire network. </p>
<p>Various nods to the importance of relays do exist in various clients however, for example:</p>
<ul>
<li>Amethyst shows pretty granular controls and stats on their relay list.</li>
<li>Snort (and others) shows the list of relays other users connect to on their profile page.</li>
<li>Gossip has all kinds of settings for how many relays to use, how smart to be about relay discovery, and more.</li>
<li>Coracle shows which relays an event was seen on in the note's overflow menu, and asks new users to select relays during the onboarding process.</li>
</ul>
<p>Other common patterns include: color-coding relays, differentiating between read and write relays, and auto-selecting relays different from the user's own selections in order to fetch context related to a given note or feed.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/relay-list.png" alt="Coracle's relay list"></p>
<p>All of these are great features, but they are baby steps, and don't fundamentally address the problem (or realize the possibility) of allowing users to navigate between overlapping venn diagrams of relays and their content.</p>
<h1>Let me tell you about my feelings</h1>
<p>I think it's generally a shared perception that these half-measures aren't enough, but nobody really knows what to do about it. Even fiatjaf, who has relentlessly pushed development efforts towards surfacing relays admits in the bounty cited above, "The app should make it seamless to browse these various scenarios, I have no idea how."</p>
<p>I share this utter sense of bewilderment. I feel unmoored when I try to think what a user interface that fully embraced  multiple relays would look like. Decades of using software with a single-master paradigm has broken my mind; designing something that could actually be used to seamlessly navigate between relays is a massive effort for my poor, tired brain.</p>
<p>The closest thing to a "vision" for what this would look like is what Arkin0x has built with <a href="https://onosendai.tech/">ONOSENDAI</a>: a vast, three-dimensional space that you can travel through. Although to solve the problem, they would have to use an address space focused on relationships between relays, pubkeys, and events, rather than event content simhashes.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/onosendai.png" alt="ONOSENDAI"></p>
<p>This could be a workable approach, resulting in something similar to <a href="https://lninsights.com/">LN Insights</a>, a browser for lightning network topology, which adds node capacity and clustering as additional dimensions. But it's also true that this type of visualization quickly becomes disorienting, and is far less familiar than a traditional user interface with buttons and menus.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/lninsights.png" alt="LN Insights"></p>
<p>There are examples of this kind of thing being executed successfully by tools like Figma which allow you to zoom in and out on your canvas to travel from one place to another. Games like Supreme Commander support zoom-to-navigate, in addition to showing multiple windowed views of the same game. Tools like Photoshop and vector graphics editors take a different approach and introduce an extra dimension by allowing you to group content into multiple layers.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/supreme-commander.jpeg" alt="Supreme Commander"></p>
<p>Another way to think about the additional dimension that relays introduce is by imagining Nostr is a virtual world, with geography (relays), actors (pubkeys), and history (events). Users are mobile, and can travel at will through the world (unless denied access by a relay), viewing artifacts left by other users in the form of published events. The wrinkle is that events can happen in multiple places at the same time, or be replicated across space over time as events get re-broadcasted.</p>
<p>Take a look at the <a href="https://t.me/ONOSENDAITECH/302">conversation</a> I had with Arkin0x on telegram while writing this post for more ideas for representing Nostr in 3D space.</p>
<h1>Back to flatland</h1>
<p>In traditional user interfaces, relationships within the data model are not usually represented spatially, except in very purpose-built applications like UML diagrams or mind maps. Instead, space is taken up by an additional dimension: affordances for user interaction. Screens are designed according to functionality, and access to groups of those functions exist in navigation items or menus. Content is addressed by overlaying those groups of functionality either literally via modal dialogs, or dimensionally using "Uniform Resource Locators". There's no space left for representing the same address space in multiple dimensions, especially simultaneously.</p>
<p>So, what is required is either a new UI element or a re-purposed one that satisfies the same semantics as a checkbox group: a way to choose zero or more options for the same value. This isn't too hard, you could add a dropdown menu on feed views, and call it good. But this won't make any sense to users unless they know what differentiates relays from one another, and with 1,300 relays in the network and counting, it will be impossible to process that information without help from the software.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/multi-select.webp" alt="Multi-selects"></p>
<p>So, relays need to be filtered and grouped. This can be partly accomplished by giving good names and metadata to relays, but the important thing is the content that lives on a given relay, which might be analyzed using the social graph, textually, or using some other heuristic. Unfortunately, with the current culture of cross-posting for reach, relays don't differ substantially from one another. For now, filters and groups have to be user-generated, which creates a chicken-and-egg problem, because remember? we are trying to make it easy for users to navigate Nostr!</p>
<p>Maybe a good place to start would be to create a tool that would allow users to analyze for themselves the factors contributing to relay differentiation, as specified in <a href="https://nostrbounties.com/b/naddr1qq9rzd3cxqcrjvesxqusygpm7rrrljungc6q0tuh5hj7ue863q73qlheu4vywtzwhx42a7j9n5psgqqqw4rs7umkzv">this bounty</a>. Then, those insights could be quantified and automatically integrated into a given client's implementation of groups and filters. Of course, that runs afoul of the <a href="https://blog.coracle.social/posts/c1c74b4b60f36a29b77c358e72eb0452bf742ed7fec1d5f5625e84b54c1cc05b">problem of centralization</a>.</p>
<p>Or, discovery could be built in to clients using crude tools like checkboxes, color codes, and modal dialogs, and as the network partitions and relays specialize due to scaling limitations users can begin to develop a gestalt for what kind of notes end up on a given relay. The naturally occurring social partitioning that would result would self-reinforce by allowing implementations to classify relay content by personalities or content central to content already hosted there.</p>
<h1>Conclusion</h1>
<p>This post has been far more stream-of-consciousness than usual, and for that I apologize. But I also thank you, dear reader, for helping me rubber-duck my way to profundity. Here are my take-aways (maybe yours are different):</p>
<ul>
<li>Multi-master content is a truly novel paradigm, and interface metaphors for surfacing it don't really exist.</li>
<li>The semantics of multi-master match multi-select and checkbox list interface elements.</li>
<li>Relays are not sufficiently differentiated to support intelligent filtering and grouping. Users cannot currently care about the distinctions between relays, because they don't currently exist.</li>
<li>The concept of "layers" in tools for video/image/graphics editing is probably the closest thing we have to a metaphor for representing two-dimensional content in multiple dimensions. Layers correspond well to dialogs, and so a first pass at this problem might be to show a feed's content modified by relay selection in a popover dialog.</li>
</ul>
<p>I'm sure I'm not the only one thinking about this problem, so please! Take a moment to leave a comment with your thoughts, opinions, or hallucinations.</p>
]]></content:encoded>
      <itunes:author><![CDATA[ hodlbod]]></itunes:author>
      <itunes:summary><![CDATA[<p>Yesterday I was browsing bountsr and discovered a <a href="https://bountsr.org/relay-browsing/">new bounty</a> by fiatjaf for adding "relay browsing" to clients. This is the bounty Coracle was born to claim! However, it's a problem I've been putting off for some time now, because it's a very hard problem requiring some real creativity. In this post I'll survey the state of the art, try to articulate my vague ideas about what needs to be done, and sketch some next steps toward realizing this goal.</p>
<h1>The problem of relays</h1>
<p>Relays are a problem. They are simultaneously an implementation detail that users don't understand and don't want to deal with, and the very soul of Nostr. So far, no client has unleashed the power of Nostr's architecture, instead focusing on ease of adoption by starting users off with a hard-coded set of relays. Users are then left to dig through their settings to change which relays they want to connect to. Others, like Primal, attempt to elide the concept of relays altogether and provide a unified view of the entire network. </p>
<p>Various nods to the importance of relays do exist in various clients however, for example:</p>
<ul>
<li>Amethyst shows pretty granular controls and stats on their relay list.</li>
<li>Snort (and others) shows the list of relays other users connect to on their profile page.</li>
<li>Gossip has all kinds of settings for how many relays to use, how smart to be about relay discovery, and more.</li>
<li>Coracle shows which relays an event was seen on in the note's overflow menu, and asks new users to select relays during the onboarding process.</li>
</ul>
<p>Other common patterns include: color-coding relays, differentiating between read and write relays, and auto-selecting relays different from the user's own selections in order to fetch context related to a given note or feed.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/relay-list.png" alt="Coracle's relay list"></p>
<p>All of these are great features, but they are baby steps, and don't fundamentally address the problem (or realize the possibility) of allowing users to navigate between overlapping venn diagrams of relays and their content.</p>
<h1>Let me tell you about my feelings</h1>
<p>I think it's generally a shared perception that these half-measures aren't enough, but nobody really knows what to do about it. Even fiatjaf, who has relentlessly pushed development efforts towards surfacing relays admits in the bounty cited above, "The app should make it seamless to browse these various scenarios, I have no idea how."</p>
<p>I share this utter sense of bewilderment. I feel unmoored when I try to think what a user interface that fully embraced  multiple relays would look like. Decades of using software with a single-master paradigm has broken my mind; designing something that could actually be used to seamlessly navigate between relays is a massive effort for my poor, tired brain.</p>
<p>The closest thing to a "vision" for what this would look like is what Arkin0x has built with <a href="https://onosendai.tech/">ONOSENDAI</a>: a vast, three-dimensional space that you can travel through. Although to solve the problem, they would have to use an address space focused on relationships between relays, pubkeys, and events, rather than event content simhashes.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/onosendai.png" alt="ONOSENDAI"></p>
<p>This could be a workable approach, resulting in something similar to <a href="https://lninsights.com/">LN Insights</a>, a browser for lightning network topology, which adds node capacity and clustering as additional dimensions. But it's also true that this type of visualization quickly becomes disorienting, and is far less familiar than a traditional user interface with buttons and menus.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/lninsights.png" alt="LN Insights"></p>
<p>There are examples of this kind of thing being executed successfully by tools like Figma which allow you to zoom in and out on your canvas to travel from one place to another. Games like Supreme Commander support zoom-to-navigate, in addition to showing multiple windowed views of the same game. Tools like Photoshop and vector graphics editors take a different approach and introduce an extra dimension by allowing you to group content into multiple layers.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/supreme-commander.jpeg" alt="Supreme Commander"></p>
<p>Another way to think about the additional dimension that relays introduce is by imagining Nostr is a virtual world, with geography (relays), actors (pubkeys), and history (events). Users are mobile, and can travel at will through the world (unless denied access by a relay), viewing artifacts left by other users in the form of published events. The wrinkle is that events can happen in multiple places at the same time, or be replicated across space over time as events get re-broadcasted.</p>
<p>Take a look at the <a href="https://t.me/ONOSENDAITECH/302">conversation</a> I had with Arkin0x on telegram while writing this post for more ideas for representing Nostr in 3D space.</p>
<h1>Back to flatland</h1>
<p>In traditional user interfaces, relationships within the data model are not usually represented spatially, except in very purpose-built applications like UML diagrams or mind maps. Instead, space is taken up by an additional dimension: affordances for user interaction. Screens are designed according to functionality, and access to groups of those functions exist in navigation items or menus. Content is addressed by overlaying those groups of functionality either literally via modal dialogs, or dimensionally using "Uniform Resource Locators". There's no space left for representing the same address space in multiple dimensions, especially simultaneously.</p>
<p>So, what is required is either a new UI element or a re-purposed one that satisfies the same semantics as a checkbox group: a way to choose zero or more options for the same value. This isn't too hard, you could add a dropdown menu on feed views, and call it good. But this won't make any sense to users unless they know what differentiates relays from one another, and with 1,300 relays in the network and counting, it will be impossible to process that information without help from the software.</p>
<p><img src="https://coracle.us-southeast-1.linodeobjects.com/blog/2304/multi-select.webp" alt="Multi-selects"></p>
<p>So, relays need to be filtered and grouped. This can be partly accomplished by giving good names and metadata to relays, but the important thing is the content that lives on a given relay, which might be analyzed using the social graph, textually, or using some other heuristic. Unfortunately, with the current culture of cross-posting for reach, relays don't differ substantially from one another. For now, filters and groups have to be user-generated, which creates a chicken-and-egg problem, because remember? we are trying to make it easy for users to navigate Nostr!</p>
<p>Maybe a good place to start would be to create a tool that would allow users to analyze for themselves the factors contributing to relay differentiation, as specified in <a href="https://nostrbounties.com/b/naddr1qq9rzd3cxqcrjvesxqusygpm7rrrljungc6q0tuh5hj7ue863q73qlheu4vywtzwhx42a7j9n5psgqqqw4rs7umkzv">this bounty</a>. Then, those insights could be quantified and automatically integrated into a given client's implementation of groups and filters. Of course, that runs afoul of the <a href="https://blog.coracle.social/posts/c1c74b4b60f36a29b77c358e72eb0452bf742ed7fec1d5f5625e84b54c1cc05b">problem of centralization</a>.</p>
<p>Or, discovery could be built in to clients using crude tools like checkboxes, color codes, and modal dialogs, and as the network partitions and relays specialize due to scaling limitations users can begin to develop a gestalt for what kind of notes end up on a given relay. The naturally occurring social partitioning that would result would self-reinforce by allowing implementations to classify relay content by personalities or content central to content already hosted there.</p>
<h1>Conclusion</h1>
<p>This post has been far more stream-of-consciousness than usual, and for that I apologize. But I also thank you, dear reader, for helping me rubber-duck my way to profundity. Here are my take-aways (maybe yours are different):</p>
<ul>
<li>Multi-master content is a truly novel paradigm, and interface metaphors for surfacing it don't really exist.</li>
<li>The semantics of multi-master match multi-select and checkbox list interface elements.</li>
<li>Relays are not sufficiently differentiated to support intelligent filtering and grouping. Users cannot currently care about the distinctions between relays, because they don't currently exist.</li>
<li>The concept of "layers" in tools for video/image/graphics editing is probably the closest thing we have to a metaphor for representing two-dimensional content in multiple dimensions. Layers correspond well to dialogs, and so a first pass at this problem might be to show a feed's content modified by relay selection in a popover dialog.</li>
</ul>
<p>I'm sure I'm not the only one thinking about this problem, so please! Take a moment to leave a comment with your thoughts, opinions, or hallucinations.</p>
]]></itunes:summary>
      <itunes:image href="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-5k_RL3Zc6G0-unsplash.jpeg"/>
      </item>
      
      <item>
      <title><![CDATA[Relays as Routers: Keeping Nostr Extensions Decentralized]]></title>
      <description><![CDATA[Instead of allowing non-standard data services like search engines or recommendations gatekeep relays, flip the script and make relays the gatekeepers instead. The addition of a single feature can open the door for relays to support any extension at no additional cost.
]]></description>
             <itunes:subtitle><![CDATA[Instead of allowing non-standard data services like search engines or recommendations gatekeep relays, flip the script and make relays the gatekeepers instead. The addition of a single feature can open the door for relays to support any extension at no additional cost.
]]></itunes:subtitle>
      <pubDate>Fri, 31 Mar 2023 17:41:21 GMT</pubDate>
      <link>https://hodlbod.npub.pro/post/relays-as-routers/</link>
      <comments>https://hodlbod.npub.pro/post/relays-as-routers/</comments>
      <guid isPermaLink="false">naddr1qqghyetvv9uhxttpwvkhymm4w3jhyuczyztuwzjyxe4x2dwpgken87tna2rdlhpd02va5cvvgrrywpddnr3jyqcyqqq823cx382jr</guid>
      <category>nostr</category>
      
        <media:content url="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-lAQRH4mCyl4-unsplash.jpeg" medium="image"/>
        <enclosure 
          url="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-lAQRH4mCyl4-unsplash.jpeg" length="0" 
          type="image/jpeg" 
        />
      <noteId>naddr1qqghyetvv9uhxttpwvkhymm4w3jhyuczyztuwzjyxe4x2dwpgken87tna2rdlhpd02va5cvvgrrywpddnr3jyqcyqqq823cx382jr</noteId>
      <npub>npub1jlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qdjynqn</npub>
      <dc:creator><![CDATA[ hodlbod]]></dc:creator>
      <content:encoded><![CDATA[<p>First, a product announcement.</p>
<p><a href="https://coracle.social">Coracle</a> now supports connection multiplexing, which can reduce bandwidth usage by over 90% depending on how many relays you use. It's opt-in for now, but you can set it up by going to Settings and entering <code>wss://multiplextr.coracle.social</code> as your "Multiplextr URL".</p>
<p>You can check out the source code and self-host the library using <a href="https://github.com/coracle-social/multiplextr">this link</a>. If you're a dev and want to add client support for multiplextr, the <a href="https://github.com/coracle-social/paravel">library</a> I built to support this use case might be of use.</p>
<p>Now, on to your regularly scheduled blog post.</p>
<p><img src="https://media.giphy.com/media/xznyPebL28X5u/giphy.gif" alt="Now for something completely different"></p>
<p>The above announcement isn't irrelevant to what I want to talk about in this post, which is (broadly) the question of "how can Nostr remain decentralized and still support advanced functionality?"</p>
<p>This is probably the most common question articulated among devs and enthusiasts - is search centralizing? What about recommendation engines? COUNT? Analytics? The answer is yes, and responses range from "it'll be fine" to "nostr is already captured".</p>
<p>For my part, I'm not sure if this problem can be solved. Already we have a <a href="https://www.investopedia.com/ask/answers/09/browser-wars-netscape-internet-explorer.asp">browser wars</a> dynamic emerging among clients, and business models based on proprietary services and advertising have been publicly considered. For the record, I don't think conventional business models are necessarily bad. The world works this way for a reason and Nostr isn't going to change that by default.</p>
<p>Nevertheless, I want to see a new internet emerge where my attention belongs to me, and I'm not beholden to massive companies who don't give a rip about me. As a result, much of the work I've put into Coracle hasn't gone into fun features, but into things I think will help realize the vision of Nostr. This gives me FOMO as I watch others' progress, but if I don't stay focused on <a href="https://blog.coracle.social/posts/a37516e98e3aa496645ab22d3427f534ec565b56916ffde4e64f292b6b85f697">my vision for Nostr</a>, what am I even doing?</p>
<p>I should be clear that this is not a judgment on the motivations of others, building for fun and profit is just as legitimate as building to idealistically realize the best of all Nostrs. However, I would say that it is every developer's duty to keep in mind that what we're trying to accomplish here is not a web2 clone.</p>
<h1>Two, and only two options</h1>
<p>With all that said, let's get into the meat of the problem. There's a false dichotomy floating around out there that we have two options for adding server-side functionality to the nostr ecosystem. Option 1: pack all required functionality into relays, eliminating the "dumb relay" model, and making it extremely difficult to run a relay. Option 2: keep relays dumb and the protocol minimal, allowing indexers, search engines, and recommendation services (which I'll collectively call "extensions" here) to profit by solving advanced use cases.</p>
<p>Both alternatives are obviously deficient. Relays need to be something hobbyists can run; requiring relays to fold in a recommendation engine or search index makes that much harder, and for every feature required, proprietary solutions will be able to build a bigger moat.</p>
<p>On the other hand, proprietary extensions will not bother to interoperate. This will result in an app-store-like landscape of competing extensions, which will redirect developer and user attention away from relays to extensions. If nostr is to succeed, relays must remain an important first-class concept. Aggregators and indexers that gloss over the differences between relays destroy much of the value an individual relay has to offer.</p>
<p>In either case, some components of the network will become too sophisticated for a layman to deploy. The only alternative is for a few professionals to take up the slack and grow their service as a business. But I think there's a way to squeeze between the horns of the dilemma.</p>
<h1>It's all about routing</h1>
<p>It seems to me that most people prefer the "extension" model of scaling functionality of Nostr as a pragmatic, market-driven alternative to the impossibility of requiring all relays to support all possible features. And I agree, the folks developing and operating more sophisticated tools should be compensated for their hard work.</p>
<p>The real problem with this approach is that not that extensions are competitive and specialized, but that they obscure the importance of relays by becoming gatekeepers for data by providing additional functionality. If a client or user has to select a search engine and ask it to return results for a given relay, they have given that search engine control over their results, when their trust really should be placed in the relay itself.</p>
<p>(I will say as an aside, that there are scenarios when the gatekeeper approach does make sense, like when a user wants to "bring his own algorithm". But this should be something a user can opt-in to, not a default requirement for accessing the underlying protocol.)</p>
<p>Here's my proposal: instead of requiring users to trust some non-standard extension to make decisions for them, flip the script and make relays the gatekeepers instead. With this approach, the addition of a single feature can open the door for relays to support any extension at no additional cost.</p>
<p>One of the most exciting aspects of Nostr is the redundancy relays provide. With Nostr, you don't need to trust a single entity to store your data for you! Why should you trust a single gatekeeper to route you to that data? Relays don't need to provide search or recommendations or indexing functionality directly, they can simply send you to a third-party extension <em>they</em> deem trustworthy.</p>
<p>This approach allows extensions to piggy-back on the trust already endowed in relays by end users. By allowing relays that are already aligned with end users to broker connections with extensions, they form a circuit breaker for delegated trust. This is more convenient for end users, and makes it easier to switch extensions if needed, since relay operators are more likely to have their finger on the pulse than end users.</p>
<p>It also enables cleaner business relationships. Instead of asking clients to create custom integrations with particular extensions leading to vendor lock-in, an extension provider can implement a common interface and sell to relays instead by offering to index their particular data set.</p>
<p>With this model, relays have the flexibility to either provide their own advanced functionality or delegate it to someone else, reducing the functionality gap that would otherwise emerge with thick relays without removing the ability for extension service providers to run a business, all the while keeping users and clients focused on interacting with relay operators rather than non-standard extensions.</p>
<h1>Making it happen</h1>
<p>The difficulty with this of course is that add-on services need to be identifiable based on functionality, and they must be interoperable. This means that their functionality must be described by some protocol (whether the core Nostr protocol or an addition to it), rather than by proprietary extensions. There will be extensions that are too complex or special-purpose to fit into this model, or for whom interoperability doesn't matter. That's ok. But for the rest, the work of specifying extensions will pay off in the long run.</p>
<p>This routing layer might take a variety of forms - I've already proposed an <a href="https://github.com/nostr-protocol/nips/pull/259">addition to</a> to NIP 11 for service recommendations. Clients would look up what add-ons their relays recommend, then follow those recommendations to find a service that supports their requirements.</p>
<p>It also occurs to me having written my multiplexer relay this week (and here we come full circle) that it would be trivially easy for relays to proxy certain types of requests. So for example, a relay might fulfill REQs itself, but pass SEARCH requests on to a third-party extension and relay the result to the end user.</p>
<p>In either case though, a well-behaved client could get all the functionality desired, for all of the data required, without compomising the brilliant trust model fiatjaf came up with.</p>
<h1>Conclusion</h1>
<p>I think this is a very important problem to solve, and I think relay-sponsored extension recommendations/routing is a very good way to do it. So, please comment with criticisms! And if you agree with me, and want to see something like this become the standard, comment on my <a href="https://github.com/nostr-protocol/nips/pull/259">pull request</a>.</p>
]]></content:encoded>
      <itunes:author><![CDATA[ hodlbod]]></itunes:author>
      <itunes:summary><![CDATA[<p>First, a product announcement.</p>
<p><a href="https://coracle.social">Coracle</a> now supports connection multiplexing, which can reduce bandwidth usage by over 90% depending on how many relays you use. It's opt-in for now, but you can set it up by going to Settings and entering <code>wss://multiplextr.coracle.social</code> as your "Multiplextr URL".</p>
<p>You can check out the source code and self-host the library using <a href="https://github.com/coracle-social/multiplextr">this link</a>. If you're a dev and want to add client support for multiplextr, the <a href="https://github.com/coracle-social/paravel">library</a> I built to support this use case might be of use.</p>
<p>Now, on to your regularly scheduled blog post.</p>
<p><img src="https://media.giphy.com/media/xznyPebL28X5u/giphy.gif" alt="Now for something completely different"></p>
<p>The above announcement isn't irrelevant to what I want to talk about in this post, which is (broadly) the question of "how can Nostr remain decentralized and still support advanced functionality?"</p>
<p>This is probably the most common question articulated among devs and enthusiasts - is search centralizing? What about recommendation engines? COUNT? Analytics? The answer is yes, and responses range from "it'll be fine" to "nostr is already captured".</p>
<p>For my part, I'm not sure if this problem can be solved. Already we have a <a href="https://www.investopedia.com/ask/answers/09/browser-wars-netscape-internet-explorer.asp">browser wars</a> dynamic emerging among clients, and business models based on proprietary services and advertising have been publicly considered. For the record, I don't think conventional business models are necessarily bad. The world works this way for a reason and Nostr isn't going to change that by default.</p>
<p>Nevertheless, I want to see a new internet emerge where my attention belongs to me, and I'm not beholden to massive companies who don't give a rip about me. As a result, much of the work I've put into Coracle hasn't gone into fun features, but into things I think will help realize the vision of Nostr. This gives me FOMO as I watch others' progress, but if I don't stay focused on <a href="https://blog.coracle.social/posts/a37516e98e3aa496645ab22d3427f534ec565b56916ffde4e64f292b6b85f697">my vision for Nostr</a>, what am I even doing?</p>
<p>I should be clear that this is not a judgment on the motivations of others, building for fun and profit is just as legitimate as building to idealistically realize the best of all Nostrs. However, I would say that it is every developer's duty to keep in mind that what we're trying to accomplish here is not a web2 clone.</p>
<h1>Two, and only two options</h1>
<p>With all that said, let's get into the meat of the problem. There's a false dichotomy floating around out there that we have two options for adding server-side functionality to the nostr ecosystem. Option 1: pack all required functionality into relays, eliminating the "dumb relay" model, and making it extremely difficult to run a relay. Option 2: keep relays dumb and the protocol minimal, allowing indexers, search engines, and recommendation services (which I'll collectively call "extensions" here) to profit by solving advanced use cases.</p>
<p>Both alternatives are obviously deficient. Relays need to be something hobbyists can run; requiring relays to fold in a recommendation engine or search index makes that much harder, and for every feature required, proprietary solutions will be able to build a bigger moat.</p>
<p>On the other hand, proprietary extensions will not bother to interoperate. This will result in an app-store-like landscape of competing extensions, which will redirect developer and user attention away from relays to extensions. If nostr is to succeed, relays must remain an important first-class concept. Aggregators and indexers that gloss over the differences between relays destroy much of the value an individual relay has to offer.</p>
<p>In either case, some components of the network will become too sophisticated for a layman to deploy. The only alternative is for a few professionals to take up the slack and grow their service as a business. But I think there's a way to squeeze between the horns of the dilemma.</p>
<h1>It's all about routing</h1>
<p>It seems to me that most people prefer the "extension" model of scaling functionality of Nostr as a pragmatic, market-driven alternative to the impossibility of requiring all relays to support all possible features. And I agree, the folks developing and operating more sophisticated tools should be compensated for their hard work.</p>
<p>The real problem with this approach is that not that extensions are competitive and specialized, but that they obscure the importance of relays by becoming gatekeepers for data by providing additional functionality. If a client or user has to select a search engine and ask it to return results for a given relay, they have given that search engine control over their results, when their trust really should be placed in the relay itself.</p>
<p>(I will say as an aside, that there are scenarios when the gatekeeper approach does make sense, like when a user wants to "bring his own algorithm". But this should be something a user can opt-in to, not a default requirement for accessing the underlying protocol.)</p>
<p>Here's my proposal: instead of requiring users to trust some non-standard extension to make decisions for them, flip the script and make relays the gatekeepers instead. With this approach, the addition of a single feature can open the door for relays to support any extension at no additional cost.</p>
<p>One of the most exciting aspects of Nostr is the redundancy relays provide. With Nostr, you don't need to trust a single entity to store your data for you! Why should you trust a single gatekeeper to route you to that data? Relays don't need to provide search or recommendations or indexing functionality directly, they can simply send you to a third-party extension <em>they</em> deem trustworthy.</p>
<p>This approach allows extensions to piggy-back on the trust already endowed in relays by end users. By allowing relays that are already aligned with end users to broker connections with extensions, they form a circuit breaker for delegated trust. This is more convenient for end users, and makes it easier to switch extensions if needed, since relay operators are more likely to have their finger on the pulse than end users.</p>
<p>It also enables cleaner business relationships. Instead of asking clients to create custom integrations with particular extensions leading to vendor lock-in, an extension provider can implement a common interface and sell to relays instead by offering to index their particular data set.</p>
<p>With this model, relays have the flexibility to either provide their own advanced functionality or delegate it to someone else, reducing the functionality gap that would otherwise emerge with thick relays without removing the ability for extension service providers to run a business, all the while keeping users and clients focused on interacting with relay operators rather than non-standard extensions.</p>
<h1>Making it happen</h1>
<p>The difficulty with this of course is that add-on services need to be identifiable based on functionality, and they must be interoperable. This means that their functionality must be described by some protocol (whether the core Nostr protocol or an addition to it), rather than by proprietary extensions. There will be extensions that are too complex or special-purpose to fit into this model, or for whom interoperability doesn't matter. That's ok. But for the rest, the work of specifying extensions will pay off in the long run.</p>
<p>This routing layer might take a variety of forms - I've already proposed an <a href="https://github.com/nostr-protocol/nips/pull/259">addition to</a> to NIP 11 for service recommendations. Clients would look up what add-ons their relays recommend, then follow those recommendations to find a service that supports their requirements.</p>
<p>It also occurs to me having written my multiplexer relay this week (and here we come full circle) that it would be trivially easy for relays to proxy certain types of requests. So for example, a relay might fulfill REQs itself, but pass SEARCH requests on to a third-party extension and relay the result to the end user.</p>
<p>In either case though, a well-behaved client could get all the functionality desired, for all of the data required, without compomising the brilliant trust model fiatjaf came up with.</p>
<h1>Conclusion</h1>
<p>I think this is a very important problem to solve, and I think relay-sponsored extension recommendations/routing is a very good way to do it. So, please comment with criticisms! And if you agree with me, and want to see something like this become the standard, comment on my <a href="https://github.com/nostr-protocol/nips/pull/259">pull request</a>.</p>
]]></itunes:summary>
      <itunes:image href="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-lAQRH4mCyl4-unsplash.jpeg"/>
      </item>
      
      <item>
      <title><![CDATA[A Vision for Nostr]]></title>
      <description><![CDATA[What Mastodon got wrong, and what I hope Nostr gets right]]></description>
             <itunes:subtitle><![CDATA[What Mastodon got wrong, and what I hope Nostr gets right]]></itunes:subtitle>
      <pubDate>Wed, 29 Mar 2023 19:55:14 GMT</pubDate>
      <link>https://hodlbod.npub.pro/post/a-vision-for-nostr/</link>
      <comments>https://hodlbod.npub.pro/post/a-vision-for-nostr/</comments>
      <guid isPermaLink="false">naddr1qqfxzttkd9ekjmmw94nx7u3ddehhxarjqgsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgsrqsqqqa2807nk73</guid>
      <category>nostr</category>
      
        <media:content url="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-_lwLalY6Yzg-unsplash.jpeg" medium="image"/>
        <enclosure 
          url="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-_lwLalY6Yzg-unsplash.jpeg" length="0" 
          type="image/jpeg" 
        />
      <noteId>naddr1qqfxzttkd9ekjmmw94nx7u3ddehhxarjqgsf03c2gsmx5ef4c9zmxvlew04gdh7u94afnknp33qvv3c94kvwxgsrqsqqqa2807nk73</noteId>
      <npub>npub1jlrs53pkdfjnts29kveljul2sm0actt6n8dxrrzqcersttvcuv3qdjynqn</npub>
      <dc:creator><![CDATA[ hodlbod]]></dc:creator>
      <content:encoded><![CDATA[<p>"What is Nostr?" is a hard question to answer. But an even more difficult one is "what should Nostr be?" Set aside the fact that "other stuff" is making up an ever-growing share of Nostr applications, even the social media use case on its own is a fractal of a problem.</p>
<p>What's encouraging though, is that despite the complexity of "social media", there is a surprising level of consensus on what needs to be done - within the Nostr developer community, differences are characterized more by emphasis than by direction.</p>
<h1>Staying on mission</h1>
<p>Instead of focusing on "problems to be solved" within the current system (e.g. content monetization or data harvesting), people who "get" nostr have made its core principles their own. Because these principles radically differ from the way things are done in centralized systems, they spawn a complex system of new affordances and limitations.</p>
<p>If I had to sum up what the core principle of Nostr is, I would say "individual sovereignty". Nostr is a social experiment that asks people to take responsibility for what they say (and sell, host, publish, promote). This topic has been explored ad nauseum by <a href="https://dergigi.com/2019/08/22/the-rise-of-the-sovereign-individual/">better writers than I</a> using Bitcoin as a vehicle, so I'll avoid re-treading the same ground if I can, except to point out that the two key design decisions of the Nostr protocol, self-custody of keys and hosting spread across multiple relays, simultaneously entrust control to users and revoke certain entitlements users are accustomed to.</p>
<p>It's well- (maybe even over-) understood what the risks and benefits are of holding your own keys. And being able to either select or host your own relays, each with different purposes and characteristics, gives individuals a level of control over his own publishing platform precedented only by the World Wide Web itself.</p>
<h1>Lies they tell</h1>
<p>But there are a lot of things users lose when moving away from a centralized platform. The ability to edit, delete, block, and promote content are not what I'm talking about - the guarantees for being able to do these things on Nostr are weaker, but as long as someone can take a screenshot of your Tweet, or block Google's ads, or log in with a different account, the affordances provided by centralized platforms are conveniences at best, and illusory at worst - that is, unless we go full digital panopticon, with universal biometric authentication and DRM for our brains.</p>
<p>What is more interesting to me is how centralized social media platforms lie about what they essentially are. Twitter's motto is "what’s happening", and their <a href="https://about.twitter.com/en">about page</a> features a tweet encouraging others to "Speak the truth, even if your voice shakes." And yet over the last several years they have censored real news, promoted propaganda, and shadow banned those whose "voice shakes". Musk's desperate claims that "we'll stop, I promise" don't negate the fact that Twitter retains control over users' speech in a way that is inherently in conflict with their stated mission.</p>
<p>This is true even of non-political speech, because it is in Twitter's interest to promote content that drives engagement, because engagement is what in turn drives advertising profits. This undermines their claim of user enfranchisement - they exercise partiality in choosing whose voice gets a megaphone.</p>
<p>Users of Nostr know the feeling of this weight being lifted. Nostr is anything but polished, but that's part of the charm - you know there is no one scanning your content, deciding who sees what and with what "added context". Many users including myself have experienced a 10x or more increase in engagement, despite a much smaller number of people on the platform. This is of course likely due not only to the lack of an algorithm, but also to the lack of celebrities, which tend to absorb attention, leaving little for the rest of us. But for now, Nostr is for the plebs.</p>
<h1>Cutting the Gordian Knot</h1>
<p>And I hope, and have reason, that it will continue to be so. When I spoke to my pastor prior to moving to Austin to work on Coracle full-time, I asked him what problems related to social media he would like to see solved. He said that he would like to see a solution that puts users in control of their algorithm, and allows individuals to broadcast their content to as wide an audience as possible.</p>
<p>There is a contradiction here, and the claim that it can be solved is one of the main lies that centralized platforms like to tell. You are free to broadcast your data as widely as you want, but no one is obligated to read it. Twitter tries to square the circle by artificially reversing this trade-off, resulting in a system where "you can't broadcast your data unless we want to force people to read it." But even they can't give their users control while simultaneously taking it away.</p>
<p>There is a path forward though, and now we finally get to the point of this post. Nostr is so revolutionary because it puts "digital localism" within reach. I had better define my terms here, since "digital localism" is used to describe a lot of dystopian ideas I'm not very excited about. What I mean by the term is something like "social relevance". Contra the egalitarians, there are real differences that exist to set groups of people apart. Things like topical interest, physical geography, professional network, religious belief, and yes, ethnicity and sex.</p>
<h1>What is a community anyway</h1>
<p>The fact that digital "communties" exist is something that to their credit Mastodon recognized, and sought to accommodate. But they missed the fact that humanity is partitioned into a nearly infinite number of overlapping sub-groups based on a nearly infinite number of dimensions. Yes, maybe I should be friends with you because you also like cats, but let's refine this further, do you think cilantro tastes like soap, are you a member of the Church of Satan, are you Italian, have you been reading Hayak lately, do you like watching Hallmark movies, English, do you speak it? Partitioning people into groups based on a single dimension is an exercise in futility, and is the reason Mastodon instances are either ghost towns or home to millions of users.</p>
<p>By allowing users to download/host their own data and join as many and whichever relays they choose based on arbitrary criteria, people are now able to co-locate in digital space, and interact with each instance in a different way. This is why I'm not excited about tools that spray your data to as many relays as possible. This only serves to maintain the illusion that replicating all content across every instance can scale, and it can't.</p>
<p>Instead, relays should differentiate, both in terms of function and membership. In the future (and even now) there will be closed archival relays that scrape the network and provide a backup of user data for a fee; public-read, private-write relays that allow members to participate in an exclusive group with greater reach; private-read, private-write closed community relays; public "town square" relays, paid relays that provide indexes, full-text search, or content recommendations for the wider network (or a relevant subset of it); and relays that provide oracles for data external to nostr. The ability of users to pick and choose which relays to connect to (and to multiplex those connections through yet another proxy/aggregator relay) allows them to define their own low-granularity social graph, refining it further with follows, mutes, and other "algorithmic" tools.</p>
<p>The same is true of client implementations. Many people building social media platforms want to "fix Twitter". But that vision of digital society is amazingly narrow (luckily, Nostr developers don't seem to suffer from the same kind of myopia). <em>Most</em> people I know don't have Twitter accounts, or use them. For them, Twitter is about as relevant to their lives as CNN. Instead, they use private Facebook groups to arrange babysitters for their kids, or Cragislist to buy and sell local goods. They use Google maps to find reviews for nearby businesses, and the church email list to keep up with prayer requests. They subscribe to newsletters their friends publish, and spend their days at work sending memes over Slack. The common theme here is that all these platforms connect "us" with "mine", not with "them". And yes, journalism and topical interest ala Reddit is a part of this, but for normal people, a vanishingly small part. But let's stop squawking about "echo chambers".</p>
<p>And Nostr, <a href="https://blog.coracle.social/what-nostr-is-bad-at.html">despite its limitations</a>, can be applied to every use case enumerated above. In so doing, it will free regular people from the constraining force of opinionated, artificial, centralized communication platforms, and allow them to build a digital social network that complements real life.</p>
<h1>Conclusion</h1>
<p>The driving force, for me, is not to erase our differences and create an egalitarian utopia, or stick it to big tech, or to make money, but to see the people I love, who belong to me, and to whom I belong, flourish by being connected with the people who belong to them, and to whom they belong. The resulting network will be characterized by high trust and high cohesion, laying a solid foundation for content and ideas to efficiently propagate across the distributed social graph, similar to how the lightning network routes transactions. But the key to making this work is to rise to the occasion, and take back our digital sovereignty by making it as easy for the average person to navigate the digital social landscape as they do in real life.</p>
]]></content:encoded>
      <itunes:author><![CDATA[ hodlbod]]></itunes:author>
      <itunes:summary><![CDATA[<p>"What is Nostr?" is a hard question to answer. But an even more difficult one is "what should Nostr be?" Set aside the fact that "other stuff" is making up an ever-growing share of Nostr applications, even the social media use case on its own is a fractal of a problem.</p>
<p>What's encouraging though, is that despite the complexity of "social media", there is a surprising level of consensus on what needs to be done - within the Nostr developer community, differences are characterized more by emphasis than by direction.</p>
<h1>Staying on mission</h1>
<p>Instead of focusing on "problems to be solved" within the current system (e.g. content monetization or data harvesting), people who "get" nostr have made its core principles their own. Because these principles radically differ from the way things are done in centralized systems, they spawn a complex system of new affordances and limitations.</p>
<p>If I had to sum up what the core principle of Nostr is, I would say "individual sovereignty". Nostr is a social experiment that asks people to take responsibility for what they say (and sell, host, publish, promote). This topic has been explored ad nauseum by <a href="https://dergigi.com/2019/08/22/the-rise-of-the-sovereign-individual/">better writers than I</a> using Bitcoin as a vehicle, so I'll avoid re-treading the same ground if I can, except to point out that the two key design decisions of the Nostr protocol, self-custody of keys and hosting spread across multiple relays, simultaneously entrust control to users and revoke certain entitlements users are accustomed to.</p>
<p>It's well- (maybe even over-) understood what the risks and benefits are of holding your own keys. And being able to either select or host your own relays, each with different purposes and characteristics, gives individuals a level of control over his own publishing platform precedented only by the World Wide Web itself.</p>
<h1>Lies they tell</h1>
<p>But there are a lot of things users lose when moving away from a centralized platform. The ability to edit, delete, block, and promote content are not what I'm talking about - the guarantees for being able to do these things on Nostr are weaker, but as long as someone can take a screenshot of your Tweet, or block Google's ads, or log in with a different account, the affordances provided by centralized platforms are conveniences at best, and illusory at worst - that is, unless we go full digital panopticon, with universal biometric authentication and DRM for our brains.</p>
<p>What is more interesting to me is how centralized social media platforms lie about what they essentially are. Twitter's motto is "what’s happening", and their <a href="https://about.twitter.com/en">about page</a> features a tweet encouraging others to "Speak the truth, even if your voice shakes." And yet over the last several years they have censored real news, promoted propaganda, and shadow banned those whose "voice shakes". Musk's desperate claims that "we'll stop, I promise" don't negate the fact that Twitter retains control over users' speech in a way that is inherently in conflict with their stated mission.</p>
<p>This is true even of non-political speech, because it is in Twitter's interest to promote content that drives engagement, because engagement is what in turn drives advertising profits. This undermines their claim of user enfranchisement - they exercise partiality in choosing whose voice gets a megaphone.</p>
<p>Users of Nostr know the feeling of this weight being lifted. Nostr is anything but polished, but that's part of the charm - you know there is no one scanning your content, deciding who sees what and with what "added context". Many users including myself have experienced a 10x or more increase in engagement, despite a much smaller number of people on the platform. This is of course likely due not only to the lack of an algorithm, but also to the lack of celebrities, which tend to absorb attention, leaving little for the rest of us. But for now, Nostr is for the plebs.</p>
<h1>Cutting the Gordian Knot</h1>
<p>And I hope, and have reason, that it will continue to be so. When I spoke to my pastor prior to moving to Austin to work on Coracle full-time, I asked him what problems related to social media he would like to see solved. He said that he would like to see a solution that puts users in control of their algorithm, and allows individuals to broadcast their content to as wide an audience as possible.</p>
<p>There is a contradiction here, and the claim that it can be solved is one of the main lies that centralized platforms like to tell. You are free to broadcast your data as widely as you want, but no one is obligated to read it. Twitter tries to square the circle by artificially reversing this trade-off, resulting in a system where "you can't broadcast your data unless we want to force people to read it." But even they can't give their users control while simultaneously taking it away.</p>
<p>There is a path forward though, and now we finally get to the point of this post. Nostr is so revolutionary because it puts "digital localism" within reach. I had better define my terms here, since "digital localism" is used to describe a lot of dystopian ideas I'm not very excited about. What I mean by the term is something like "social relevance". Contra the egalitarians, there are real differences that exist to set groups of people apart. Things like topical interest, physical geography, professional network, religious belief, and yes, ethnicity and sex.</p>
<h1>What is a community anyway</h1>
<p>The fact that digital "communties" exist is something that to their credit Mastodon recognized, and sought to accommodate. But they missed the fact that humanity is partitioned into a nearly infinite number of overlapping sub-groups based on a nearly infinite number of dimensions. Yes, maybe I should be friends with you because you also like cats, but let's refine this further, do you think cilantro tastes like soap, are you a member of the Church of Satan, are you Italian, have you been reading Hayak lately, do you like watching Hallmark movies, English, do you speak it? Partitioning people into groups based on a single dimension is an exercise in futility, and is the reason Mastodon instances are either ghost towns or home to millions of users.</p>
<p>By allowing users to download/host their own data and join as many and whichever relays they choose based on arbitrary criteria, people are now able to co-locate in digital space, and interact with each instance in a different way. This is why I'm not excited about tools that spray your data to as many relays as possible. This only serves to maintain the illusion that replicating all content across every instance can scale, and it can't.</p>
<p>Instead, relays should differentiate, both in terms of function and membership. In the future (and even now) there will be closed archival relays that scrape the network and provide a backup of user data for a fee; public-read, private-write relays that allow members to participate in an exclusive group with greater reach; private-read, private-write closed community relays; public "town square" relays, paid relays that provide indexes, full-text search, or content recommendations for the wider network (or a relevant subset of it); and relays that provide oracles for data external to nostr. The ability of users to pick and choose which relays to connect to (and to multiplex those connections through yet another proxy/aggregator relay) allows them to define their own low-granularity social graph, refining it further with follows, mutes, and other "algorithmic" tools.</p>
<p>The same is true of client implementations. Many people building social media platforms want to "fix Twitter". But that vision of digital society is amazingly narrow (luckily, Nostr developers don't seem to suffer from the same kind of myopia). <em>Most</em> people I know don't have Twitter accounts, or use them. For them, Twitter is about as relevant to their lives as CNN. Instead, they use private Facebook groups to arrange babysitters for their kids, or Cragislist to buy and sell local goods. They use Google maps to find reviews for nearby businesses, and the church email list to keep up with prayer requests. They subscribe to newsletters their friends publish, and spend their days at work sending memes over Slack. The common theme here is that all these platforms connect "us" with "mine", not with "them". And yes, journalism and topical interest ala Reddit is a part of this, but for normal people, a vanishingly small part. But let's stop squawking about "echo chambers".</p>
<p>And Nostr, <a href="https://blog.coracle.social/what-nostr-is-bad-at.html">despite its limitations</a>, can be applied to every use case enumerated above. In so doing, it will free regular people from the constraining force of opinionated, artificial, centralized communication platforms, and allow them to build a digital social network that complements real life.</p>
<h1>Conclusion</h1>
<p>The driving force, for me, is not to erase our differences and create an egalitarian utopia, or stick it to big tech, or to make money, but to see the people I love, who belong to me, and to whom I belong, flourish by being connected with the people who belong to them, and to whom they belong. The resulting network will be characterized by high trust and high cohesion, laying a solid foundation for content and ideas to efficiently propagate across the distributed social graph, similar to how the lightning network routes transactions. But the key to making this work is to rise to the occasion, and take back our digital sovereignty by making it as easy for the average person to navigate the digital social landscape as they do in real life.</p>
]]></itunes:summary>
      <itunes:image href="https://coracle.us-southeast-1.linodeobjects.com/juniperphoton-_lwLalY6Yzg-unsplash.jpeg"/>
      </item>
      
      </channel>
      </rss>
    