scsibug / nostr-rs-relay

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

Nip47 #195

Open spirrello opened 5 months ago

spirrello commented 5 months ago

Hi,

Do you have plans to support Nip47?

thesimplekid commented 5 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 5 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 5 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 5 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 5 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 5 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 5 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 5 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