nostr-rs-relay icon indicating copy to clipboard operation
nostr-rs-relay copied to clipboard

Nip47

Open spirrello opened this issue 9 months ago • 8 comments

Hi,

Do you have plans to support Nip47?

spirrello avatar May 08 '24 13:05 spirrello

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?

thesimplekid avatar May 08 '24 13:05 thesimplekid

@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.

spirrello avatar May 09 '24 18:05 spirrello

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?

thesimplekid avatar May 10 '24 10:05 thesimplekid

@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 avatar May 10 '24 14:05 spirrello

@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

spirrello avatar May 13 '24 12:05 spirrello

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

thesimplekid avatar May 13 '24 13:05 thesimplekid

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) }]

spirrello avatar May 13 '24 13:05 spirrello

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

thesimplekid avatar May 13 '24 13:05 thesimplekid