scsibug / nostr-rs-relay

Mirror of https://sr.ht/~gheartsfield/nostr-rs-relay/
MIT License
593 stars 161 forks source link

Nip47 #195

Open spirrello opened 6 months ago

spirrello commented 6 months ago

Hi,

Do you have plans to support Nip47?

thesimplekid commented 6 months ago

What is needed from the relay to support this? I don't think the relay needs to implement anything specific for it its done on the client side?

spirrello commented 6 months ago

@thesimplekid Not entirely sure. I'll do some testing. Is there a way to enable logging? When I send events to the relay I don't see any logs.

thesimplekid commented 6 months ago

Its been awhile since I've looked at it but if i remember correctly its a bit tricky to debug because they're ephemeral events they don't get stored to the DB only broadcasted to any clients listening so you can't check the DB for them, I put in a couple extra logging lines temporarily when i was doing it.

Whats the issue you're having that leads you to question if its supported?

spirrello commented 6 months ago

@thesimplekid was just curious if it was supported. I was running it locally and was trying to get a small client to use nip 47 against the relay.

Here's a snippet of the code I was using which in itself could be incorrect.

async fn nip_47_request() -> Result<()> {
    let nwc_uri = std::env::var("NWC_URI").expect("NWC_URI not set");
    let nwc_uri = NostrWalletConnectURI::from_str(&nwc_uri).unwrap();
    info!("\n{nwc_uri}\n");

    let secret = nwc_uri.secret.clone();
    let signer: Keys = Keys::new(secret);
    let client = Client::new(signer);
    client.add_relay(nwc_uri.relay_url.clone()).await?;
    client.connect().await;
    println!("Connected to relay {}", nwc_uri.relay_url.clone());

    let req = nip47::Request::get_info().clone();
    let req_event = req.to_event(&nwc_uri).unwrap();

    loop {
        match client.send_event(req_event.clone()).await {
            Ok(event_id) => {
                info!("event_id: {}", event_id);
                sleep(Duration::from_secs(30)).await;
            }
            Err(err) => {
                sleep(Duration::from_secs(300)).await;
                error!("error: {}", err);
            }
        }
    }
}
spirrello commented 6 months ago

@thesimplekid If I send a nip1 I can see the following logs from the relay.

2024-05-13T12:16:28.272859Z DEBUG hyper::proto::h1::conn: read eof
2024-05-13T12:16:28.291494Z  INFO nostr_rs_relay::db: persisted event: "c1b55f66" (kind: 0) from: "690ff589" in: 16.228867ms (IP: "127.0.0.1")
2024-05-13T12:16:28.293459Z  INFO nostr_rs_relay::db: persisted event: "b02ef96f" (kind: 1) from: "690ff589" in: 403.301µs (IP: "127.0.0.1")
2024-05-13T12:16:32.148933Z  INFO nostr_rs_relay::db: persisted event: "00000a37" (kind: 1) from: "690ff589" in: 1.524981ms (IP: "127.0.0.1")

But if I send nip47 messages using the function I shared earlier I don't see anything really indicative that it supports nip47.

