Avatar
Yuki Kishimoto
68d81165918100b7da43fc28f7d1fc12554466e1115886b9e7bb326f65ec4272
GitHub: https://github.com/yukibtc PGP: 86F3 105A DFA8 AB58 7268 DCD7 8D3D CD04 2496 19D1
Replying to Avatar Vampiro Doidão

nostr:nprofile1qqsx3kq3vkgczq9hmfplc28h687py42yvms3zkyxh8nmkvn0vhkyyuspz4mhxue69uhkummnw3ezummcw3ezuer9wchsz9thwden5te0wfjkccte9ejxzmt4wvhxjme0qy88wumn8ghj7mn0wvhxcmmv9u0uehfp, I think some imports are missing in the examples, but even after fixing that, it still throws errors. Can you help me?

// Copyright (c) 2022-2023 Yuki Kishimoto

// Copyright (c) 2023-2024 Rust Nostr Developers

// Distributed under the MIT software license

use nostr_sdk::prelude::*;

use tracing_subscriber;

use rand;

#[tokio::main]

async fn main() -> Result<()> {

tracing_subscriber::fmt::init();

let keys = Keys::parse("nsec12kcgs78l06p30jz7z7h3n2x2cy99nw2z6zspjdp7qc206887mwvs95lnkx")?;

let client = Client::builder()

.signer(keys.clone())

.opts(Options::new().gossip(true))

.build();

println!("Bot public key: {}", keys.public_key().to_bech32()?);

client.add_relay("wss://nostr.oxtr.dev").await?;

client.add_relay("wss://relay.damus.io").await?;

client.add_relay("wss://nostr.mom").await?;

client.add_relay("wss://nostr.wine").await?;

client.add_relay("wss://relay.nostr.info").await?;

client.add_relay("wss://auth.nostr1.com").await?;

client.connect().await;

let metadata = Metadata::new()

.name("rust-nostr-bot-example")

.display_name("rust-nostr bot example")

.website(Url::parse("https://github.com/rust-nostr/nostr")?);

client.set_metadata(&metadata).await?;

let subscription = Filter::new()

.pubkey(keys.public_key())

.kind(Kind::GiftWrap)

.limit(0); // Limit set to 0 to get only new events! Timestamp::now() CAN'T be used for gift wrap since the timestamps are tweaked!

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

client

.handle_notifications(|notification| async {

if let RelayPoolNotification::Event { event, .. } = notification {

if event.kind == Kind::GiftWrap {

match client.unwrap_gift_wrap(&event).await {

Ok(UnwrappedGift { rumor, sender }) => {

if rumor.kind == Kind::PrivateDirectMessage {

let content: String = match rumor.content.as_str() {

"/rand" => rand::random::().to_string(),

"/help" => help(),

_ => String::from(

"Invalid command, send /help to see all commands.",

),

};

// Send private message

client.send_private_msg(sender, content, []).await?;

}

}

Err(e) => tracing::error!("Impossible to decrypt direct message: {e}"),

}

}

}

Ok(false) // Set to true to exit from the loop

})

.await?;

Ok(())

}

fn help() -> String {

let mut output = String::new();

output.push_str("Commands:\n");

output.push_str("/rand - Random number\n");

output.push_str("/help - Help");

output

}

Error log:

user@Debian:~/sjnostr$ cargo run

Compiling sjnostr v0.1.0 (/home/user/sjnostr)

error[E0422]: cannot find struct, variant or union type `UnwrappedGift` in this scope

--> src/main.rs:48:28

|

