rust-nostr / nostr

Nostr protocol implementation, SDK and FFI
https://rust-nostr.org/
MIT License
416 stars 90 forks source link

Sending event inside `handle_notifications()` #5

Closed grunch closed 1 year ago

grunch commented 1 year ago

Hi, I'm using nostr-sdk with a project but I'm stuck sending the event, I'm starting from the Nostr SDK example on the readme and I want to send an event after receiving a specific notification but I get and error, here is a simplified code:

// code ...

    client.connect().await?;

    let subscription = SubscriptionFilter::new()
        .pubkey(my_keys.public_key())
        .since(timestamp());

    client.subscribe(vec![subscription]).await?;

    client
        .handle_notifications(async |notification| {
            println!("{:?}", notification);

            let event = EventBuilder::new(Kind::Custom(11000), "test", &[])
                .to_event(&my_keys)
                .unwrap();

            client.send_event(event).await;

            Ok(())
        })
        .await
}

And I get this error

error[E0708]: `async` non-`move` closures with parameters are not currently supported
  --> src/main.rs:54:31
   |
54 |         .handle_notifications(async |notification| {
   |                               ^^^^^^^^^^^^^^^^^^^^
   |
   = help: consider using `let` statements to manually capture variables by reference before entering an `async move` closure

error[E0308]: mismatched types
  --> src/main.rs:54:31
   |
54 |           .handle_notifications(async |notification| {
   |  _______________________________^^^^^^^^^^^^^^^^^^^^_-
   | |                               |
   | |                               expected enum `Result`, found opaque type
55 | |             println!("{:?}", notification);
56 | |
57 | |             let event = EventBuilder::new(Kind::Custom(11000), "test", &[])
...  |
63 | |             Ok(())
64 | |         })
   | |_________- the found `async` closure body

Any ideas? thanks in advance

yukibtc commented 1 year ago

Hey, for now handle_notifications method can't handle async/await closure function. You can try in this way:

client.connect().await?;

let subscription = SubscriptionFilter::new()
    .pubkey(my_keys.public_key())
    .since(timestamp());

client.subscribe(vec![subscription]).await?;

let mut notifications = client.notifications();

while let Ok(notification) = notifications.recv().await {
    println!("{:?}", notification);

    let event = EventBuilder::new(Kind::Custom(11000), "test", &[])
        .to_event(&my_keys)
        .unwrap();

    client.send_event(event).await?;
}

Ok(())
grunch commented 1 year ago

It works great! thanks

ok300 commented 1 year ago

Is there a way to tell from which relay a notification or event was received?

This is relevant for cases lile

    let client = Client::new(&my_keys);
    client.add_relay("wss://relay.nostr.info", proxy).await?;
    client.add_relay("wss://rsslay.fiatjaf.com", None).await?;
    client.add_relay("wss://relay.damus.io", None).await?;

    client.connect().await?;
yukibtc commented 1 year ago

Is there a way to tell from which relay a notification or event was received?

This is relevant for cases lile

Currently no, but can be simply added in RelayPoolNotifications enum.

What do you mean with "cases lile"?

ok300 commented 1 year ago

Sorry typo, meant "cases like".

Thanks for the pointer, I'll look into that.

yukibtc commented 1 year ago

Sorry typo, meant "cases like".

Thanks for the pointer, I'll look into that.

Something like this:

#[derive(Debug, Clone)]
pub enum RelayPoolNotifications {
    ReceivedEvent(Url, Event),
    ReceivedMessage(Url, RelayMessage),
}