-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is just enostr from notedeck! Fixes: #29
- Loading branch information
Showing
42 changed files
with
1,295 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,4 @@ tags | |
target/ | ||
.build-result | ||
.buildcmd | ||
build.log |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
[submodule "nostrdb"] | ||
path = nostrdb | ||
path = nostrdb_rs/nostrdb | ||
url = https://github.com/damus-io/nostrdb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,27 @@ | ||
[package] | ||
name = "nostrdb" | ||
authors = ["William Casarin <[email protected]>"] | ||
description = "An unfairly fast embedded nostr database backed by lmdb" | ||
readme = "README.md" | ||
version = "0.5.1" | ||
edition = "2021" | ||
build = "build.rs" | ||
license = "GPL-3.0-or-later" | ||
homepage = "https://github.com/damus-io/nostrdb-rs/" | ||
repository = "https://github.com/damus-io/nostrdb-rs/" | ||
[workspace] | ||
resolver = "2" | ||
members = [ | ||
"nostrdb_rs", | ||
"nostrdb_net", | ||
] | ||
|
||
[build-dependencies] | ||
cc = "1.0" | ||
bindgen = "0.69.1" | ||
|
||
[features] | ||
bindgen = [] | ||
|
||
[dependencies] | ||
flatbuffers = "23.5.26" | ||
[workspace.dependencies] | ||
bech32 = { version = "0.11", default-features = false } | ||
dirs = "5.0.1" | ||
hex = "0.4.3" | ||
libc = "0.2.151" | ||
nostrdb_net = { path = "nostrdb_net" } | ||
nostrdb = { path = "nostrdb_rs" } | ||
nostr = { version = "0.37.0", default-features = false, features = ["std", "nip49"] } | ||
serde_derive = "1" | ||
serde_json = "1.0.89" | ||
serde = { version = "1", features = ["derive"] } | ||
tempfile = "3.13.0" | ||
thiserror = "2.0.7" | ||
futures = "0.3.31" | ||
tokio = { version = "1", features = ["rt-multi-thread", "macros"] } | ||
tokio = { version = "1.16", features = ["macros", "rt-multi-thread"] } | ||
#tokio = { version = "1", features = ["rt-multi-thread", "macros"] } | ||
tracing = "0.1.40" | ||
tracing-subscriber = "0.3.18" | ||
|
||
[dev-dependencies] | ||
hex = "0.4.3" | ||
url = "2.5.2" | ||
urlencoding = "2.1.3" | ||
uuid = { version = "1.10.0", features = ["v4"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[package] | ||
name = "nostrdb_net" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
ewebsock = { version = "0.8.0", features = ["tls"] } | ||
serde_derive = "1" | ||
serde = { version = "1", features = ["derive"] } # You only need this if you want app persistence | ||
serde_json = { workspace = true } | ||
nostr = { workspace = true } | ||
bech32 = { workspace = true } | ||
nostrdb = { workspace = true } | ||
hex = { workspace = true } | ||
tracing = { workspace = true } | ||
thiserror = { workspace = true } | ||
url = { workspace = true } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
use crate::{Error, Note}; | ||
use nostrdb::Filter; | ||
use serde_json::json; | ||
|
||
/// Messages sent by clients, received by relays | ||
#[derive(Debug)] | ||
pub enum ClientMessage { | ||
Event { | ||
note: Note, | ||
}, | ||
Req { | ||
sub_id: String, | ||
filters: Vec<Filter>, | ||
}, | ||
Close { | ||
sub_id: String, | ||
}, | ||
Raw(String), | ||
} | ||
|
||
impl ClientMessage { | ||
pub fn event(note: Note) -> Self { | ||
ClientMessage::Event { note } | ||
} | ||
|
||
pub fn raw(raw: String) -> Self { | ||
ClientMessage::Raw(raw) | ||
} | ||
|
||
pub fn req(sub_id: String, filters: Vec<Filter>) -> Self { | ||
ClientMessage::Req { sub_id, filters } | ||
} | ||
|
||
pub fn close(sub_id: String) -> Self { | ||
ClientMessage::Close { sub_id } | ||
} | ||
|
||
pub fn to_json(&self) -> Result<String, Error> { | ||
Ok(match self { | ||
Self::Event { note } => json!(["EVENT", note]).to_string(), | ||
Self::Raw(raw) => raw.clone(), | ||
Self::Req { sub_id, filters } => { | ||
if filters.is_empty() { | ||
format!("[\"REQ\",\"{}\",{{ }}]", sub_id) | ||
} else if filters.len() == 1 { | ||
let filters_json_str = filters[0].json()?; | ||
format!("[\"REQ\",\"{}\",{}]", sub_id, filters_json_str) | ||
} else { | ||
let filters_json_str: Result<Vec<String>, Error> = filters | ||
.iter() | ||
.map(|f| f.json().map_err(Into::<Error>::into)) | ||
.collect(); | ||
format!("[\"REQ\",\"{}\",{}]", sub_id, filters_json_str?.join(",")) | ||
} | ||
} | ||
Self::Close { sub_id } => json!(["CLOSE", sub_id]).to_string(), | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
mod message; | ||
|
||
pub use message::ClientMessage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
//use nostr::prelude::secp256k1; | ||
use std::array::TryFromSliceError; | ||
use thiserror::Error; | ||
|
||
#[derive(Error, Debug)] | ||
pub enum Error { | ||
#[error("message is empty")] | ||
Empty, | ||
|
||
#[error("decoding failed")] | ||
DecodeFailed, | ||
|
||
#[error("hex decoding failed")] | ||
HexDecodeFailed, | ||
|
||
#[error("invalid bech32")] | ||
InvalidBech32, | ||
|
||
#[error("invalid byte size")] | ||
InvalidByteSize, | ||
|
||
#[error("invalid signature")] | ||
InvalidSignature, | ||
|
||
#[error("invalid public key")] | ||
InvalidPublicKey, | ||
|
||
// Secp(secp256k1::Error), | ||
#[error("json error: {0}")] | ||
Json(#[from] serde_json::Error), | ||
|
||
#[error("nostrdb error: {0}")] | ||
Nostrdb(#[from] nostrdb::Error), | ||
|
||
#[error("{0}")] | ||
Generic(String), | ||
} | ||
|
||
impl From<String> for Error { | ||
fn from(s: String) -> Self { | ||
Error::Generic(s) | ||
} | ||
} | ||
|
||
impl From<TryFromSliceError> for Error { | ||
fn from(_e: TryFromSliceError) -> Self { | ||
Error::InvalidByteSize | ||
} | ||
} | ||
|
||
impl From<hex::FromHexError> for Error { | ||
fn from(_e: hex::FromHexError) -> Self { | ||
Error::HexDecodeFailed | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub type Filter = nostrdb::Filter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
use nostr::nips::nip49::EncryptedSecretKey; | ||
use serde::Deserialize; | ||
use serde::Serialize; | ||
|
||
use crate::Pubkey; | ||
use crate::SecretKey; | ||
|
||
#[derive(Debug, Eq, PartialEq, Clone)] | ||
pub struct Keypair { | ||
pub pubkey: Pubkey, | ||
pub secret_key: Option<SecretKey>, | ||
} | ||
|
||
impl Keypair { | ||
pub fn from_secret(secret_key: SecretKey) -> Self { | ||
let cloned_secret_key = secret_key.clone(); | ||
let nostr_keys = nostr::Keys::new(secret_key); | ||
Keypair { | ||
pubkey: Pubkey::new(nostr_keys.public_key().to_bytes()), | ||
secret_key: Some(cloned_secret_key), | ||
} | ||
} | ||
|
||
pub fn new(pubkey: Pubkey, secret_key: Option<SecretKey>) -> Self { | ||
Keypair { pubkey, secret_key } | ||
} | ||
|
||
pub fn only_pubkey(pubkey: Pubkey) -> Self { | ||
Keypair { | ||
pubkey, | ||
secret_key: None, | ||
} | ||
} | ||
|
||
pub fn to_full(&self) -> Option<FilledKeypair<'_>> { | ||
self.secret_key.as_ref().map(|secret_key| FilledKeypair { | ||
pubkey: &self.pubkey, | ||
secret_key, | ||
}) | ||
} | ||
} | ||
|
||
#[derive(Debug, Eq, PartialEq, Clone)] | ||
pub struct FullKeypair { | ||
pub pubkey: Pubkey, | ||
pub secret_key: SecretKey, | ||
} | ||
|
||
#[derive(Debug, Eq, PartialEq, Clone, Copy)] | ||
pub struct FilledKeypair<'a> { | ||
pub pubkey: &'a Pubkey, | ||
pub secret_key: &'a SecretKey, | ||
} | ||
|
||
impl<'a> FilledKeypair<'a> { | ||
pub fn new(pubkey: &'a Pubkey, secret_key: &'a SecretKey) -> Self { | ||
FilledKeypair { pubkey, secret_key } | ||
} | ||
|
||
pub fn to_full(&self) -> FullKeypair { | ||
FullKeypair { | ||
pubkey: self.pubkey.to_owned(), | ||
secret_key: self.secret_key.to_owned(), | ||
} | ||
} | ||
} | ||
|
||
impl FullKeypair { | ||
pub fn new(pubkey: Pubkey, secret_key: SecretKey) -> Self { | ||
FullKeypair { pubkey, secret_key } | ||
} | ||
|
||
pub fn to_filled(&self) -> FilledKeypair<'_> { | ||
FilledKeypair::new(&self.pubkey, &self.secret_key) | ||
} | ||
|
||
pub fn generate() -> Self { | ||
let mut rng = nostr::secp256k1::rand::rngs::OsRng; | ||
let (secret_key, _) = &nostr::SECP256K1.generate_keypair(&mut rng); | ||
let (xopk, _) = secret_key.x_only_public_key(&nostr::SECP256K1); | ||
let secret_key = nostr::SecretKey::from(*secret_key); | ||
FullKeypair { | ||
pubkey: Pubkey::new(xopk.serialize()), | ||
secret_key, | ||
} | ||
} | ||
|
||
pub fn to_keypair(self) -> Keypair { | ||
Keypair { | ||
pubkey: self.pubkey, | ||
secret_key: Some(self.secret_key), | ||
} | ||
} | ||
} | ||
|
||
impl std::fmt::Display for Keypair { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
write!( | ||
f, | ||
"Keypair:\n\tpublic: {}\n\tsecret: {}", | ||
self.pubkey, | ||
match self.secret_key { | ||
Some(_) => "Some(<hidden>)", | ||
None => "None", | ||
} | ||
) | ||
} | ||
} | ||
|
||
impl std::fmt::Display for FullKeypair { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
write!(f, "Keypair:\n\tpublic: {}\n\tsecret: <hidden>", self.pubkey) | ||
} | ||
} | ||
|
||
#[derive(Debug, Eq, PartialEq, Serialize, Deserialize)] | ||
pub struct SerializableKeypair { | ||
pub pubkey: Pubkey, | ||
pub encrypted_secret_key: Option<EncryptedSecretKey>, | ||
} | ||
|
||
impl SerializableKeypair { | ||
pub fn from_keypair(kp: &Keypair, pass: &str, log_n: u8) -> Self { | ||
Self { | ||
pubkey: kp.pubkey, | ||
encrypted_secret_key: kp.secret_key.clone().and_then(|s| { | ||
EncryptedSecretKey::new(&s, pass, log_n, nostr::nips::nip49::KeySecurity::Weak).ok() | ||
}), | ||
} | ||
} | ||
|
||
pub fn to_keypair(&self, pass: &str) -> Keypair { | ||
Keypair::new( | ||
self.pubkey, | ||
self.encrypted_secret_key | ||
.and_then(|e| e.to_secret_key(pass).ok()), | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
mod client; | ||
mod error; | ||
mod filter; | ||
mod keypair; | ||
mod note; | ||
mod profile; | ||
mod pubkey; | ||
mod relay; | ||
|
||
pub use client::ClientMessage; | ||
pub use error::Error; | ||
pub use ewebsock; | ||
pub use filter::Filter; | ||
pub use keypair::{FilledKeypair, FullKeypair, Keypair, SerializableKeypair}; | ||
pub use nostr::SecretKey; | ||
pub use note::{Note, NoteId}; | ||
pub use profile::Profile; | ||
pub use pubkey::Pubkey; | ||
pub use relay::message::{RelayEvent, RelayMessage}; | ||
pub use relay::pool::{PoolEvent, RelayPool}; | ||
pub use relay::{Relay, RelayStatus}; | ||
|
||
pub type Result<T> = std::result::Result<T, error::Error>; |
Oops, something went wrong.