48 | Ok(UnwrappedGift { rumor, sender }) => {

| ^^^^^^^^^^^^^ not found in this scope

error[E0599]: no method named `unwrap_gift_wrap` found for struct `nostr_sdk::Client` in the current scope

--> src/main.rs:47:34

|

47 | match client.unwrap_gift_wrap(&event).await {

| ^^^^^^^^^^^^^^^^ method not found in `Client`

error[E0599]: no method named `send_private_msg` found for struct `nostr_sdk::Client` in the current scope

--> src/main.rs:59:40

|

59 | ... client.send_private_msg(sender, content, []).await?;

| ^^^^^^^^^^^^^^^^ method not found in `Client`

Some errors have detailed explanations: E0422, E0599.

For more information about an error, try `rustc --explain E0422`.

error: could not compile `sjnostr` (bin "sjnostr") due to 3 previous errors

You have to enable `nip59` feature

Replying to Avatar JeffG

nostr:npub1drvpzev3syqt0kjrls50050uzf25gehpz9vgdw08hvex7e0vgfeq0eseet have you ever seen any behavior like this with LMDB? I don’t know if it would effect the rust Nostr but bindings or not.

No, but I tested it few times on Android and only on GrapheneOS

What makes the python FFI circuitous in your opinion?

It doesn't check the kind 3 but the filters or the events.

Extract the author/s and the p tags from filters/events and request the kind 10002/10050 (if not already cached or if expired).

Yes, every relay have some flags (the RelayServiceFlags). These define what a relay can do. For example, the automatically added (the gossip ones) will have the `GOSSIP` flag.

Kind 10050 is for DMs, kind 10002 for the other stuff. But both have the same aim. So IMO both have to be under the `gossip` option.

Because the NIP17 relay list have to be auto discovered and some relays to be automatically added to the pool.

By default nothing is auto discovered and no relay is automatically added to the pool.

## rust-nostr v0.37 is out! 🦀

### Summary

Add support to NIP17 relay list in SDK (when `gossip` option is enabled), add NIP22 and NIP73 support,

fix Swift Package, many performance improvements and bug fixes and more!

From this release all the rust features are be disabled by default (except `std` feature in `nostr` crate).

Full changelog: https://rust-nostr.org/changelog

### Contributors

Thanks to all contributors!

* nostr:npub1zuuajd7u3sx8xu92yav9jwxpr839cs0kc3q6t56vd5u9q033xmhsk6c2uc

* nostr:npub1q0uulk2ga9dwkp8hsquzx38hc88uqggdntelgqrtkm29r3ass6fq8y9py9

* nostr:npub1zfss807aer0j26mwp2la0ume0jqde3823rmu97ra6sgyyg956e0s6xw445

* nostr:npub1zwnx29tj2lnem8wvjcx7avm8l4unswlz6zatk0vxzeu62uqagcash7fhrf

* nostr:npub1acxjpdrlk2vw320dxcy3prl87g5kh4c73wp0knullrmp7c4mc7nq88gj3j

### Links

https://rust-nostr.org

https://rust-nostr.org/donate

#rustnostr #nostr #rustlang #programming #rust #python #javascript #kotlin #swift #flutter

Thanks! This would be the new snippet

```rust

use nwc::prelude::*;

let nwc = NWC::new(uri);

let params = PayInvoiceRequest::new(invoice);

let response = nwc.pay_invoice(params).await?;

```

Hey nostr:nprofile1qqsptdw0dn05l5wq9u5tens0r972ltjv337xdglzuga0nlnppp6nzhspz9mhxue69uhkummnw3eryvfwvdhk6qg5waehxw309aex2mrp0yhxgctdw4eju6t0qyw8wumn8ghj7mn0wd68ytnzd96xxmmfdejhytnnda3kjctvh2gd6f, I was wondering where can I open a PR to update the nwc.dev website. I noticed that the rust-nostr snippet on the homepage is really old, now there is a very simple client to use NWC. It's not too important... just asking.

Replying to Avatar 0xtr

hey nostr:npub1drvpzev3syqt0kjrls50050uzf25gehpz9vgdw08hvex7e0vgfeq0eseet, rust-nostr.org and rust-nostr.github.io doesn't seem to work anymore.

Thanks! Should be fixed now

The `NostrConnect` client, after the first `get_public_key` request, remembers the user public key and will no longer ask for it for that session.

Replying to Avatar DanConwayDev

From 151f0abb89e6ded8fa60557ca9d3c2469a68ce47 Mon Sep 17 00:00:00 2001

From: DanConwayDev

Date: Wed, 13 Nov 2024 12:34:21 +0000

Subject: [PATCH] connect: prevent err after `set_user_public_key`

prevent bootstrap from resulting in an error when triggered after

`set_user_public_key` is called. eg.

```

let signer = NostrConnect::new(...);

signer.set_user_public_key(pk);

// first usage of signer will trigger bootstrap eg:

signer.sign_event(e);

```

throw a error during bootstrap if the remote signer public key is

different to the value given to `set_user_public_key`. this would

happen in the unlikely event that the remote signer was reconfigured

to use the same app keys with a user key

---

crates/nostr-connect/src/client.rs | 8 +++++++-

crates/nostr-connect/src/error.rs | 3 +++

2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/crates/nostr-connect/src/client.rs b/crates/nostr-connect/src/client.rs

index 6bae456..c0dfffb 100644

--- a/crates/nostr-connect/src/client.rs

+++ b/crates/nostr-connect/src/client.rs

@@ -127,7 +127,13 @@ impl NostrConnect {

GetRemoteSignerPublicKey::RemoteOnly(public_key) => public_key,

GetRemoteSignerPublicKey::WithUserPublicKey { remote, user } => {

// Set user public key

- self.user_public_key.set(user)?; // This shouldn't fails

+ if let Some(stored_user_public_key) = self.user_public_key.get() {

+ if !user.eq(stored_user_public_key) {

+ return Err(Error::UserPublicKeyChanged(stored_user_public_key, user))

+ }

+ } else {

+ self.user_public_key.set(user)?; // This shouldn't fails

+ }

// Return remote signer public key

remote

diff --git a/crates/nostr-connect/src/error.rs b/crates/nostr-connect/src/error.rs

index 8a63543..8c6f2ba 100644

--- a/crates/nostr-connect/src/error.rs

+++ b/crates/nostr-connect/src/error.rs

@@ -37,6 +37,9 @@ pub enum Error {

/// Set user public key error

#[error(transparent)]

SetUserPublicKey(#[from] SetError),

+ /// User public key has changed

+ #[error("user public key changed from: {0} to: {1}")]

+ UserPublicKeyChanged(PublicKey, PublicKey),

/// NIP46 response error

#[error("response error: {0}")]

Response(String),

--

libgit2 1.8.1

Thanks! I already done a similar change locally that I not pushed yet, so I'm going to close this.

Replying to Avatar Five

Hey nostr:nprofile1qqsx3kq3vkgczq9hmfplc28h687py42yvms3zkyxh8nmkvn0vhkyyuspz4mhxue69uhkummnw3ezummcw3ezuer9wchsz9thwden5te0wfjkccte9ejxzmt4wvhxjme0qy88wumn8ghj7mn0wvhxcmmv9u0uehfp and #rust-nostr fans, can you enlighten me please:

When I am calculating my Web of Trust I do the following:

0. Create client with outbox model enabled

1. Get my follows, mutes, reports in one fetch call

2. Get follows, mutes, reports of my follows in another fetch call, using an authors filter that has all follows in it

3. Calculate scores with my weights locally

Question:

Why did step 2. take hours to complete?

It seems like it's trying to connect to loads of relays.

My guess is either I am doing sth horribly wrong or there is no smart relay set calculation for filters in the pool.

In ndk this calculation takes under 10 seconds to complete, even without any caching. It will first look at the filters and calculate a relay set that has all authors in it then does the fetching.

#asknostr #rust

I openes a PR: https://github.com/Pleb5/muse/pull/1

In my tests, after those changes, the WoT calculation takes between 7 and 13 secs.

Replying to Avatar Five

Hey nostr:nprofile1qqsx3kq3vkgczq9hmfplc28h687py42yvms3zkyxh8nmkvn0vhkyyuspz4mhxue69uhkummnw3ezummcw3ezuer9wchsz9thwden5te0wfjkccte9ejxzmt4wvhxjme0qy88wumn8ghj7mn0wvhxcmmv9u0uehfp and #rust-nostr fans, can you enlighten me please:

When I am calculating my Web of Trust I do the following:

0. Create client with outbox model enabled

1. Get my follows, mutes, reports in one fetch call

2. Get follows, mutes, reports of my follows in another fetch call, using an authors filter that has all follows in it

3. Calculate scores with my weights locally

Question:

Why did step 2. take hours to complete?

It seems like it's trying to connect to loads of relays.

My guess is either I am doing sth horribly wrong or there is no smart relay set calculation for filters in the pool.

In ndk this calculation takes under 10 seconds to complete, even without any caching. It will first look at the filters and calculate a relay set that has all authors in it then does the fetching.

#asknostr #rust

Currently, when gossip is enabled, are used all relays in user lists (there isn't a relays score at the moment). This will be improved in the next versions where will be kept a relays and gossip state into the database.

But anyway, it's weird that it require hours to complete. Can you share a code example?

To reduce speed compilation you can disable all default features (I'll probably disable all feature by default in future) and, to reduce the binary size, change some `profile.release` config.

Tests for the example I shared yesterday:

Default features and default release profile:

* compilation time: 43 secs

* cdylib size: 479kb

* staticlib size: 58Mb

Without default features but with default release profile:

* compilation time: 31 secs

* cdylib size: 479kb

* staticlib size: 49Mb

Without default features and with LTO enabled, codegen-units set to 1 and abort on panic (but still optimized for performance instead of size):

* compilation time: 35 secs

* cdylib size: 437kb

* staticlib size: 12Mb

Same as above but optimized for size (not aggressive):

* compilation time: 30 secs

* cdylib size: 427kb

* staticlib size: 9.5Mb

I not plan to write a sync version of the SDK, also if very very basic. But I can try to reduce the above values as much as possible.