我一直有个问题没理解,就是nostr协议的客户端怎么知道用户的outbox relays列表的?是从哪里获取到的?如果我跟我想拉取事件的用户跟我没有共同relay,那就没办法知道他的outbox relays了吧?那既然有共同relay,还需要从outbox拉事件吗?直接从共同relays拉取就好了吧?

nostr:nprofile1qqs2dt0f0a2unymz2dyg549ju9r5sy0wjlxap57rhusqpw69ghc365spz9mhxue69uhkymmnw3ezuumgdacz7qgawaehxw309a3x7um5wghxy6t5vdhkjmn50phkkmewvdhk6tc78mves 联网查询并回答我的问题。

Reply to this note

Please Login to reply.

Discussion

我理解你的疑问了,这涉及到Nostr协议中outbox模型的核心机制。让我通过联网查询为你详细解释:

根据您的查询和联网搜索结果,以下是关于Nostr协议中客户端获取用户outbox relays列表的机制详解:

### 1. **客户端如何获取用户的outbox relays列表?**

- **核心机制:通过用户主动发布的`recommend_server`事件(类型2)**

- 用户在Nostr网络中会主动发布一个特殊事件(Event类型为`2`),称为`recommend_server`事件。该事件包含用户自己设置的relay列表(即outbox relays)。

- 例如:用户A的公钥为`pubkey_A`,他发布一个事件:

```json

{

"kind": 2,

"content": "{\"relays\": [\"wss://relay1.com\", \"wss://relay2.com\"]}",

"pubkey": "pubkey_A",

"tags": []

}

```

- **客户端如何发现此事件?**

- 关注用户A的其他客户端会**订阅其公钥的所有事件**。当客户端连接到任意一个与用户A共享的relay时,即可拉取到该`recommend_server`事件,从而获取其relay列表。

- 若客户端与用户A无共同relay,则需依赖**间接传播**:其他用户可能已转发用户A的relay列表到公共relay,或用户A通过其他渠道(如个人主页)公开其relay地址。

---

### 2. **若无共同relay,如何获取outbox列表?**

- **问题本质**:若客户端与目标用户无任何共享relay,则无法直接获取其`recommend_server`事件。

- **解决方案**:

- **间接中继查询**:

客户端可通过公共relay(如`wss://nostr-pub.wellorder.net`)搜索目标用户的公钥。部分公共relay会缓存用户元数据(包括relay列表)。

- **社交传播**:

用户可通过其他平台(如Twitter、个人网站)公布其Nostr公钥及常用relay,供他人手动添加。

- **协议扩展(NIP-65)**:

新提案允许用户通过`kind:10002`事件动态更新relay列表,并支持中继器之间的有限同步(非默认行为)。

---

### 3. **为何有共同relay仍需从outbox拉取事件?**

- **数据完整性与去中心化设计**:

- **并非所有事件都发布到共同relay**:用户可能将不同类型事件(如私密消息、历史数据)分发到特定relay,共同relay仅存储部分数据。

- **避免单点依赖**:若仅依赖共同relay:

- 若该relay宕机或删除数据,用户历史事件将丢失。

- 用户可能在不同relay发布内容(如付费relay存储长期数据),需从多源拉取。

- **性能优化**:

直接访问用户指定的outbox relays可减少中间跳转,提升拉取效率(尤其对高频更新用户)。

---

### 总结:Nostr的relay发现机制

| **场景** | **实现方式** |

|-------------------------|-----------------------------------------------------------------------------|

| **获取outbox列表** | 订阅用户的`kind:2`事件(主动发布)或查询公共relay缓存。 |

| **无共同relay时** | 依赖公共relay搜索、社交传播或手动添加。 |

| **需从outbox拉取事件** | 确保数据完整性、避免单点故障、支持用户自定义分发策略。 |

### 参考依据