2024-05-13T12:18:00.583571Z DEBUG hyper::proto::h1::io: parsed 2 headers
2024-05-13T12:18:00.583622Z DEBUG hyper::proto::h1::conn: incoming body is empty
2024-05-13T12:18:00.583582Z DEBUG hyper::proto::h1::io: parsed 5 headers
2024-05-13T12:18:00.583660Z DEBUG hyper::proto::h1::conn: incoming body is empty
2024-05-13T12:18:00.586456Z DEBUG hyper::proto::h1::io: flushed 166 bytes
2024-05-13T12:18:00.586860Z DEBUG hyper::proto::h1::io: flushed 586 bytes
2024-05-13T12:18:00.588220Z DEBUG hyper::proto::h1::conn: read eof
2024-05-13T12:18:00.590411Z  INFO nostr_rs_relay::server: new client connection (cid: 7b18c285, ip: "127.0.0.1")
2024-05-13T12:18:00.590440Z  INFO nostr_rs_relay::server: cid: 7b18c285, origin: "<unspecified>", user-agent: "<unspecified>"
2024-05-13T12:18:01.224836Z  INFO nostr_rs_relay::server: stopping client connection (cid: 7b18c285, ip: "127.0.0.1", sent: 1 events, recv: 0 events, connected: 635.056249ms)
2024-05-13T12:18:02.005106Z DEBUG hyper::proto::h1::io: parsed 5 headers
2024-05-13T12:18:02.005131Z DEBUG hyper::proto::h1::conn: incoming body is empty
2024-05-13T12:18:02.005245Z DEBUG hyper::proto::h1::io: flushed 166 bytes
2024-05-13T12:18:02.005360Z  INFO nostr_rs_relay::server: new client connection (cid: 0b42195f, ip: "127.0.0.1")
2024-05-13T12:18:02.005372Z  INFO nostr_rs_relay::server: cid: 0b42195f, origin: "<unspecified>", user-agent: "<unspecified>"
2024-05-13T12:18:02.007357Z DEBUG hyper::proto::h1::io: parsed 2 headers
2024-05-13T12:18:02.007376Z DEBUG hyper::proto::h1::conn: incoming body is empty
2024-05-13T12:18:02.007560Z DEBUG hyper::proto::h1::io: flushed 586 bytes
2024-05-13T12:18:02.008755Z DEBUG hyper::proto::h1::conn: read eof
thesimplekid commented 6 months ago

NIP47 uses ephemeral events so they are not persisted to the db so you shouldn't expect to the the persisted event log message.

2024-05-13T12:18:01.224836Z  INFO nostr_rs_relay::server: stopping client connection (cid: 7b18c285, ip: "127.0.0.1", sent: 1 events, recv: 0 events, connected: 635.056249ms)

But it looks like the relay is receive is getting the event. Do you have any clients subscribed to listen for the event?

I don't see anything really indicative that it supports nip47

There is no specific support the relay needs to provide for NIP47 other then ephemeral event passing

spirrello commented 6 months ago

Here's a snippet I'm using to listen for events but I don't see any events.

 let mut filters_vec = Vec::new();
    let subscription = Filter::new()
        .kind(Kind::WalletConnectRequest)
        .since(Timestamp::now());
    filters_vec.push(subscription);

    client.subscribe(filters_vec.clone(), None).await;

    loop {
        let events = client
            .get_events_of(filters_vec.clone(), Some(Duration::from_secs(5)))
            .await?;

        info!("events: {:?}", events);
        sleep(Duration::from_secs(5)).await;
    }

Perhaps my subscription filter isn't working for nip 47. If I use Kind::TextNote instead the listener sees events just fine:

events: [Event { id: EventId(0xc5bc7fd34a50c25ee0c5842d7e6edde8166a6f85db02865c23fec0a8d94bf063), pubkey: PublicKey { inner: XOnlyPublicKey(68966f0d6709bfb0967b9aa29106f18b614c24abfb0e2872b071b20a5394e76b16f1118f92b0c9b91891b69dd60acd8c517fd3dc90958736c232ed732dc33c4f) }, created_at: Timestamp(1715607200), kind: TextNote, tags: [], content: "yolo from rust-nostr!", sig: Signature(d1f0fd1a600530b7e0e7bf5776fa341938220f29bba67d278059d179a36b697a2cedf239b319ec3473d0394759f679950b1bce8dcbd23f5cf03c499077340035) }]
thesimplekid commented 6 months ago

I think the issue is with your listening code not the relay.

You subscribe here

client.subscribe(filters_vec.clone(), None).await;

But you're not actually listening for that subscription. You are then later calling get_events but that won't work for ephemeral events as they are only sent to the active subscriptions.

You need to handle notifications on the active subscription. Here is a good example you should be able to modify for NWC events. https://github.com/rust-nostr/nostr/blob/master/crates/nostr-sdk/examples/subscriptions.rs

kumulynja commented 1 day ago

@thesimplekid Even when not persisting the nip47 events, would it be possible to send an OK relay message?

Because now the sender of a nip47 event doesn't know if the relay accepted it and passed it to the active subscriptions or not. And following nip01, the relay should indicate the acceptance or denial of all events with an OK message.

I created a separate issue for this since it seems to be a general problem: https://github.com/scsibug/nostr-rs-relay/issues/220