nostr-dev-kit / ndk

Nostr Development Kit with outbox-model support
MIT License
360 stars 97 forks source link

event.publish(), timeout error for every relay in the NDKRelaySet #219

Closed Sebastix closed 5 months ago

Sebastix commented 5 months ago

In multiple clients I'm using NDK and the code for publising events have stopped working. So I started debugging but I'm still stuck on why it stopped working.

error publishing to relay wss://khatru.nostrver.se Error: Timeout
    at @nostr-dev-kit_ndk.js?v=e943c541:17126:31

I've created a simple example page in Nuxstr to reproduce the problem: https://nuxstr.nostrver.se/publish-event I'm using Brave with the nos2x browser extension for the signing.

The code in the repo of this page: https://github.com/Sebastix/nuxstr/blob/master/pages/publish-event.vue#L9

Full snippet:

<script setup>
  import { useNdkStore } from '~/stores/Ndk'
  import { useUserStore } from "~/stores/User";
  import {NDKEvent, NDKRelaySet, NDKRelay, NDKNip07Signer, PublishError} from "@nostr-dev-kit/ndk";

  const NdkStore = useNdkStore()
  const UserStore = useUserStore()
  const nip07signer = new NDKNip07Signer()
  const publishEvent = async () => {
    try {
      // Create event.
      const event = new NDKEvent(NdkStore.ndk)
      event.kind = 13811
      event.content = 'This is just a test from Nuxstr publishing a short text note (kind 13811)...'
      // Publish event to given relaySet
      const relays = new NDKRelaySet(
        new Set([
          new NDKRelay('wss://khatru.nostrver.se'), // this relay is only accepting event kinds 13811 and 37515
          new NDKRelay('wss://nostr.sebastix.dev')
        ]),
        NdkStore.ndk
      )
      await event.publish(relays, 10000)
    } catch (e) {
      console.log(e)
      if (e instanceof PublishError) {
        for (const [relay, err] of e.errors) {
          console.error(`error publishing to relay ${relay.url}`, err);
        }
      }
    }
  }

  onMounted(async () => {
    try {
      if (!UserStore.signedIn) {
        await NdkStore.initNdk()
        NdkStore.ndk.signer = nip07signer
        await NdkStore.ndk.connect()
        const user = await nip07signer.user()
        UserStore.login(user, NdkStore.ndk)
        NdkStore.ndk.pool?.on("relay:connecting", (relay) => {
          console.log("🪄 MAIN POOL Connecting to relay", relay.url);
        });
        NdkStore.ndk.pool?.on("relay:connect", (relay) => {
          console.log("✅ MAIN POOL Connected to relay", relay.url);
        });
      }
    } catch (e) {
      console.log(e)
    }
  })

</script>

<template>
  <div>
    <button @click="publishEvent" class="p-2 bg-purple-100 text-purple-500">Publish event</button>
  </div>
</template>

<style lang="scss">

</style>
Sebastix commented 5 months ago

Just simply using event.publish() without a NDKRelaySet seems to work though...

See https://njump.me/nevent1qvzqqqqqqypzqpnrnguxe8qszsshvgkvhn6qjzxy7xsvx03rlrtddr62haj4lrm3qy88wumn8ghj7mn0wvhxcmmv9uq3camnwvaz7tmwdaehgu3wwdjkyctnw35hstnnda3kjctv9uqzp8sl77qy65kqqwluefu8qe3sx8raduhwlhczptdfhwgjvs67pqagf40wxg

erskingardner commented 5 months ago

Ok – I created a simple svelte version of this to test. A few things I'm noticing.

  1. You're code is failing websocket connections a lot. I'm not sure what's the cause there but I just keep seeing error messages like this: CleanShot 2024-05-14 at 10 13 52
  2. I think that many relays are rejecting the kind: 13811 events because they aren't valid replaceable events (they're missing tags). I've tried to publish those and get errors but when I change them to kind:1 it works just fine. This seems to depend on the relay (which makes sense as many would probably have slightly different validation checks).

When I connect, and the relays haven't disconnected, publishing of valid kind 1 events works just fine to all relays. I'm going to close this for now but feel free to reopen if you have more info @Sebastix

Sebastix commented 5 months ago

@erskingardner Sure that those relays are live? Afaik wss://relayer.fiatjaf.com is not live for example. If you're using Alby, please note this: https://github.com/getAlby/lightning-browser-extension/pull/3142

In my provided example I'm trying to publish an event to a set of relays (2 relays). When I publish an event kind 13811 with nak, the relay accepts it (without any provided tags).

./nak event -k 13811 --sec 472...7a8b -c 'hello this is new place checkin 9999' --auth wss://khatru.nostrver.se
connecting to wss://khatru.nostrver.se... ok.
{"id":"b62382edd07a6d151a3a037accef8af764fa6d8c1efecf497abda79676f266fe","pubkey":"efbb28950ec699e1f988dc8dba00e70cb89d18d7d9e931036a4c36ea4de77586","created_at":1715677576,"kind":13811,"tags":[],"content":"hello this is new place checkin 9999","sig":"3286064fa1b7e40db03bcb7c60add6b10172d9edb0a653773370fde83341f51927fe1bcb90d449fdd93d7bddadab0be17c57ca95e2c3c19c004842c52116752e"}
publishing to wss://khatru.nostrver.se... success.
erskingardner commented 5 months ago

I don't know. Sorry, I don't have more time to today to look into it. From what I could see, NDK was working just fine publishing to explicit relays whether they were passed via the NDK instantiation or in the publish call.

Sebastix commented 5 months ago

@erskingardner np, I will dig into it later today ;) thx for the feedback so far!

Sebastix commented 5 months ago

@erskingardner I think I found a bug for replaceable events here: https://github.com/nostr-dev-kit/ndk/blob/master/ndk/src/events/index.ts#L191 as the signature is always invalid for the event being published. There is a difference in the created_at value of the event signed by the remote signer and the value being transmitted to the relay.

Sebastix commented 5 months ago

Ah, @pablof7z changed / fixed it yesterday!

now it needs a release ;)

Sebastix commented 5 months ago

With version 2.8.2 released earlier today by @pablof7z the NDKEvent.publish() is working again for replaceable events. NDKEvent.publish(NDKRelaySet) is still giving me a timeout for each specified relay in that set.

I would like to reopen the issue, but it seems I don't have the permission to do @erskingardner