commit e6571d8847bb06b0de97c4b61657276a8ccee5d9
parent b6f5d8dc035c7bd227c8ecf76b89c2beb1812c48
Author: William Casarin <jb55@jb55.com>
Date: Sun, 11 Dec 2022 15:46:18 -0800
initial nostr code
Diffstat:
16 files changed, 1434 insertions(+), 41 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,7 +1,9 @@
.build-result
.buildcmd
-/target
+target
+.git
/dist
.direnv/
+src/camera.rs
*.patch
*.txt
diff --git a/Cargo.lock b/Cargo.lock
@@ -645,7 +645,8 @@ dependencies = [
"egui",
"egui_extras",
"ehttp",
- "ewebsock",
+ "enostr",
+ "ewebsock 0.2.0 (git+https://github.com/jb55/ewebsock.git?rev=93420aa96a990e7513647db775751a2dc9d4a1ba)",
"image",
"log",
"poll-promise",
@@ -654,7 +655,6 @@ dependencies = [
"tracing",
"tracing-subscriber",
"tracing-wasm",
- "wasm-bindgen-futures",
]
[[package]]
@@ -915,6 +915,16 @@ dependencies = [
]
[[package]]
+name = "enostr"
+version = "0.1.0"
+dependencies = [
+ "ewebsock 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde",
+ "serde_derive",
+ "serde_json",
+]
+
+[[package]]
name = "enumset"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -991,6 +1001,24 @@ dependencies = [
]
[[package]]
+name = "ewebsock"
+version = "0.2.0"
+source = "git+https://github.com/jb55/ewebsock.git?rev=93420aa96a990e7513647db775751a2dc9d4a1ba#93420aa96a990e7513647db775751a2dc9d4a1ba"
+dependencies = [
+ "async-stream",
+ "futures",
+ "futures-util",
+ "js-sys",
+ "tokio",
+ "tokio-tungstenite",
+ "tracing",
+ "tungstenite",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+]
+
+[[package]]
name = "expat-sys"
version = "2.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2360,6 +2388,12 @@ dependencies = [
]
[[package]]
+name = "ryu"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
+
+[[package]]
name = "safe_arch"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2438,6 +2472,17 @@ dependencies = [
]
[[package]]
+name = "serde_json"
+version = "1.0.89"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
name = "servo-fontconfig"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
@@ -24,9 +24,10 @@ serde_derive = "1"
serde = { version = "1", features = ["derive"] } # You only need this if you want app persistence
tracing = "0.1.37"
tracing-subscriber = "0.3"
-ewebsock = "0.2.0"
+ewebsock = { git = "https://github.com/jb55/ewebsock.git", rev = "93420aa96a990e7513647db775751a2dc9d4a1ba" }
#wasm-bindgen = "0.2.83"
-wasm-bindgen-futures = "0.4"
+#wasm-bindgen-futures = "0.4"
+enostr = { path = "enostr" }
# web:
diff --git a/enostr/Cargo.lock b/enostr/Cargo.lock
@@ -0,0 +1,808 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "async-stream"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e"
+dependencies = [
+ "async-stream-impl",
+ "futures-core",
+]
+
+[[package]]
+name = "async-stream-impl"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "base64"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+
+[[package]]
+name = "block-buffer"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
+
+[[package]]
+name = "byteorder"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
+
+[[package]]
+name = "bytes"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "crypto-common"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "digest"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f"
+dependencies = [
+ "block-buffer",
+ "crypto-common",
+]
+
+[[package]]
+name = "enostr"
+version = "0.1.0"
+dependencies = [
+ "ewebsock",
+ "serde",
+ "serde_derive",
+ "serde_json",
+]
+
+[[package]]
+name = "ewebsock"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "689197e24a57aee379b3bbef527e70607fc6d4b58fae4f1d98a2c6d91503e230"
+dependencies = [
+ "async-stream",
+ "futures",
+ "futures-util",
+ "js-sys",
+ "tokio",
+ "tokio-tungstenite",
+ "tracing",
+ "tungstenite",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "futures"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
+[[package]]
+name = "futures-core"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "futures-sink"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
+
+[[package]]
+name = "futures-task"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
+
+[[package]]
+name = "futures-util"
+version = "0.3.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
+ "futures-task",
+ "memchr",
+ "pin-project-lite",
+ "pin-utils",
+ "slab",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.14.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
+name = "http"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "httparse"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
+
+[[package]]
+name = "idna"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "itoa"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
+
+[[package]]
+name = "js-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.138"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "mio"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
+
+[[package]]
+name = "percent-encoding"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+
+[[package]]
+name = "pin-utils"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
+
+[[package]]
+name = "ppv-lite86"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rand"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "libc",
+ "rand_chacha",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
+dependencies = [
+ "ppv-lite86",
+ "rand_core",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
+dependencies = [
+ "getrandom",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
+
+[[package]]
+name = "serde"
+version = "1.0.149"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055"
+dependencies = [
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.149"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.89"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
+dependencies = [
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "sha-1"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
+[[package]]
+name = "slab"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "socket2"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.105"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
+
+[[package]]
+name = "tokio"
+version = "1.23.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eab6d665857cc6ca78d6e80303a02cea7a7851e85dfbd77cbdc09bd129f1ef46"
+dependencies = [
+ "autocfg",
+ "bytes",
+ "libc",
+ "memchr",
+ "mio",
+ "pin-project-lite",
+ "socket2",
+ "windows-sys",
+]
+
+[[package]]
+name = "tokio-tungstenite"
+version = "0.17.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181"
+dependencies = [
+ "futures-util",
+ "log",
+ "tokio",
+ "tungstenite",
+]
+
+[[package]]
+name = "tracing"
+version = "0.1.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
+dependencies = [
+ "cfg-if",
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "tungstenite"
+version = "0.17.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0"
+dependencies = [
+ "base64",
+ "byteorder",
+ "bytes",
+ "http",
+ "httparse",
+ "log",
+ "rand",
+ "sha-1",
+ "thiserror",
+ "url",
+ "utf-8",
+]
+
+[[package]]
+name = "typenum"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "url"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+]
+
+[[package]]
+name = "utf-8"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+
+[[package]]
+name = "web-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows-sys"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
diff --git a/enostr/Cargo.toml b/enostr/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "enostr"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+ewebsock = "0.2.0"
+serde_derive = "1"
+serde = { version = "1", features = ["derive"] } # You only need this if you want app persistence
+serde_json = "1.0.89"
diff --git a/enostr/src/error.rs b/enostr/src/error.rs
@@ -0,0 +1,38 @@
+use serde_json;
+
+#[derive(Debug)]
+pub enum Error {
+ MessageEmpty,
+ MessageDecodeFailed,
+ InvalidSignature,
+ Json(serde_json::Error),
+ Generic(String),
+}
+
+impl std::cmp::PartialEq for Error {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (Error::MessageEmpty, Error::MessageEmpty) => true,
+ (Error::MessageDecodeFailed, Error::MessageDecodeFailed) => true,
+ (Error::InvalidSignature, Error::InvalidSignature) => true,
+ // This is slightly wrong but whatevs
+ (Error::Json(..), Error::Json(..)) => true,
+ (Error::Generic(left), Error::Generic(right)) => left == right,
+ _ => false,
+ }
+ }
+}
+
+impl std::cmp::Eq for Error {}
+
+impl From<String> for Error {
+ fn from(s: String) -> Self {
+ Error::Generic(s)
+ }
+}
+
+impl From<serde_json::Error> for Error {
+ fn from(e: serde_json::Error) -> Self {
+ Error::Json(e)
+ }
+}
diff --git a/enostr/src/event.rs b/enostr/src/event.rs
@@ -0,0 +1,73 @@
+use crate::{Error, Result};
+use serde_derive::{Deserialize, Serialize};
+
+/// Event is the struct used to represent a Nostr event
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub struct Event {
+ /// 32-bytes sha256 of the the serialized event data
+ pub id: String,
+ /// 32-bytes hex-encoded public key of the event creator
+ #[serde(rename = "pubkey")]
+ pub pubkey: String,
+ /// unix timestamp in seconds
+ pub created_at: u64,
+ /// integer
+ /// 0: NostrEvent
+ pub kind: u64,
+ /// Tags
+ pub tags: Vec<Vec<String>>,
+ /// arbitrary string
+ pub content: String,
+ /// 64-bytes signature of the sha256 hash of the serialized event data, which is the same as the "id" field
+ pub sig: String,
+}
+
+impl PartialEq for Event {
+ fn eq(&self, other: &Self) -> bool {
+ self.id == other.id
+ }
+}
+
+impl Eq for Event {}
+
+impl Event {
+ pub fn from_json(s: &str) -> Result<Self> {
+ serde_json::from_str(s).map_err(Into::into)
+ }
+
+ pub fn verify(&self) -> Result<Self> {
+ return Err(Error::InvalidSignature);
+ }
+
+ /// This is just for serde sanity checking
+ #[allow(dead_code)]
+ pub(crate) fn new_dummy(
+ id: &str,
+ pubkey: &str,
+ created_at: u64,
+ kind: u64,
+ tags: Vec<Vec<String>>,
+ content: &str,
+ sig: &str,
+ ) -> Result<Self> {
+ let event = Event {
+ id: id.to_string(),
+ pubkey: pubkey.to_string(),
+ created_at,
+ kind,
+ tags,
+ content: content.to_string(),
+ sig: sig.to_string(),
+ };
+
+ event.verify()
+ }
+}
+
+impl std::str::FromStr for Event {
+ type Err = Error;
+
+ fn from_str(s: &str) -> Result<Self> {
+ Event::from_json(s)
+ }
+}
diff --git a/enostr/src/lib.rs b/enostr/src/lib.rs
@@ -0,0 +1,10 @@
+mod error;
+mod event;
+mod relay;
+
+pub use error::Error;
+pub use event::Event;
+pub use relay::pool::RelayPool;
+pub use relay::Relay;
+
+pub type Result<T> = std::result::Result<T, error::Error>;
diff --git a/enostr/src/relay/message.rs b/enostr/src/relay/message.rs
@@ -0,0 +1,283 @@
+use crate::Error;
+use crate::Event;
+use crate::Result;
+use serde_json::Value;
+
+use ewebsock::{WsEvent, WsMessage};
+
+#[derive(Debug, Eq, PartialEq)]
+pub struct CommandResult {
+ event_id: String,
+ status: bool,
+ message: String,
+}
+
+#[derive(Debug, Eq, PartialEq)]
+pub enum RelayMessage {
+ OK(CommandResult),
+ Eose(String),
+ Event(String, Event),
+ Notice(String),
+}
+
+#[derive(Debug)]
+pub enum RelayEvent {
+ Opened,
+ Closed,
+ Other(WsMessage),
+ Message(RelayMessage),
+}
+
+impl TryFrom<WsEvent> for RelayEvent {
+ type Error = Error;
+
+ fn try_from(message: WsEvent) -> Result<Self> {
+ match message {
+ WsEvent::Opened => Ok(RelayEvent::Opened),
+ WsEvent::Closed => Ok(RelayEvent::Closed),
+ WsEvent::Message(ws_msg) => ws_msg.try_into(),
+ WsEvent::Error(s) => Err(s.into()),
+ }
+ }
+}
+
+impl TryFrom<WsMessage> for RelayEvent {
+ type Error = Error;
+
+ fn try_from(wsmsg: WsMessage) -> Result<Self> {
+ match wsmsg {
+ WsMessage::Text(s) => RelayMessage::from_json(&s).map(RelayEvent::Message),
+ wsmsg => Ok(RelayEvent::Other(wsmsg)),
+ }
+ }
+}
+
+impl RelayMessage {
+ pub fn eose(subid: String) -> Self {
+ RelayMessage::Eose(subid)
+ }
+
+ pub fn notice(msg: String) -> Self {
+ RelayMessage::Notice(msg)
+ }
+
+ pub fn ok(event_id: String, status: bool, message: String) -> Self {
+ RelayMessage::OK(CommandResult {
+ event_id: event_id,
+ status,
+ message: message,
+ })
+ }
+
+ pub fn event(ev: Event, sub_id: String) -> Self {
+ RelayMessage::Event(sub_id, ev)
+ }
+
+ // I was lazy and took this from the nostr crate. thx yuki!
+ pub fn from_json(msg: &str) -> Result<Self> {
+ if msg.is_empty() {
+ return Err(Error::MessageEmpty);
+ }
+
+ let v: Vec<Value> = serde_json::from_str(msg).map_err(|_| Error::MessageDecodeFailed)?;
+
+ // Notice
+ // Relay response format: ["NOTICE", <message>]
+ if v[0] == "NOTICE" {
+ if v.len() != 2 {
+ return Err(Error::MessageDecodeFailed);
+ }
+ let v_notice: String =
+ serde_json::from_value(v[1].clone()).map_err(|_| Error::MessageDecodeFailed)?;
+ return Ok(Self::notice(v_notice));
+ }
+
+ // Event
+ // Relay response format: ["EVENT", <subscription id>, <event JSON>]
+ if v[0] == "EVENT" {
+ if v.len() != 3 {
+ return Err(Error::MessageDecodeFailed);
+ }
+
+ let event =
+ Event::from_json(&v[2].to_string()).map_err(|_| Error::MessageDecodeFailed)?;
+
+ let subscription_id: String =
+ serde_json::from_value(v[1].clone()).map_err(|_| Error::MessageDecodeFailed)?;
+
+ return Ok(Self::event(event, subscription_id));
+ }
+
+ // EOSE (NIP-15)
+ // Relay response format: ["EOSE", <subscription_id>]
+ if v[0] == "EOSE" {
+ if v.len() != 2 {
+ return Err(Error::MessageDecodeFailed);
+ }
+
+ let subscription_id: String =
+ serde_json::from_value(v[1].clone()).map_err(|_| Error::MessageDecodeFailed)?;
+
+ return Ok(Self::eose(subscription_id));
+ }
+
+ // OK (NIP-20)
+ // Relay response format: ["OK", <event_id>, <true|false>, <message>]
+ if v[0] == "OK" {
+ if v.len() != 4 {
+ return Err(Error::MessageDecodeFailed);
+ }
+
+ let event_id: String =
+ serde_json::from_value(v[1].clone()).map_err(|_| Error::MessageDecodeFailed)?;
+
+ let status: bool =
+ serde_json::from_value(v[2].clone()).map_err(|_| Error::MessageDecodeFailed)?;
+
+ let message: String =
+ serde_json::from_value(v[3].clone()).map_err(|_| Error::MessageDecodeFailed)?;
+
+ return Ok(Self::ok(event_id, status, message));
+ }
+
+ Err(Error::MessageDecodeFailed)
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_handle_valid_notice() -> Result<()> {
+ let valid_notice_msg = r#"["NOTICE","Invalid event format!"]"#;
+ let handled_valid_notice_msg = RelayMessage::notice("Invalid event format!".to_string());
+
+ assert_eq!(
+ RelayMessage::from_json(valid_notice_msg)?,
+ handled_valid_notice_msg
+ );
+
+ Ok(())
+ }
+ #[test]
+ fn test_handle_invalid_notice() {
+ //Missing content
+ let invalid_notice_msg = r#"["NOTICE"]"#;
+ //The content is not string
+ let invalid_notice_msg_content = r#"["NOTICE": 404]"#;
+
+ assert_eq!(
+ RelayMessage::from_json(invalid_notice_msg).unwrap_err(),
+ Error::MessageDecodeFailed
+ );
+ assert_eq!(
+ RelayMessage::from_json(invalid_notice_msg_content).unwrap_err(),
+ Error::MessageDecodeFailed
+ );
+ }
+
+ #[test]
+ fn test_handle_valid_event() -> Result<()> {
+ let valid_event_msg = r#"["EVENT", "random_string", {"id":"70b10f70c1318967eddf12527799411b1a9780ad9c43858f5e5fcd45486a13a5","pubkey":"379e863e8357163b5bce5d2688dc4f1dcc2d505222fb8d74db600f30535dfdfe","created_at":1612809991,"kind":1,"tags":[],"content":"test","sig":"273a9cd5d11455590f4359500bccb7a89428262b96b3ea87a756b770964472f8c3e87f5d5e64d8d2e859a71462a3f477b554565c4f2f326cb01dd7620db71502"}]"#;
+
+ let id = "70b10f70c1318967eddf12527799411b1a9780ad9c43858f5e5fcd45486a13a5";
+ let pubkey = "379e863e8357163b5bce5d2688dc4f1dcc2d505222fb8d74db600f30535dfdfe";
+ let created_at = 1612809991;
+ let kind = 1;
+ let tags = vec![];
+ let content = "test";
+ let sig = "273a9cd5d11455590f4359500bccb7a89428262b96b3ea87a756b770964472f8c3e87f5d5e64d8d2e859a71462a3f477b554565c4f2f326cb01dd7620db71502";
+
+ let handled_event = Event::new_dummy(id, pubkey, created_at, kind, tags, content, sig);
+
+ assert_eq!(
+ RelayMessage::from_json(valid_event_msg)?,
+ RelayMessage::event(handled_event?, "random_string".to_string())
+ );
+
+ Ok(())
+ }
+
+ #[test]
+ fn test_handle_invalid_event() {
+ //Mising Event field
+ let invalid_event_msg = r#"["EVENT", "random_string"]"#;
+ //Event JSON with incomplete content
+ let invalid_event_msg_content = r#"["EVENT", "random_string", {"id":"70b10f70c1318967eddf12527799411b1a9780ad9c43858f5e5fcd45486a13a5","pubkey":"379e863e8357163b5bce5d2688dc4f1dcc2d505222fb8d74db600f30535dfdfe"}]"#;
+
+ assert_eq!(
+ RelayMessage::from_json(invalid_event_msg).unwrap_err(),
+ Error::MessageDecodeFailed
+ );
+
+ assert_eq!(
+ RelayMessage::from_json(invalid_event_msg_content).unwrap_err(),
+ Error::MessageDecodeFailed
+ );
+ }
+
+ #[test]
+ fn test_handle_valid_eose() -> Result<()> {
+ let valid_eose_msg = r#"["EOSE","random-subscription-id"]"#;
+ let handled_valid_eose_msg = RelayMessage::eose("random-subscription-id".to_string());
+
+ assert_eq!(
+ RelayMessage::from_json(valid_eose_msg)?,
+ handled_valid_eose_msg
+ );
+
+ Ok(())
+ }
+ #[test]
+ fn test_handle_invalid_eose() {
+ // Missing subscription ID
+ assert_eq!(
+ RelayMessage::from_json(r#"["EOSE"]"#).unwrap_err(),
+ Error::MessageDecodeFailed
+ );
+
+ // The subscription ID is not string
+ assert_eq!(
+ RelayMessage::from_json(r#"["EOSE", 404]"#).unwrap_err(),
+ Error::MessageDecodeFailed
+ );
+ }
+
+ #[test]
+ fn test_handle_valid_ok() -> Result<()> {
+ let valid_ok_msg = r#"["OK", "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30", true, "pow: difficulty 25>=24"]"#;
+ let handled_valid_ok_msg = RelayMessage::ok(
+ "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30".to_string(),
+ true,
+ "pow: difficulty 25>=24".into(),
+ );
+
+ assert_eq!(RelayMessage::from_json(valid_ok_msg)?, handled_valid_ok_msg);
+
+ Ok(())
+ }
+ #[test]
+ fn test_handle_invalid_ok() {
+ // Missing params
+ assert_eq!(
+ RelayMessage::from_json(
+ r#"["OK", "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30"]"#
+ )
+ .unwrap_err(),
+ Error::MessageDecodeFailed
+ );
+
+ // Invalid status
+ assert_eq!(
+ RelayMessage::from_json(r#"["OK", "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30", hello, ""]"#).unwrap_err(),
+ Error::MessageDecodeFailed
+ );
+
+ // Invalid message
+ assert_eq!(
+ RelayMessage::from_json(r#"["OK", "b1a649ebe8b435ec71d3784793f3bbf4b93e64e17568a741aecd4c7ddeafce30", hello, 404]"#).unwrap_err(),
+ Error::MessageDecodeFailed
+ );
+ }
+}
diff --git a/enostr/src/relay/mod.rs b/enostr/src/relay/mod.rs
@@ -0,0 +1,60 @@
+use ewebsock::{WsReceiver, WsSender};
+
+use crate::Result;
+use std::fmt;
+use std::hash::{Hash, Hasher};
+
+pub mod message;
+pub mod pool;
+
+#[derive(Debug)]
+pub enum RelayStatus {
+ Connected,
+ Connecting,
+ Disconnected,
+}
+
+pub struct Relay {
+ pub url: String,
+ pub status: RelayStatus,
+ pub sender: WsSender,
+ pub receiver: WsReceiver,
+}
+
+impl fmt::Debug for Relay {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("Relay")
+ .field("url", &self.url)
+ .field("status", &self.status)
+ .finish()
+ }
+}
+
+impl Hash for Relay {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ // Hashes the Relay by hashing the URL
+ self.url.hash(state);
+ }
+}
+
+impl PartialEq for Relay {
+ fn eq(&self, other: &Self) -> bool {
+ self.url == other.url
+ }
+}
+
+impl Eq for Relay {}
+
+impl Relay {
+ pub fn new(url: String) -> Result<Self> {
+ let status = RelayStatus::Connecting;
+ let (sender, receiver) = ewebsock::connect(&url)?;
+
+ Ok(Self {
+ url,
+ sender,
+ receiver,
+ status,
+ })
+ }
+}
diff --git a/enostr/src/relay/pool.rs b/enostr/src/relay/pool.rs
@@ -0,0 +1,62 @@
+use crate::relay::message::RelayEvent;
+use crate::relay::Relay;
+use crate::Result;
+
+#[derive(Debug)]
+pub struct PoolMessage<'a> {
+ relay: &'a str,
+ event: RelayEvent,
+}
+
+pub struct RelayPool {
+ relays: Vec<Relay>,
+}
+
+impl Default for RelayPool {
+ fn default() -> RelayPool {
+ RelayPool { relays: Vec::new() }
+ }
+}
+
+impl RelayPool {
+ // Constructs a new, empty RelayPool.
+ pub fn new(relays: Vec<Relay>) -> RelayPool {
+ RelayPool { relays: relays }
+ }
+
+ pub fn has(&self, url: &str) -> bool {
+ for relay in &self.relays {
+ if &relay.url == url {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Adds a websocket url to the RelayPool.
+ pub fn add_url(&mut self, url: String) -> Result<()> {
+ let relay = Relay::new(url)?;
+
+ self.relays.push(relay);
+
+ Ok(())
+ }
+
+ pub fn try_recv(&self) -> Option<PoolMessage<'_>> {
+ for relay in &self.relays {
+ if let Some(msg) = relay.receiver.try_recv() {
+ if let Ok(event) = msg.try_into() {
+ let pmsg = PoolMessage {
+ event,
+ relay: &relay.url,
+ };
+ return Some(pmsg);
+ }
+ }
+ }
+
+ None
+ }
+
+ pub fn connect() {}
+}
diff --git a/src/app.rs b/src/app.rs
@@ -11,7 +11,7 @@ use std::collections::HashMap;
use std::hash::Hash;
use tracing::debug;
-use crate::Event;
+use enostr::{Event, RelayPool};
#[derive(Hash, Eq, PartialEq, Clone, Debug)]
enum UrlKey<'a> {
@@ -33,6 +33,9 @@ pub struct Damus<'a> {
n_panels: u32,
#[serde(skip)]
+ pool: RelayPool,
+
+ #[serde(skip)]
events: Vec<Event>,
#[serde(skip)]
@@ -49,6 +52,7 @@ impl Default for Damus<'_> {
// Example stuff:
label: "Hello World!".to_owned(),
composing: false,
+ pool: RelayPool::default(),
events: vec![],
img_cache: HashMap::new(),
value: 2.7,
@@ -63,6 +67,10 @@ pub fn is_mobile(ctx: &egui::Context) -> bool {
}
fn damus_update(damus: &mut Damus, ctx: &Context) {
+ render_damus(damus, ctx);
+}
+
+fn render_damus(damus: &mut Damus, ctx: &Context) {
if is_mobile(ctx) {
render_damus_mobile(ctx, damus);
} else {
@@ -185,17 +193,17 @@ fn render_event(ui: &mut egui::Ui, img_cache: &mut ImageCache<'_>, ev: &Event) {
//let damus_pic = "https://192.168.87.26/img/damus.svg".into();
let jb55_pic = "https://cdn.jb55.com/img/red-me.jpg".into();
//let jb55_pic = "http://192.168.87.26/img/red-me.jpg".into();
- let pic =
- if ev.pub_key == "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245" {
- jb55_pic
- } else {
- damus_pic
- };
+ let pic = if ev.pubkey == "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245"
+ {
+ jb55_pic
+ } else {
+ damus_pic
+ };
- render_pfp(ui, img_cache, &ev.pub_key, pic);
+ render_pfp(ui, img_cache, &ev.pubkey, pic);
ui.with_layout(egui::Layout::top_down(egui::Align::LEFT), |ui| {
- render_username(ui, &ev.pub_key);
+ render_username(ui, &ev.pubkey);
ui.label(&ev.content);
})
@@ -300,7 +308,7 @@ fn add_test_events(damus: &mut Damus<'_>) {
let test_event = Event {
id: "6938e3cd841f3111dbdbd909f87fd52c3d1f1e4a07fd121d1243196e532811cb".to_string(),
- pub_key: "f0a6ff7f70b872de6d82c8daec692a433fd23b6a49f25923c6f034df715cdeec".to_string(),
+ pubkey: "f0a6ff7f70b872de6d82c8daec692a433fd23b6a49f25923c6f034df715cdeec".to_string(),
created_at: 1667781968,
kind: 1,
tags: vec![],
@@ -310,7 +318,7 @@ fn add_test_events(damus: &mut Damus<'_>) {
let test_event2 = Event {
id: "6938e3cd841f3111dbdbd909f87fd52c3d1f1e4a07fd121d1243196e532811cb".to_string(),
- pub_key: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245".to_string(),
+ pubkey: "32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245".to_string(),
created_at: 1667781968,
kind: 1,
tags: vec![],
diff --git a/src/bin/main.rs b/src/bin/main.rs
@@ -2,7 +2,6 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
use damus::Damus;
use eframe;
-use log::info;
// Entry point for wasm
//#[cfg(target_arch = "wasm32")]
@@ -41,3 +40,4 @@ pub fn main() {
.expect("failed to start eframe");
});
}
+
diff --git a/src/error.rs b/src/error.rs
@@ -0,0 +1,12 @@
+use enostr;
+
+#[derive(Eq, PartialEq)]
+pub enum Error {
+ Nostr(enostr::Error),
+}
+
+impl From<enostr::Error> for Error {
+ fn from(err: enostr::Error) -> Self {
+ Error::Nostr(err)
+ }
+}
diff --git a/src/event.rs b/src/event.rs
@@ -1,22 +0,0 @@
-use serde_derive::{Deserialize, Serialize};
-
-/// Event is the struct used to represent a Nostr event
-#[derive(Serialize, Deserialize, Debug, Clone)]
-pub struct Event {
- /// 32-bytes sha256 of the the serialized event data
- pub id: String,
- /// 32-bytes hex-encoded public key of the event creator
- #[serde(rename = "pubkey")]
- pub pub_key: String,
- /// unix timestamp in seconds
- pub created_at: u64,
- /// integer
- /// 0: NostrEvent
- pub kind: u8,
- /// Tags
- pub tags: Vec<Vec<String>>,
- /// arbitrary string
- pub content: String,
- /// 64-bytes signature of the sha256 hash of the serialized event data, which is the same as the "id" field
- pub sig: String,
-}
diff --git a/src/lib.rs b/src/lib.rs
@@ -1,9 +1,10 @@
mod app;
//mod camera;
-mod event;
+mod error;
pub use app::Damus;
-pub use event::Event;
+
+pub type Result<T> = std::result::Result<T, error::Error>;
//#[cfg(target_os = "android")]
//use egui_android::run_android;