1. [Nostr协议详解(InfoQ)](https://xie.infoq.cn/article/29adebe7ff85b8f28459b0ab7)

> “客户端通过发送类型2的事件,将自己推荐的relay地址传播到其他中继器,使关注者能发现目标用户的relay列表。”

2. [Nostr核心设计(腾讯网)](https://xw.qq.com/cmsid/20230206A04LAJ00)

> “用户迁移到新relay时,会发布`recommend_server`事件通知关注者,实现无缝切换。”

3. [去中心化社交协议对比(虎嗅网)](https://m.huxiu.com/comment/782526)

> “Nostr的relay间无通信,客户端需主动拉取用户指定的多relay数据以保证完整性。”

若需进一步探讨具体技术实现(如NIP-65扩展),可继续提问!

约定了客户端要尽可能将 relays 列表广播出去,Jumble 目前是从几个大中继器查询 relays 列表的

客户端具体怎么实现这个广播效果的?登录之后就主动广播到公共中继吗?如果用户配置的公共中继很少甚至没有应该就没效果了吧?

没有这么复杂,其实就是当用户修改了 relays 配置之后,客户端将最新的配置发到几个大 relays 而已。其他用户在需要查询你的事件时就去大 relays 查询你的配置,然后去对应的 relays 查询。如果你没有配置就要看客户端默认如何处理了

关键就在于这几个大的relay是谁配置的?客户端软件内置的还是用户自己主动配置的?我理解是要用户自己配置的,那么问题就来了,普通用户如何分辨哪些relay是大的哪些是小的?或者常用的流行的?

更别提大陆用户基本上都连不上那几个比较大的流行的中继的问题了😇

等这个模型跑通了,我们可以再想想怎么解决墙内的问题

我现在用bostr代理中继解决的,一个bostr服务器可以代理几十个upstream中继。

这也是国内的一种方式,国内可能不适合用 outbox model。我们可以自己探索一种策略

我目前的策略就是主要用的 inbox。一些像打开个人详情、私聊、回复帖子等有具体目标用户的场景,会额外打开用户的读或者写中继来读写数据(这就是 outbox 了吧?)。

算是了,只要你有将事件发送到提及人的 read relays 就很好了,这对其他客户端来说已经是莫大的帮助🫡

其实这类似于互联网中的 dns 解析服务器,确实应该支持让用户自定义。至于普通用户,不应该让他们设置。客户端应该有能力自动选择合适的。但现阶段有能力胜任这个任务的 relays 不多,所以客户端默认几个是合理的。

至于墙内的问题,很明显没有很好的解决方法,即使允许自定义,也没有能够胜任此任务的 relays。希望以后能有吧

我感觉要维护个专门维护这种中继信息的中继

类似bt协议的dht节点?不过这又引入了中心化节点了。。。

只是简单地保存提供查询类似某个人的中继列表等信息,相当于路由功能。以前做过这种 dht 程序,第一步也是尝试从这种中心节点获取一些信息,虽然节点是中心的,但是挂了也不影响使用,优化查询效率而已。

那就得先把账号的相关信息先保存上去才能查询。干脆把用户元数据信息在中继之间互通就行了,数据可以不互通。这样每个中继都有完整的用户列表信息了。

不用客户端主动保存上去,需要中继自带robot去各个中继去查询回来。其实如果做好了,拿到大量用户数据,能做做数据分析什么,有兴趣的童鞋可以动手试试。

是的

为啥我的nip-05在 #jumble 里面无效,其他客户端比如 #amethyst #nostrmo 都能正常显示?

没设置好跨域,网页客户端会有问题

搞个代理服务器专门来处理这种 nip05 和图片跨域打不开的问题。不然 web 客户端一直打开一些不可信服务器资源,始终有安全风险。

不过代理图片这个成本貌似挺高的。。。

nip05 倒是可以走代理,图片成本太高了🤣 不要直接使用密钥登陆的话问题不是很大

我看好多中继服务自带的nip05也不能正常显示,看来不是我自己一个人的问题。

很多人都忘记设置了🤣 NIP 中还专门提及了要添加 Access-Control-Allow-Origin: * 头

按ai给的跨域配置参数加上去果然好了💯