rust-nostr / nostr Goto Github PK
View Code? Open in Web Editor NEWNostr protocol implementation, SDK and FFI
Home Page: https://rust-nostr.org/
License: MIT License
Nostr protocol implementation, SDK and FFI
Home Page: https://rust-nostr.org/
License: MIT License
Describe the enhancement
NIP19-related data types like Nip19Event
or ParameterizedReplaceableEvent
have all fields private. However, I believe the values they hold should be accessible for reading.
Use case
Clients not only need to create NIP19 strings but also parse them and extract information from them. For that, they need access to values held by the fields.
Describe the enhancement
I would like to import your library and its functions from Python. I didn't find any documentation how to use rust implementations from within Python. Do you have a guide or some examples?
Use case
Use bindings to implement Python based applications/services/tools
Thanks and all the best
Describe the bug
Tag for generated Event seems to be missing # symbol. For example Tag::Identifier
should generate "#d". However the raw JSON only shows "d".
To Reproduce
let app_tag: Tag = Tag::Identifier(APP_SPEC_D_TAG.to_string());
ends up giving me JSON of
"tags":[["d","SomeAppTag"],
Expected behavior
Expect the tag key to be "#d" instead of "d".
Build environment
Describe the enhancement
I'd like to be able to share a RelayPool instance between multiple clients instances.
Use case
I am currently developing nostrss which allows to stream RSS feeds with multiple profiles.
As current nostr-sdk
client handles a single identity per instance, i have to start a unique client instance for each identity i intend to publish with. Each identity uses a default relays configuration, and therefore each client instance will try to start a connection on the relays.
This means that for a program that would want to publish notes with 10 different identities will try to establish 10 connections on the same relay, which is kind of spammy and unnecessary.
Additional context
I don't know if this is feasible, but maybe providing an Arc<Mutex<RelayPool>>
instead of a single RelayPool
instance to the relay_pool
client's property could be a way to go ? It'd need obviously to also allow to provide the Arced Mutex when initiating the client.
Describe the bug
I'm trying to create a new public channel using the new_channel()
function on the Client but it throws an "InvalidName" error. This is caused by the event builder not accepting spaces in names because of this regex: https://github.com/rust-nostr/nostr/blob/master/crates/nostr/src/event/builder.rs#L22
To Reproduce
Use the new_channel()
function in the event builder where you have set the name parameter in the Metadata parameter to a string that contains spaces.
Expected behavior
Spaces is a allowed in names and the function shouldn't throw an error.
Build environment
method name: sign_psbt
params: [network: string, psbt: string, descriptor?] //the descriptor could be optional
result: {
psbt: string,
finalized: boolean
}
Describe the bug
https://github.com/nostr-protocol/nips/blob/4b44453626dccd928952392fa8c6e7807b39a8ba/01.md
The
ids
andauthors
lists contain lowercase hexadecimal strings, which may either be an exact 64-character match, or a prefix of the event value. A prefix match is when the filter string is an exact string prefix of the event value. The use of prefixes allows for more compact filters where a large number of values are queried, and can provide some privacy for clients that may not want to disclose the exact authors or events they are searching for.
To Reproduce
N/A
Expected behavior
According to NIP-01, Filter
must have authors
field as Option<Vec<String>>
instead of Option<Vec<XOnlyPublicKey>>
, like ids
field already is.
Build environment
Describe the enhancement
Often times to handle an event notification, async functions are called. handle_notifications
itself is also an async function. So it'd be nice if there's a version of the function that takes in a async function.
Use case
To handle event notifications with routines that involves async function calls that will be await
ed.
Additional context
An example implementation
/// Handle notifications
pub async fn handle_notifications<F, Fut>(&self, func: F) -> Result<(), Error>
where
F: Fn(RelayPoolNotification) -> Fut,
Fut: Future<Output = Result<(), Error>>
{
loop {
let mut notifications = self.notifications();
while let Ok(notification) = notifications.recv().await {
func(notification).await?;
}
}
}
Currently this crate doesn't support Tag kinds used for nip57. To use this crate with my project I used the custom kind but think NIP57 is popular enough that it would make sense to define them here. Would you be interested in a PR for this?
When a Client
is dropped it still persists the connections to the relays, this is an easy footgun that can cause resource exhaustion.
The user needs to remember to call disconnect()
otherwise.
Describe the enhancement
The 0.20.0
version of nostr-sdk
provided with a publish_pow_text_note
method that allowed to use NIP-13 for message publishing.
As per the commit history, this method has been deleted from codebase without any apparent replacement for it.
I can't find any explanation on why this has been removed, and would like to either see it reintegrated, or understand why this has been striped out.
Use case
PoW notes imho are useful to show the will of clients to publish their messages on the network by allocating resources to ensure their messages are considered as legit.
I know not many relays use it for now to filter out the messages they broadcast, but i'm pretty sure over time its use will improve.
Currently UniFFI bindings works but are incomplete (compared to nostr
and nostr-sdk
crates)
Describe the enhancement
get_events_of(filters, duration)
returns matching events until EOSE
.
There are situations, however, where the caller may want to listen for one or more new events. In that case, using get_events_of
returns an empty list.
The only way the client can do this now, is to loop over client.notifications().recv().await
, which is unwieldy, especially when combined with a tokio::timeout
for limiting the amount of waiting.
Use case
One use-case is NIP-47 Nostr Wallet Connect, when a client sends a Kind::WalletConnectRequest
and wants to wait for the wallet service's Kind::WalletConnectResponse
to know if the NWC payment succeeded or failed.
Additional context
One way to achieve this is to have two variants:
get_stored_events_of(filters, duration)
, renamed from get_events_of(filters, duration)
get_all_events_of(filters, duration)
, new function containing events until EOSE
and new ones, where duration
means wait_duration
, meaning "wait and collect new events for this long before returning"Another approach is to extend get_stored_events
with a new arg include_new_events: bool
. This looks simpler, but may actually be more confusing, since the flag also controls the meaning of duration
(true
= wait for this duration before returning, false
= return on EOSE
or after this duration).
I noticed that while running a Client
from the nostr-sdk
crate and calling client.shutdown()
when a signal is received, there is a delay in the shutdown process. Looking at the code, I saw the thread::sleep
for 3 seconds here: https://github.com/rust-nostr/nostr/blob/master/crates/nostr-sdk/src/relay/pool.rs#L489
Why is that? If it's to wait for resource cleanup elsewhere, is there a possible path to wire that up using channels? It's not a huge issue, just creates a bit of an odd UX when closing a terminal-based client. Ideally, when the user is ready to quit the client, it exits as soon as possible.
I'd be happy to look into improving this, but I wanted to make sure I understand the motivation for it in the first place.
When sending messages (e.g. events) via Client
, they are sent to all connected relays. It would be useful to allow to choose to which relays the message is going to be sent.
Something like this, for illustration:
pub async fn send_event(&self, event: Event) -> Result<EventId, Error>
pub async fn send_event_to_some_relays<P>(&self, event: Event, accept_relay: P) -> Result<EventId, Error>
where P: Fn(&Url, &Relay) -> bool
I am running into an issue where my Kind 0 has both displayName
and display_name
and this causes the deserialization (Metadata::fromstr
) to fail. I'm not sure the best way to handle this as it doesn't make sense to have two fields that are the same but if clients are doing this it shouldn't break the deserialization of Metadata
.
{
"id": "0ff46820eb7531d8b2b400f90e8ee6124107bdd348a9615ab8a565c1736c11a7",
"pubkey": "04918dfc36c93e7db6cc0d60f37e1522f1c36b64d3f4b424c532d7c595febbc5",
"created_at": 1684718891,
"kind": 0,
"tags": [],
"content": "{\"lud16\":\"[email protected]\",\"nip05\":\"[email protected]\",\"picture\":\"https://thesimplekid.com/thesimplekid.png\",\"display_name\":\"thesimplekid\",\"about\":\"Wannabe open source dev\",\"name\":\"thesimplekid\",\"username\":\"thesimplekid\",\"displayName\":\"thesimplekid\",\"banner\":\"\",\"website\":\"\",\"lud06\":\"\"}",
"sig": "7291f43daf24342712b29b61f7e6439ea70955a1cb7907a3352f30c9a12bd6bf6401da08e846b0388aec72ad40a3f77af641c4da041ebf0081b65fa27d124a65"
}
nostr/crates/nostr/src/types/metadata.rs
Lines 41 to 44 in 2c98c20
Request and set RelayInformationDocument
in Relay
struct on connect
method call.
Looks like a ton of things added/changed since May. Any ETA on releases? Is it going through a major overhaul right now?
Thanks.
Describe the bug
For example, using tag 't' for hashtags is only a suggestion in NIP-12, its not a requirement for all Event notes. The tag with letter 't' is not reserved for anything and can mean different things depending on the Event kind, notably in NIP-23 (kind:30023
), NIP-99 (kind:30402
), and would have no special meaning whatsoever under NIP-78 (kind:30078
).
With the current TagKind
implementation (
nostr/crates/nostr/src/event/tag.rs
Line 382 in 30fc521
Custom
. This makes parsing particularly difficult.
One suggestion would be to create different TagKind
enums for each use-cases (eg, each NIP). An alternative would be to remove all special treatment for single letter Tag Kinds.
To reproduce
Create a TagKind::Custom
with kind string "t"
. Upon deserialization, it will become TagKind::T
instead.
Expected behaviour
Expects TagKind::Custom
with kind string "t"
to be deserialized back to TagKind::Custom
with kind string "t"
. Only TagKind::T
should be deserialized to TagKind::T
.
Build environment
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
Describe the bug
While nostr
parses and serializing "relay" tag, a trailing slash is added to the URL, resulting in a change in the event's id and a failure to verify the signature.
To Reproduce
Run the following test cases:
Expected behavior
The following event should be parsed as a valid event:
{"content":"","created_at":1682667878,"id":"3ece4a62659e91c70465cd8b2c1d0c87b5c8ae1320b75bceef56d0b53cef910a","kind":22242,"pubkey":"8f0a4c451af7940f055469228bbf5247c57ecec2867a4f35a5e1fa5056eddf8a","sig":"0a40073145aa3364b3cd780c7afd2a7ed90fdc7e63ea9815848cb7e9e09b7c628bc68fa4cff8dc77428f3155c99baf44fc0060bb1af51d50b7266141e2c62e90","tags":[["relay","wss://grove-ctrl-coding-casual.trycloudflare.com"],["challenge","7M26dMbCnGrV3vKCkHNQeFII0dagXyhwJvrbdG0dhuyhvAQiiH3nwK0FplTrxppc"]]}
(We can verify this with https://nak.nostr.com/ )
Build environment
Additional context
I am investigating a problem not being able to be verified NIP-42 AUTH messages sent from Amethyst. vitorpamplona/amethyst#354
Snort seems to add a trailing slash to the relay
tag value, so this is not apparent. Other events are also not affected because they do not use the relay
tag kind.
stdweb is unmaintained
Details | |
---|---|
Status | unmaintained |
Package | stdweb |
Version | 0.4.20 |
URL | koute/stdweb#403 |
Date | 2020-05-04 |
The author of the stdweb
crate is unresponsive.
Maintained alternatives:
See advisory page for additional details.
Describe the enhancement
Support for compiling with latest release, avoiding the use of special branch.
Use case
To improve mostro.network exchange, we are using your amazing lib.
Additional context
We spoke about the error some months ago and I add here a log:
error[E0432]: unresolved import `nostr_sdk::nostr::hashes::hex::ToHex`
--> src/lightning/mod.rs:10:46
|
10 | use nostr_sdk::nostr::hashes::hex::{FromHex, ToHex};
| ^^^^^ no `ToHex` in `hex`
error[E0432]: unresolved import `nostr_sdk::prelude::hex::ToHex`
--> src/util.rs:14:5
|
14 | use nostr_sdk::prelude::hex::ToHex;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `ToHex` in `hex`
error[E0061]: this function takes 3 arguments but 4 arguments were supplied
Thanks for your great work.
I'm making an app and I want to create a default pubkey that uses nostr to identify the users (to keep track of customers).
How do I print the formatted pubkey to display it to the user? Such as npubq3qfun...
I already have the Xonly pubkey but I can't find in the docs how to convert it to that form.
A few weeks ago, the NIP-48 (discussion here) was merged in the nips specs.
A few projects maintainer that provide bridges were pinged to see if we would implement it.
I intend to implement those tags for publishing with nostrss. However, for now the SDK client does not provide any enum kind for those proxy tags.
I think i'd be great to have it implemented in the SDK.
Thanks for providing this cool library.
Describe the bug
I'm trying to get a note from relay using client.get_events_of
, but timeouts occur frequently.
It seems that the connection to a relay is taking a long time.
[2023-02-16T02:43:10Z DEBUG nostr_sdk::relay::pool] RelayPoolTask Thread Started
[2023-02-16T02:43:10Z DEBUG nostr_sdk::relay] wss://relay.damus.io/ channel capacity: 1023
[2023-02-16T02:43:10Z DEBUG nostr_sdk::relay] Connecting to wss://relay.damus.io/
[2023-02-16T02:43:10Z DEBUG reqwest::connect] starting new connection: https://relay.damus.io/
[2023-02-16T02:43:10Z DEBUG rustls::client::hs] No cached session for DnsName(DnsName(DnsName("relay.damus.io")))
[2023-02-16T02:43:10Z DEBUG rustls::client::hs] Not resuming any session
[2023-02-16T02:43:10Z DEBUG rustls::client::hs] No cached session for DnsName(DnsName(DnsName("relay.damus.io")))
[2023-02-16T02:43:10Z DEBUG rustls::client::hs] Not resuming any session
[2023-02-16T02:43:10Z DEBUG rustls::client::hs] Using ciphersuite TLS13_AES_256_GCM_SHA384
[2023-02-16T02:43:10Z DEBUG rustls::client::tls13] Not resuming
[2023-02-16T02:43:10Z DEBUG rustls::client::tls13] TLS1.3 encrypted extensions: [ServerNameAck, Protocols([6832])]
[2023-02-16T02:43:10Z DEBUG rustls::client::hs] ALPN protocol is Some(b"h2")
[2023-02-16T02:43:10Z DEBUG rustls::client::hs] Using ciphersuite TLS13_AES_256_GCM_SHA384
[2023-02-16T02:43:10Z DEBUG rustls::client::tls13] Not resuming
[2023-02-16T02:43:10Z DEBUG rustls::client::tls13] TLS1.3 encrypted extensions: [ServerNameAck]
[2023-02-16T02:43:10Z DEBUG rustls::client::hs] ALPN protocol is None
[2023-02-16T02:43:10Z DEBUG rustls::client::tls13] Ticket saved
[2023-02-16T02:43:10Z DEBUG rustls::client::tls13] Ticket saved
[2023-02-16T02:43:23Z DEBUG rustls::conn] Sending warning alert CloseNotify
[2023-02-16T02:43:30Z DEBUG rustls::client::tls13] Ticket saved
[2023-02-16T02:43:30Z DEBUG rustls::client::tls13] Ticket saved
[2023-02-16T02:43:30Z DEBUG tungstenite::handshake::client] Client handshake done.
[2023-02-16T02:43:30Z INFO nostr_sdk::relay] Connected to wss://relay.damus.io/
[2023-02-16T02:43:30Z DEBUG nostr_sdk::relay] Relay Message Thread Started
[2023-02-16T02:43:30Z DEBUG nostr_sdk::relay] Relay Event Thread Started
[2023-02-16T02:43:50Z DEBUG nostr_sdk::relay] wss://relay.damus.io/ channel capacity: 1024
[2023-02-16T02:44:10Z ERROR nostr_sdk::relay::pool] Failed to get events from wss://relay.damus.io/: timeout
Even if the connection is successfully established, event cannot be acquired.
I added a debug code in get_events_of_with_callback
in src/relay/mod.rs
and found the following error returned from a relay.
Notice { message: "ERROR: bad req: subscription id too long" }
Notice { message: "ERROR: bad req: arr too small" }
Note that I also use nostr-tools and the same code worked without timeouts.
To Reproduce
Full code is here: https://github.com/akiomik/nostr-sdk-timeout-issue
use nostr_sdk::prelude::*;
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<()> {
env_logger::init();
// Create new client
let my_keys: Keys = Keys::generate();
let client = Client::new(&my_keys);
// Connect to a relay
client.add_relay("wss://relay.damus.io", None).await?;
client.connect().await;
// Get event
let id = String::from("4aac0ffb020ed44e4f54a39ac1897f9bc6512d0e0fb5e29226d14a88b1c58a9c");
let timeout = Some(Duration::from_secs(60));
let filter = Filter::new().ids(vec![id]);
let events = client.get_events_of(vec![filter], timeout).await?;
println!("{events:?}");
// Disconnect
client.disconnect().await?;
Ok(())
}
Expected behavior
It works without timeouts.
Build environment
Does this support query for tags that are not 't'? My reading of NIP 12 says that it can be any single-letter key. But it seems this crate only supports e,p,t,r?
Describe the enhancement
It's possible to construct event kinds that make them incompatible with (i.e. not ==
to) the json deserialized version of themselves.
The enhancement would be to only expose valid ways of constructing event kinds, such that this is not an issue anymore.
Use case
For example, for a custom kind 20100, which is in the ephemeral range:
// Will NOT work (false)
if let received_event.kind == Kind::Custom(20100) { }
// Will work (true)
if let received_event.kind == Kind::Ephemeral(20100) { }
// Will work (true)
// Looks like the most appropriate way
if let received_event.kind == Kind::from(20100) { }
Additional context
The only way I can think of is to enforce kinds to only be constructed via Kind::from(u64)
, although not sure how to do that.
Describe the enhancement
I noticed RelayConnectionStats
gives connection stats.
Is it possible to measure and include the connection latency? Let's say the average of the last 5 requests?
Use case
Clients that use multiple relays may want to sort by connection reliability and speed, so the user can decide which to keep and which to remove.
Some event types also take an optional relay URL (like replies to a note), and choosing the best relay would be very useful.
Describe the bug
I am trying to get a NOTE from a relay using Client#get_events_of
in nostr-sdk.
While looking at the debug logs, I noticed the following log output.
nostr_sdk::relay Receive unhandled message Notice { message: "ERROR: bad req: arr too small" } on get_events_of
nostr_sdk::relay Receive unhandled message Notice { message: "invalid: \"REQ message\" does not contain [filter]" } on get_events_of
Looking at the relay server code, it seems to be caused by an REQ without filters specified.
Adding some debugging code, I found that an empty REQ is sent apart from the actual filter (that I specified), which looks like this
nostr::message::client ["REQ", "f4a8b89c3a4d947b188a8e7f7f66e76f"]
If this message is needed, the correct filters should be set; if it is not needed, it should not be sent.
To Reproduce
Execute the following code using RUST_LOG=debug cargo run
.
use nostr_sdk::prelude::*;
use std::time::Duration;
#[tokio::main]
async fn main() -> Result<()> {
env_logger::init();
// Generate new keys
let my_keys: Keys = Keys::generate(); // dummy
// Create new client
let client = Client::new(&my_keys);
// nostream returns Notice { message: "invalid: \"REQ message\" does not contain [filter]" }
client.add_relay("wss://eden.nostr.land", None).await?;
// strfry returns Notice { message: "ERROR: bad req: arr too small" }
client.add_relay("wss://relay.damus.io", None).await?;
// Connect to relays
client.connect().await;
let id = String::from("4aac0ffb020ed44e4f54a39ac1897f9bc6512d0e0fb5e29226d14a88b1c58a9c");
let timeout = Some(Duration::from_secs(10));
let filter = Filter::new().limit(1).kinds(vec![Kind::TextNote]).ids(vec![id]);
let events = client.get_events_of(vec![filter], timeout).await?;
println!("{events:?}"); // -> []
client.disconnect().await?;
Ok(())
}
Expected behavior
No return of any Notice
from relays.
Build environment
I have a question:
How would I subscribe to a public channel via your nostr-sdk
in order to get all (or part) of the messages on this public channel?
Like the Nostr channel on
25e5c82273a271cb1a840d0060391a0bf4965cafeb029d5ab55350b418953fbb ?
Or any other channel listed here: https://damus.io/channels/
I assume this is NIP-28.
Generate changelog for every crate using git cliff
or something else.
Direct posting of gist or contributions to other social media accounts that were categorised as public, in settings
Describe the bug
Starting with commit 2dd972d calling Client.get_events_of()
returns an empty list.
This works fine in the commit before that, 2ebd5a1 .
Using Client.notifications().recv()
works in both commits.
To Reproduce
use std::time::Duration;
use nostr::prelude::*;
use nostr_sdk::prelude::*;
#[tokio::main]
async fn main() -> Result<()> {
let filters = vec![Filter::new().kind(Kind::TextNote).limit(10)];
let client = Client::new(&Keys::generate());
client.add_relay("wss://relay.damus.io", None).await?;
client.connect().await;
let res_get_events_of = client
.get_events_of(filters.clone(), Some(Duration::from_secs(3)))
.await?;
println!("recv via get_events_of: {} events", res_get_events_of.len());
let res_notification_recv = get_events_via_notification_recv(&client, filters).await?;
println!("recv via notifications: {} events", res_notification_recv.len());
Ok(())
}
async fn get_events_via_notification_recv(
client: &Client,
filters: Vec<Filter>,
) -> Result<Vec<Event>> {
let mut res: Vec<Event> = vec![];
client.subscribe(filters).await;
let mut notifications = client.notifications();
loop {
match notifications.recv().await {
Ok(notification) => {
if let RelayPoolNotification::Message(_, msg) = notification {
match msg {
RelayMessage::Event {
subscription_id: _,
event,
} => res.push(*event),
RelayMessage::EndOfStoredEvents(_) => break,
_ => {}
}
}
}
Err(e) => panic!("Unexpected error: {e}"),
}
}
Ok(res)
}
Expected behavior
In the code snippet above, Client.get_events_of()
and Client.notifications().recv()
should return the same number of events.
Build environment
1.69.0
Additional context
Dependencies in Cargo.toml
:
[dependencies]
nostr = { git = "https://github.com/rust-nostr/nostr", default-features = false, rev = "2dd972de2f56aee19818f8798869ac9355f6aadd" }
nostr-sdk = { git = "https://github.com/rust-nostr/nostr", default-features = false, rev = "2dd972de2f56aee19818f8798869ac9355f6aadd" }
tokio = { version = "*", default-features = false, features = ["rt", "macros"] }
"32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" is a pub key of an individual.
"25e5c82273a271cb1a840d0060391a0bf4965cafeb029d5ab55350b418953fbb" is a pub key of a Public Channel. Some call it a channel id
.
Question: given some string like "25e5c82273a271cb1a840d0060391a0bf4965cafeb029d5ab55350b418953fbb" how can I determine programmatically if it is a public channel or a person?
I know that the strings can be distinguished because anigma.io distinguishes them, anigma.io only let's you subscribe to public channels but rejects pub keys of individuals. How can I do it?
Would that be an interesting function to add to nostr-sdk
as a feature enhancement?
Please consider adding the traits for serialize
and deserialize
to Entity
(Enum nostr_sdk::client::Entity). Thank you.
Describe the enhancement
Secp256k1::new()
is an expensive operation (IIRC hundreds of milliseconds), avoid multiple calls by using:
Use case
Additional context
Describe the bug
Sending an event with client.send_event(ev).await
while all relays are in RelayStatus::Connecting
will result in Ok
.
To Reproduce
client.relays().await
to get relay.status().await
Connecting
(or in any other way not connected), call client.send_event(ev).await
Expected behavior
Sending when not one relay is connected should fail.
Alternatively, there could be a client.send_event(ev: Event, retry_duration: Duration)
method, which would try for some time until its sent to at least one relay.
Build environment
Describe the bug
Passing REQ event that contains negative numbers results in error
To Reproduce
Send client message:
[
"REQ",
"some_id",
{
"authors": [
"3235036bd0957dfb27ccda02d452d7c763be40c91a1ac082ba6983b25238388y"
],
"kinds": [
0,
3
],
"limit": 200000,
"since": -50123406
}
]
Expected behavior
Parsed ClientMessage::Req structure
Build environment
Additional context
nostr_console sends negative values for timestamps
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.