push events to nostrdb lol

This commit is contained in:
Jack Chakany 2024-12-15 15:08:20 -05:00
parent 827be9a297
commit e9bb2a9172
9 changed files with 290 additions and 542 deletions

464
Cargo.lock generated
View file

@ -118,17 +118,6 @@ dependencies = [
"generic-array",
]
[[package]]
name = "aes"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
]
[[package]]
name = "ahash"
version = "0.8.11"
@ -330,7 +319,7 @@ dependencies = [
"polling 2.8.0",
"rustix 0.37.27",
"slab",
"socket2 0.4.10",
"socket2",
"waker-fn",
]
@ -540,6 +529,16 @@ dependencies = [
"rustc-demangle",
]
[[package]]
name = "base58ck"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f"
dependencies = [
"bitcoin-internals",
"bitcoin_hashes 0.14.0",
]
[[package]]
name = "base64"
version = "0.21.7"
@ -560,9 +559,9 @@ checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
[[package]]
name = "bech32"
version = "0.10.0-beta"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98f7eed2b2781a6f0b5c903471d48e15f56fb4e1165df8a9a2337fd1a59d45ea"
checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d"
[[package]]
name = "bincode"
@ -630,13 +629,16 @@ checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]]
name = "bitcoin"
version = "0.31.2"
version = "0.32.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c85783c2fe40083ea54a33aa2f0ba58831d90fcd190f5bdc47e74e84d2a96ae"
checksum = "ce6bc65742dea50536e35ad42492b234c27904a27f0abdcbce605015cb4ea026"
dependencies = [
"base58ck",
"bech32",
"bitcoin-internals",
"bitcoin_hashes 0.13.0",
"bitcoin-io",
"bitcoin-units",
"bitcoin_hashes 0.14.0",
"hex-conservative",
"hex_lit",
"secp256k1",
@ -645,13 +647,29 @@ dependencies = [
[[package]]
name = "bitcoin-internals"
version = "0.2.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb"
checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2"
dependencies = [
"serde",
]
[[package]]
name = "bitcoin-io"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf"
[[package]]
name = "bitcoin-units"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5285c8bcaa25876d07f37e3d30c303f2609179716e11d688f51e8f1fe70063e2"
dependencies = [
"bitcoin-internals",
"serde",
]
[[package]]
name = "bitcoin_hashes"
version = "0.11.0"
@ -660,11 +678,11 @@ checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4"
[[package]]
name = "bitcoin_hashes"
version = "0.13.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b"
checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16"
dependencies = [
"bitcoin-internals",
"bitcoin-io",
"hex-conservative",
"serde",
]
@ -1725,15 +1743,6 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "futures-channel"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
dependencies = [
"futures-core",
]
[[package]]
name = "futures-core"
version = "0.3.30"
@ -2052,9 +2061,12 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hex-conservative"
version = "0.1.2"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20"
checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd"
dependencies = [
"arrayvec",
]
[[package]]
name = "hex_lit"
@ -2097,6 +2109,7 @@ dependencies = [
"image 0.25.1",
"nostr",
"nostrdb",
"pollster",
"puffin",
"puffin_http",
"rand",
@ -2119,92 +2132,12 @@ dependencies = [
"itoa",
]
[[package]]
name = "http-body"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
dependencies = [
"bytes",
"http",
]
[[package]]
name = "http-body-util"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
dependencies = [
"bytes",
"futures-util",
"http",
"http-body",
"pin-project-lite",
]
[[package]]
name = "httparse"
version = "1.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
[[package]]
name = "hyper"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http",
"http-body",
"httparse",
"itoa",
"pin-project-lite",
"smallvec",
"tokio",
"want",
]
[[package]]
name = "hyper-rustls"
version = "0.27.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155"
dependencies = [
"futures-util",
"http",
"hyper",
"hyper-util",
"rustls 0.23.11",
"rustls-pki-types",
"tokio",
"tokio-rustls",
"tower-service",
"webpki-roots",
]
[[package]]
name = "hyper-util"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http",
"http-body",
"hyper",
"pin-project-lite",
"socket2 0.5.7",
"tokio",
"tower",
"tower-service",
"tracing",
]
[[package]]
name = "icrate"
version = "0.0.4"
@ -2338,12 +2271,6 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "ipnet"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
[[package]]
name = "itertools"
version = "0.12.1"
@ -2655,17 +2582,6 @@ dependencies = [
"simd-adler32",
]
[[package]]
name = "mio"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
dependencies = [
"libc",
"wasi",
"windows-sys 0.48.0",
]
[[package]]
name = "naga"
version = "0.19.2"
@ -2723,6 +2639,12 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e664971378a3987224f7a0e10059782035e89899ae403718ee07de85bec42afe"
[[package]]
name = "negentropy"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a88da9dd148bbcdce323dd6ac47d369b4769d4a3b78c6c52389b9269f77932"
[[package]]
name = "new_debug_unreachable"
version = "1.0.6"
@ -2765,12 +2687,13 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
[[package]]
name = "nostr"
version = "0.32.1"
version = "0.37.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7948938314ee0392f378ab1a5d58b4707f2207550bc410b1629a80a4f28af7d"
checksum = "8aad4b767bbed24ac5eb4465bfb83bc1210522eb99d67cf4e547ec2ec7e47786"
dependencies = [
"aes",
"base64 0.21.7",
"async-trait",
"base64 0.22.1",
"bech32",
"bip39",
"bitcoin",
"cbc",
@ -2778,19 +2701,14 @@ dependencies = [
"chacha20poly1305",
"getrandom",
"instant",
"js-sys",
"negentropy",
"negentropy 0.3.1",
"negentropy 0.4.3",
"once_cell",
"reqwest",
"scrypt",
"serde",
"serde_json",
"tracing",
"unicode-normalization",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
[[package]]
@ -3004,9 +2922,9 @@ dependencies = [
[[package]]
name = "once_cell"
version = "1.19.0"
version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "opaque-debug"
@ -3116,26 +3034,6 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
[[package]]
name = "pin-project"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3"
dependencies = [
"pin-project-internal",
]
[[package]]
name = "pin-project-internal"
version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.60",
]
[[package]]
name = "pin-project-lite"
version = "0.2.14"
@ -3209,6 +3107,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "pollster"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3"
[[package]]
name = "poly1305"
version = "0.8.0"
@ -3348,53 +3252,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "quinn"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4ceeeeabace7857413798eb1ffa1e9c905a9946a57d81fb69b4b71c4d8eb3ad"
dependencies = [
"bytes",
"pin-project-lite",
"quinn-proto",
"quinn-udp",
"rustc-hash",
"rustls 0.23.11",
"thiserror",
"tokio",
"tracing",
]
[[package]]
name = "quinn-proto"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddf517c03a109db8100448a4be38d498df8a210a99fe0e1b9eaf39e78c640efe"
dependencies = [
"bytes",
"rand",
"ring",
"rustc-hash",
"rustls 0.23.11",
"slab",
"thiserror",
"tinyvec",
"tracing",
]
[[package]]
name = "quinn-udp"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9096629c45860fc7fb143e125eb826b5e721e10be3263160c7d60ca832cf8c46"
dependencies = [
"libc",
"once_cell",
"socket2 0.5.7",
"tracing",
"windows-sys 0.52.0",
]
[[package]]
name = "quote"
version = "1.0.36"
@ -3586,49 +3443,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
[[package]]
name = "reqwest"
version = "0.12.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37"
dependencies = [
"base64 0.22.1",
"bytes",
"futures-core",
"futures-util",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-rustls",
"hyper-util",
"ipnet",
"js-sys",
"log",
"mime",
"once_cell",
"percent-encoding",
"pin-project-lite",
"quinn",
"rustls 0.23.11",
"rustls-pemfile",
"rustls-pki-types",
"serde",
"serde_json",
"serde_urlencoded",
"sync_wrapper",
"tokio",
"tokio-rustls",
"tokio-socks",
"tower-service",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"webpki-roots",
"winreg",
]
[[package]]
name = "resvg"
version = "0.37.0"
@ -3747,30 +3561,6 @@ dependencies = [
"zeroize",
]
[[package]]
name = "rustls"
version = "0.23.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4828ea528154ae444e5a642dbb7d5623354030dc9822b83fd9bb79683c7399d0"
dependencies = [
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-pemfile"
version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d"
dependencies = [
"base64 0.22.1",
"rustls-pki-types",
]
[[package]]
name = "rustls-pki-types"
version = "1.7.0"
@ -3851,11 +3641,11 @@ dependencies = [
[[package]]
name = "secp256k1"
version = "0.28.2"
version = "0.29.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d24b59d129cdadea20aea4fb2352fa053712e5d713eee47d700cd4b2bc002f10"
checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113"
dependencies = [
"bitcoin_hashes 0.13.0",
"bitcoin_hashes 0.14.0",
"rand",
"secp256k1-sys",
"serde",
@ -3863,9 +3653,9 @@ dependencies = [
[[package]]
name = "secp256k1-sys"
version = "0.9.2"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5d1746aae42c19d583c3c1a8c646bfad910498e2051c551a7f2e3c0c9fbb7eb"
checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9"
dependencies = [
"cc",
]
@ -3952,18 +3742,6 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_urlencoded"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
dependencies = [
"form_urlencoded",
"itoa",
"ryu",
"serde",
]
[[package]]
name = "sha1"
version = "0.10.6"
@ -4119,16 +3897,6 @@ dependencies = [
"winapi",
]
[[package]]
name = "socket2"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "spin"
version = "0.9.8"
@ -4200,12 +3968,6 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "sync_wrapper"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
[[package]]
name = "system-deps"
version = "6.2.2"
@ -4366,14 +4128,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
dependencies = [
"backtrace",
"bytes",
"libc",
"mio",
"num_cpus",
"pin-project-lite",
"socket2 0.5.7",
"tokio-macros",
"windows-sys 0.48.0",
]
[[package]]
@ -4387,29 +4144,6 @@ dependencies = [
"syn 2.0.60",
]
[[package]]
name = "tokio-rustls"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
dependencies = [
"rustls 0.23.11",
"rustls-pki-types",
"tokio",
]
[[package]]
name = "tokio-socks"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0"
dependencies = [
"either",
"futures-util",
"thiserror",
"tokio",
]
[[package]]
name = "toml"
version = "0.8.12"
@ -4466,33 +4200,6 @@ dependencies = [
"winnow 0.6.6",
]
[[package]]
name = "tower"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
dependencies = [
"futures-core",
"futures-util",
"pin-project",
"pin-project-lite",
"tokio",
"tower-layer",
"tower-service",
]
[[package]]
name = "tower-layer"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
[[package]]
name = "tower-service"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
[[package]]
name = "tracing"
version = "0.1.40"
@ -4562,12 +4269,6 @@ dependencies = [
"tracing-log",
]
[[package]]
name = "try-lock"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "ttf-parser"
version = "0.20.0"
@ -4587,7 +4288,7 @@ dependencies = [
"httparse",
"log",
"rand",
"rustls 0.22.4",
"rustls",
"rustls-pki-types",
"sha1",
"thiserror",
@ -4793,15 +4494,6 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "want"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
dependencies = [
"try-lock",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
@ -5510,16 +5202,6 @@ dependencies = [
"memchr",
]
[[package]]
name = "winreg"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5"
dependencies = [
"cfg-if",
"windows-sys 0.48.0",
]
[[package]]
name = "x11-dl"
version = "2.21.0"

View file

@ -25,9 +25,10 @@ puffin_http = { version = "0.16.0", optional = true }
ewebsock = { version = "0.6.0", features = ["tls"] }
nostrdb = { git = "https://github.com/damus-io/nostrdb-rs", rev = "ee8afeeb0b6695fca6d27dd0b74a8dc159e37b95" }
rand = "0.8.5"
nostr = { version = "0.32.1", features = ["std", "nip59"] }
nostr = { version = "0.37.0", features = ["std", "nip59"] }
serde = "1.0.204"
serde_json = "1.0.121"
pollster = "0.4.0"
[target.'cfg(target_os = "macos")'.dependencies]
security-framework = "3.0.0"

View file

@ -1,5 +1,7 @@
use crate::keystorage::{Result, KeyStorage, KeyStorageType};
use nostr::Keys;
use crate::keystorage::{Error, Result, KeyStorage, KeyStorageType};
use nostr::{Keys, Event};
use nostr::nips::nip59::UnwrappedGift;
use pollster::FutureExt as _;
pub struct AccountManager {
pub loaded_keys: Vec<Keys>,
@ -12,6 +14,21 @@ impl AccountManager {
}
}
pub fn unwrap_gift_wrap(&mut self, gift_wrap: &Event) -> Result<UnwrappedGift> {
let target_pubkey = gift_wrap.tags.iter()
.find(|tag| tag.kind() == "p".into())
.and_then(|tag| tag.content())
.ok_or(Error::KeyNotFound)?;
let target_key = self.loaded_keys.iter()
.find(|key| key.public_key().to_string() == *target_pubkey)
.ok_or(Error::KeyNotFound)?;
UnwrappedGift::from_gift_wrap(target_key, gift_wrap)
.block_on()
.map_err(|e| Error::UnwrappingFailed(e.to_string()))
}
pub fn generate_keys(&mut self) -> Result<Keys> {
let new_keypair = Keys::generate();
self.loaded_keys.push(new_keypair.clone());
@ -53,7 +70,6 @@ impl AccountManager {
KeyStorageType::None
}
}
impl KeyStorage for AccountManager {
fn get_keys(&self) -> Result<Vec<Keys>> {
Self::get_platform_keystorage().get_keys()

View file

@ -2,6 +2,9 @@
pub enum Error {
RelayNotConnected,
SerdeJson(serde_json::Error),
Generic(String),
Empty,
DecodeFailed,
}
impl From<serde_json::Error> for Error {
@ -15,6 +18,9 @@ impl std::fmt::Display for Error {
match self {
Error::RelayNotConnected => write!(f, "Relay not connected"),
Error::SerdeJson(err) => write!(f, "JSON serialization error: {}", err),
Error::Generic(s) => write!(f, "{}", s),
Error::Empty => write!(f, "Data was empty"),
Error::DecodeFailed => write!(f, "Could not decode JSON data."),
}
}
}

View file

@ -21,7 +21,7 @@ impl MacOSKeyStorage {
match set_generic_password(
self.service_name,
&key.public_key().to_hex().as_str(),
key.secret_key().unwrap().as_secret_bytes(),
key.secret_key().as_secret_bytes(),
) {
Ok(_) => Ok(()),
Err(_) => Err(Error::Addition(key.public_key().to_hex())),

View file

@ -18,6 +18,8 @@ pub enum Error {
IOError(std::io::Error),
Addition(String),
Removal(String),
KeyNotFound,
UnwrappingFailed(String),
}
pub type Result<T> = core::result::Result<T, Error>;
@ -34,6 +36,8 @@ impl std::fmt::Debug for Error {
Error::IOError(err) => write!(f, "IOError: {:?}", err),
Error::Addition(key) => write!(f, "Could not add key {}", key),
Error::Removal(key) => write!(f, "Could not remove key {}", key),
Error::KeyNotFound => write!(f, "Could not find key in keystore"),
Error::UnwrappingFailed(err) => write!(f, "Couldn't unwrap gift wrapped event: {}", err)
}
}
}
@ -44,6 +48,8 @@ impl std::fmt::Display for Error {
Error::IOError(err) => write!(f, "IO error: {}", err),
Error::Addition(key) => write!(f, "Could not add key {}", key),
Error::Removal(key) => write!(f, "Could not remove key {}", key),
Error::KeyNotFound => write!(f, "Could not find key in keystore"),
Error::UnwrappingFailed(err) => write!(f, "Couldn't unwrap gift wrapped event: {}", err)
}
}
}

View file

@ -1,5 +1,6 @@
use nostr::{Event, EventBuilder, Keys, Kind, PublicKey, Tag};
use nostr::{Event, EventBuilder, Keys, Kind, PublicKey, Tag, TagKind, TagStandard};
use std::collections::HashMap;
use pollster::FutureExt as _;
pub const MAIL_EVENT_KIND: u16 = 1059;
@ -21,13 +22,20 @@ impl MailMessage {
pubkeys_to_send_to.push(*pubkey);
}
let base_event = EventBuilder::new(Kind::Custom(MAIL_EVENT_KIND), &self.content, [])
.to_unsigned_event(sending_keys.clone().public_key());
for pubkey in &self.cc {
tags.push(Tag::custom(TagKind::p(), vec![pubkey.to_hex().as_str(), "cc"]));
pubkeys_to_send_to.push(*pubkey);
}
tags.push(Tag::from_standardized(TagStandard::Subject(self.subject.clone())));
let base_event = EventBuilder::new(Kind::Custom(MAIL_EVENT_KIND), &self.content)
.tags(tags);
let mut event_list: HashMap<PublicKey, Event> = HashMap::new();
for pubkey in pubkeys_to_send_to {
let wrapped_event =
EventBuilder::gift_wrap(sending_keys, &pubkey, base_event.clone(), None).unwrap();
EventBuilder::gift_wrap(sending_keys, &pubkey, base_event.clone(), None).block_on().unwrap();
event_list.insert(pubkey, wrapped_event);
}

View file

@ -128,22 +128,30 @@ fn update_app(app: &mut Hoot, ctx: &egui::Context) {
if new_val.is_some() {
info!("{:?}", new_val.clone());
use relay::RelayMessage;
let deserialized: RelayMessage =
serde_json::from_str(new_val.unwrap().as_str()).expect("relay sent us bad json");
match relay::RelayMessage::from_json(&new_val.unwrap()) {
Ok(v) => process_message(app, &v),
Err(e) => error!("could not decode message sent from relay: {}", e),
};
}
}
use RelayMessage::*;
match deserialized {
Event {
subscription_id,
event,
} => {
app.events.push(event);
}
_ => {
// who cares rn
}
}
fn process_message(app: &mut Hoot, msg: &relay::RelayMessage) {
use relay::RelayMessage::*;
match msg {
Event(sub_id, event) => process_event(app, &sub_id, &event),
_ => {
// we don't care rn.
},
}
}
fn process_event(app: &mut Hoot, _sub_id: &str, event: &str) {
#[cfg(feature = "profiling")]
puffin::profile_function!();
if let Err(err) = app.ndb.process_event(event) {
error!("error processing event: {}", err);
}
}
@ -203,8 +211,8 @@ fn render_app(app: &mut Hoot, ctx: &egui::Context) {
if ui.button("Send Test Event").clicked() {
let temp_keys = nostr::Keys::generate();
// todo: lmao
let new_event = nostr::EventBuilder::text_note("GFY!", [])
.to_event(&temp_keys)
let new_event = nostr::EventBuilder::text_note("GFY!")
.sign_with_keys(&temp_keys)
.unwrap();
let event_json = crate::relay::ClientMessage::Event { event: new_event };
let _ = &app
@ -246,7 +254,7 @@ fn render_app(app: &mut Hoot, ctx: &egui::Context) {
let row_height = 30.0;
let events = app.events.clone();
body.rows(row_height, events.len(), |mut row| {
let row_index = row.index();
let event = &events[row.index()];
row.col(|ui| {
ui.checkbox(&mut false, "");
});
@ -254,18 +262,18 @@ fn render_app(app: &mut Hoot, ctx: &egui::Context) {
ui.checkbox(&mut false, "");
});
row.col(|ui| {
ui.label(events[row_index].pubkey.to_string());
ui.label(event.pubkey.to_string());
});
row.col(|ui| {
ui.label(events[row_index].content.clone());
ui.label(event.content.clone());
});
row.col(|ui| {
ui.label("2 minutes ago");
});
if row.response().clicked() {
println!("clicked: {}", events[row_index].content.clone());
app.focused_post = events[row_index].id().to_string();
println!("clicked: {}", event.content.clone());
app.focused_post = event.id.to_string();
app.page = Page::Post;
}
});
@ -279,16 +287,30 @@ fn render_app(app: &mut Hoot, ctx: &egui::Context) {
"focused_post should not be empty when Page::Post"
);
let event_to_display = app
let gift_wrapped_event = app
.events
.iter()
.find(|&x| x.id().to_string() == app.focused_post)
.find(|&x| x.id.to_string() == app.focused_post)
.expect("event id should be present inside event list");
let event_to_display = app.account_manager.unwrap_gift_wrap(gift_wrapped_event).expect("we should be able to unwrap an event we recieved");
ui.heading("View Message");
ui.label(format!("Content: {}", event_to_display.content));
ui.label(format!("ID: {}", event_to_display.id().to_string()));
ui.label(format!("Author: {}", event_to_display.pubkey.to_string()));
ui.label(format!("Content: {}", event_to_display.rumor.content));
ui.label(match &event_to_display.rumor.tags.find(nostr::TagKind::Subject) {
Some(s) => match s.content() {
Some(c) => format!("Subject: {}", c.to_string()),
None => "Subject: None".to_string(),
},
None => "Subject: None".to_string(),
});
ui.label(match &event_to_display.rumor.id {
Some(id) => format!("ID: {}", id.to_string()),
None => "ID: None".to_string(),
});
ui.label(format!("Author: {}", event_to_display.sender.to_string()));
}
});
}

View file

@ -1,138 +1,145 @@
use ewebsock::WsMessage;
use ewebsock::{WsMessage, WsEvent};
use nostr::types::Filter;
use nostr::Event;
use serde::de::{SeqAccess, Visitor};
use serde::ser::SerializeSeq;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt::{self};
use crate::error;
/// Messages that are client <- relay.
#[derive(Debug, Clone)]
pub enum RelayMessage {
Event {
subscription_id: String,
event: Event,
},
Ok {
event_id: String,
accepted: bool,
message: String,
},
Eose {
subscription_id: String,
},
Closed {
subscription_id: String,
message: String,
},
Notice {
message: String,
},
#[derive(Debug, Eq, PartialEq)]
pub struct CommandResult<'a> {
event_id: &'a str,
status: bool,
message: &'a str,
}
impl From<WsMessage> for RelayMessage {
fn from(value: WsMessage) -> Self {
#[derive(Debug, Eq, PartialEq)]
pub enum RelayMessage<'a> {
Event(&'a str, &'a str),
OK(CommandResult<'a>),
Eose(&'a str),
Closed(&'a str, &'a str),
Notice(&'a str),
}
#[derive(Debug)]
pub enum RelayEvent<'a> {
Opened,
Closed,
Other(&'a WsMessage),
Error(error::Error),
Message(RelayMessage<'a>)
}
impl<'a> From<&'a WsEvent> for RelayEvent<'a> {
fn from(value: &'a WsEvent) -> Self {
match value {
WsMessage::Text(text) => {
let parsed: RelayMessage = match serde_json::from_str(&text) {
Ok(p) => p,
Err(e) => {
panic!("could not parse message: {}", e);
}
};
parsed
}
_ => {
panic!("Cannot parse anything but text into a RelayMessage");
}
WsEvent::Opened => RelayEvent::Opened,
WsEvent::Closed => RelayEvent::Closed,
WsEvent::Message(ref ws_msg) => ws_msg.into(),
WsEvent::Error(e) => RelayEvent::Error(error::Error::Generic(e.to_owned())),
}
}
}
impl<'de> Deserialize<'de> for RelayMessage {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct RelayMessageVisitor;
impl<'a> From<&'a WsMessage> for RelayEvent<'a> {
fn from(value: &'a WsMessage) -> Self {
match value {
WsMessage::Text(s) => match RelayMessage::from_json(s).map(RelayEvent::Message) {
Ok(msg) => msg,
Err(err) => RelayEvent::Error(err),
},
value => RelayEvent::Other(value),
}
}
}
impl<'de> Visitor<'de> for RelayMessageVisitor {
type Value = RelayMessage;
impl<'a> RelayMessage<'a> {
pub fn eose(subid: &'a str) -> Self {
RelayMessage::Eose(subid)
}
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence starting with 'EVENT' or 'OK'")
pub fn notice(msg: &'a str) -> Self {
RelayMessage::Notice(msg)
}
pub fn ok(event_id: &'a str, status: bool, message: &'a str) -> Self {
RelayMessage::OK(CommandResult {
event_id,
status,
message,
})
}
pub fn event(ev: &'a str, sub_id: &'a str) -> Self {
RelayMessage::Event(sub_id, ev)
}
pub fn from_json(msg: &'a str) -> error::Result<RelayMessage<'a>> {
if msg.is_empty() {
return Err(error::Error::Empty);
}
// Notice
// Relay response format: ["NOTICE", <message>]
if msg.len() >= 12 && &msg[0..=9] == "[\"NOTICE\"," {
// TODO: there could be more than one space, whatever
let start = if msg.as_bytes().get(10).copied() == Some(b' ') {
12
} else {
11
};
let end = msg.len() - 2;
return Ok(Self::notice(&msg[start..end]));
}
// Event
// Relay response format: ["EVENT", <subscription id>, <event JSON>]
if &msg[0..=7] == "[\"EVENT\"" {
let mut start = 9;
while let Some(&b' ') = msg.as_bytes().get(start) {
start += 1; // Move past optional spaces
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let tag: &str = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(0, &self))?;
match tag {
"EVENT" => {
let subscription_id: String = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
let event: Event = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(2, &self))?;
Ok(RelayMessage::Event {
subscription_id,
event,
})
}
"OK" => {
let event_id: String = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
let accepted: bool = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(2, &self))?;
let message: String = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(3, &self))?;
Ok(RelayMessage::Ok {
event_id,
accepted,
message,
})
}
"EOSE" => {
let subscription_id: String = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
Ok(RelayMessage::Eose { subscription_id })
}
"CLOSED" => {
let subscription_id: String = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
let message: String = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(2, &self))?;
Ok(RelayMessage::Closed {
subscription_id,
message,
})
}
"NOTICE" => {
let message: String = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
Ok(RelayMessage::Notice { message })
}
_ => Err(serde::de::Error::invalid_value(
serde::de::Unexpected::Str(tag),
&self,
)),
}
if let Some(comma_index) = msg[start..].find(',') {
let subid_end = start + comma_index;
let subid = &msg[start..subid_end].trim().trim_matches('"');
return Ok(Self::event(msg, subid));
} else {
return Ok(Self::event(msg, "fixme"));
}
}
deserializer.deserialize_seq(RelayMessageVisitor)
// EOSE (NIP-15)
// Relay response format: ["EOSE", <subscription_id>]
if &msg[0..=7] == "[\"EOSE\"," {
let start = if msg.as_bytes().get(8).copied() == Some(b' ') {
10
} else {
9
};
let end = msg.len() - 2;
return Ok(Self::eose(&msg[start..end]));
}
// OK (NIP-20)
// Relay response format: ["OK",<event_id>, <true|false>, <message>]
if &msg[0..=5] == "[\"OK\"," && msg.len() >= 78 {
// TODO: fix this
let event_id = &msg[7..71];
let booly = &msg[73..77];
let status: bool = if booly == "true" {
true
} else if booly == "false" {
false
} else {
return Err(error::Error::DecodeFailed);
};
return Ok(Self::ok(event_id, status, "fixme"));
}
Err(error::Error::DecodeFailed)
}
}