Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write Rust Nostr book #173

Open
yukibtc opened this issue Sep 29, 2023 · 13 comments
Open

Write Rust Nostr book #173

yukibtc opened this issue Sep 29, 2023 · 13 comments

Comments

@yukibtc
Copy link
Member

yukibtc commented Sep 29, 2023

.

@rodant
Copy link
Contributor

rodant commented Aug 15, 2024

I'm missing a guide of how to receive nip-17 private direct messages. My code works fine with nip-04 encrypted messages and now I tried to migrate it to nip-17. On the sender side I'm sending with client.send_private_msg(pubkey, &message, None).

The code on the receiver side looks like this:

let my_pubkey = NostrPubkey::from_bech32(&self.nostr_client.get_npub()?)?;
        let filter_note = Filter::new()
            .kind(Kind::GiftWrap)
            .pubkey(my_pubkey)
            .since(Timestamp::now());

        self.nostr_client
            .client
            .subscribe(vec![filter_note], None)
            .await?;
        let mut notifications = self.nostr_client.client.notifications();

        while let Ok(notification) = notifications.recv().await {
            if let RelayPoolNotification::Event { event, .. } = notification {
                if let Ok(unwrapped_gift) = self.nostr_client.client.unwrap_gift_wrap(&event).await
                {
                    dbg!("Received event: {:?}", &unwrapped_gift);
                    if let Ok((contract_hash, contract)) =
                        self.parse_contract(&unwrapped_gift.rumor.content).await
                    {
                    ...
                    }

The problem is I don't get any events. I changed the kind to PrivateDirectMessage, but it doesn't work either, tough I think GiftWrap should be the right kind to receive. If I get the code working I would also contribute with a code example or a section in the book.

@yukibtc
Copy link
Member Author

yukibtc commented Aug 15, 2024

I'm missing a guide of how to receive nip-17 private direct messages. My code works fine with nip-04 encrypted messages and now I tried to migrate it to nip-17. On the sender side I'm sending with client.send_private_msg(pubkey, &message, None).

The code on the receiver side looks like this:

let my_pubkey = NostrPubkey::from_bech32(&self.nostr_client.get_npub()?)?;
        let filter_note = Filter::new()
            .kind(Kind::GiftWrap)
            .pubkey(my_pubkey)
            .since(Timestamp::now());

        self.nostr_client
            .client
            .subscribe(vec![filter_note], None)
            .await?;
        let mut notifications = self.nostr_client.client.notifications();

        while let Ok(notification) = notifications.recv().await {
            if let RelayPoolNotification::Event { event, .. } = notification {
                if let Ok(unwrapped_gift) = self.nostr_client.client.unwrap_gift_wrap(&event).await
                {
                    dbg!("Received event: {:?}", &unwrapped_gift);
                    if let Ok((contract_hash, contract)) =
                        self.parse_contract(&unwrapped_gift.rumor.content).await
                    {
                    ...
                    }

The problem is I don't get any events. I changed the kind to PrivateDirectMessage, but it doesn't work either, tough I think GiftWrap should be the right kind to receive. If I get the code working I would also contribute with a code example or a section in the book.

Use .limit(0) instead of .since(Timestamp::now()). The gift wraps have a tweaked timestamp (in the past).

It's available as example in the bot.rs file (nostr-sdk crate). But probably I should add a nip17.rs example too.

@rodant
Copy link
Contributor

rodant commented Aug 15, 2024

Ah, this makes sense and it works now. Thanks for your quick help.

@ethicnology
Copy link
Contributor

Hey there, I would like to try NIP17, I didn't know it was supported.
It would be great if we could have a documentation on how to receive_private_msg, send_private_msg is pretty clear.

Thank you for your work

@rodant
Copy link
Contributor

rodant commented Oct 23, 2024

Hey there, I would like to try NIP17, I didn't know it was supported. It would be great if we could have a documentation on how to receive_private_msg, send_private_msg is pretty clear.

Thank you for your work

Hey, I would contribute a Rust example. Though, it'll be as early as next week, I'm now having some vacations.

@yukibtc
Copy link
Member Author

yukibtc commented Oct 23, 2024

Hey there, I would like to try NIP17, I didn't know it was supported.
It would be great if we could have a documentation on how to receive_private_msg, send_private_msg is pretty clear.

Check the bot example in nostr-sdk crate: https://github.com/rust-nostr/nostr/blob/master/crates%2Fnostr-sdk%2Fexamples%2Fbot.rs

Is not available a receive_private_msg method. You have to subscribe to gift wrap filter and handle events with handle_notifications loop.
When you receive a gift wrap event, you can use the Client::unwrap_gift_wrap method to extract the rumor and the sender (the client must have a signer to do this).

@rodant
Copy link
Contributor

rodant commented Oct 31, 2024

Hey there, I would like to try NIP17, I didn't know it was supported. It would be great if we could have a documentation on how to receive_private_msg, send_private_msg is pretty clear.

Thank you for your work

Hi, I just submitted a PR adding example code for NIP-17 to the book. You can take a look at the code in the PR as long as it is pending.

@ev3rst
Copy link

ev3rst commented Feb 25, 2025

Hello,

Is there any plan to update the book?
Most of the python code examples are no longer compatible with .39 version

Thanks

@yukibtc
Copy link
Member Author

yukibtc commented Feb 25, 2025

Hello,

Is there any plan to update the book? Most of the python code examples are no longer compatible with .39 version

Thanks

Hi, do you mean the examples in this folder?
Those examples aren't checked over releases and the plan is to move them to the book. Instead, the examples in the book are all up-to-date to the last version and are continuously checked so they should work. If you've found an example in the book that doesn't work let me know what it is, so I'll check it.

@ev3rst
Copy link

ev3rst commented Feb 25, 2025

yes, some examples in that folder are no longer working like bot.py - which is sending TypeError: Expected Filter instance, list found when calling 'await client.subscribe([nip59_filter], None)' on line 24.

But I was talking also about these:

the plan is to move them to the book.

where is that 'book'?

@ev3rst
Copy link

ev3rst commented Feb 25, 2025

Hello again,

I have written a few updated code sample compatible with 0.39
naddr1qvzqqqr4xspzpka3ntswp659x2yu2nru4qg8s2mpxpkgfr9d3kzpv969jlplyt26qq2hs7z20f05skz5898nx5me94t9zwt989s5sjwh4tm
https://github.com/ev3rst/nostr_sdk_examples

can't figure out How to follow a given npub via nostr_sdk?
is there an example of this implemented somewhere?

@yukibtc
Copy link
Member Author

yukibtc commented Feb 27, 2025

yes, some examples in that folder are no longer working like bot.py - which is sending TypeError: Expected Filter instance, list found when calling 'await client.subscribe([nip59_filter], None)' on line 24.

But I was talking also about these:

* https://rust-nostr.org/sdk/nips/index.html

Ah, I see, some example doesn't work. I'm using pyright to check if they are written correctly, but seems that is some case it allows to use wrong types, like:

keys = Keys.generate()
client = Client(keys) # Wrong but for some reason doesn't return error with pyright, only on script execution

signer = NostrSigner.keys(keys)
client = Client(signer) # Correct

I've manually tested all the examples and fixed at commit 0227d10

where is that 'book'?

The one you linked: https://rust-nostr.org
All the book examples can be found here: https://github.com/rust-nostr/nostr/tree/0227d10b639133f71db8454320f91d8a41323c1e/book/snippets
For python: https://github.com/rust-nostr/nostr/tree/0227d10b639133f71db8454320f91d8a41323c1e/book/snippets/python/src


Hello again,

I have written a few updated code sample compatible with 0.39
naddr1qvzqqqr4xspzpka3ntswp659x2yu2nru4qg8s2mpxpkgfr9d3kzpv969jlplyt26qq2hs7z20f05skz5898nx5me94t9zwt989s5sjwh4tm
https://github.com/ev3rst/nostr_sdk_examples

can't figure out How to follow a given npub via nostr_sdk?
is there an example of this implemented somewhere?

Nice! Could be something like this:

async def main():
    keys = Keys.parse("nsec...")

    client = Client()
    await client.add_relay("wss://..")
    await client.connect()
    
    # Get current contact list
    f = Filter().author(keys.public_key()).kind(Kind.from_std(KindStandard.CONTACT_LIST))
    events = await client.fetch_events(f, timedelta(seconds=10))
    event = events.first()
    
    if event is not None:
        # Get current contact public keys
        public_keys: list[PublicKey] = event.tags().public_keys()
        
        # Add new contact
        new_public_key = PublicKey.parse("npub...")
        public_keys.append(new_public_key)
        
        # Convert public keys to contacts and create a new contact list event
        contacts: list[Contact] = [Contact(public_key=public_key, relay_url=None, alias=None) for public_key in public_keys]
        builder = EventBuilder.contact_list(contacts)
        event = builder.sign_with_keys(keys)
        
        # Send event to relays
        await client.send_event(event)
    else:
        print("No contact list found")

@ev3rst
Copy link

ev3rst commented Feb 27, 2025

Thanks very much it works fantastically!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants