Cesar Rodas 1 年間 前
コミット
903121f976

+ 205 - 459
Cargo.lock

@@ -3,17 +3,6 @@
 version = 3
 
 [[package]]
-name = "ahash"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
-dependencies = [
- "getrandom",
- "once_cell",
- "version_check",
-]
-
-[[package]]
 name = "aho-corasick"
 version = "0.7.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -32,15 +21,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "atoi"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e"
-dependencies = [
- "num-traits",
-]
-
-[[package]]
 name = "autocfg"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -65,6 +45,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445"
 
 [[package]]
+name = "bindgen"
+version = "0.64.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4243e6031260db77ede97ad86c27e501d646a27ab57b59a574f725d98ab1fb4"
+dependencies = [
+ "bitflags",
+ "cexpr",
+ "clang-sys",
+ "lazy_static",
+ "lazycell",
+ "peeking_take_while",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "rustc-hash",
+ "shlex",
+ "syn 1.0.109",
+]
+
+[[package]]
 name = "bitflags"
 version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -98,10 +98,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be"
 
 [[package]]
+name = "bzip2-sys"
+version = "0.1.11+1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+]
+
+[[package]]
 name = "cc"
 version = "1.0.79"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f"
+dependencies = [
+ "jobserver",
+]
+
+[[package]]
+name = "cexpr"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
+dependencies = [
+ "nom",
+]
 
 [[package]]
 name = "cfg-if"
@@ -125,6 +148,17 @@ dependencies = [
 ]
 
 [[package]]
+name = "clang-sys"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
+dependencies = [
+ "glob",
+ "libc",
+ "libloading",
+]
+
+[[package]]
 name = "codespan-reporting"
 version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -160,40 +194,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "crc"
-version = "3.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe"
-dependencies = [
- "crc-catalog",
-]
-
-[[package]]
-name = "crc-catalog"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484"
-
-[[package]]
-name = "crossbeam-queue"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
-dependencies = [
- "cfg-if",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-utils"
-version = "0.8.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c063cd8cc95f5c377ed0d4b49a4b21f632396ff690e8470c29b3359b346984b"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
 name = "crypto-common"
 version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -264,18 +264,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "dotenvy"
-version = "0.15.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03d8c417d7a8cb362e0c37e5d815f5eb7c37f79ff93707329d5a194e42e54ca0"
-
-[[package]]
-name = "either"
-version = "1.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
-
-[[package]]
 name = "enum_derive"
 version = "0.1.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -316,67 +304,40 @@ dependencies = [
 ]
 
 [[package]]
-name = "event-listener"
-version = "2.5.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
-
-[[package]]
-name = "fastrand"
-version = "1.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
-dependencies = [
- "instant",
-]
-
-[[package]]
-name = "flume"
-version = "0.10.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577"
-dependencies = [
- "futures-core",
- "futures-sink",
- "pin-project",
- "spin 0.9.6",
-]
-
-[[package]]
 name = "fnv"
 version = "1.0.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
 
 [[package]]
-name = "foreign-types"
-version = "0.3.2"
+name = "form_urlencoded"
+version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
 dependencies = [
- "foreign-types-shared",
+ "percent-encoding",
 ]
 
 [[package]]
-name = "foreign-types-shared"
-version = "0.1.1"
+name = "futures"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
-
-[[package]]
-name = "form_urlencoded"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
+checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40"
 dependencies = [
- "percent-encoding",
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
 ]
 
 [[package]]
 name = "futures-channel"
-version = "0.3.27"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "164713a5a0dcc3e7b4b1ed7d3b433cabc18025386f9339346e8daf15963cf7ac"
+checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2"
 dependencies = [
  "futures-core",
  "futures-sink",
@@ -384,15 +345,15 @@ dependencies = [
 
 [[package]]
 name = "futures-core"
-version = "0.3.27"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "86d7a0c1aa76363dac491de0ee99faf6941128376f1cf96f07db7603b7de69dd"
+checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c"
 
 [[package]]
 name = "futures-executor"
-version = "0.3.27"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1997dd9df74cdac935c76252744c1ed5794fac083242ea4fe77ef3ed60ba0f83"
+checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0"
 dependencies = [
  "futures-core",
  "futures-task",
@@ -400,49 +361,47 @@ dependencies = [
 ]
 
 [[package]]
-name = "futures-intrusive"
-version = "0.4.2"
+name = "futures-io"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5"
-dependencies = [
- "futures-core",
- "lock_api",
- "parking_lot 0.11.2",
-]
+checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964"
 
 [[package]]
 name = "futures-macro"
-version = "0.3.27"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6"
+checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 1.0.109",
+ "syn 2.0.12",
 ]
 
 [[package]]
 name = "futures-sink"
-version = "0.3.27"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec93083a4aecafb2a80a885c9de1f0ccae9dbd32c2bb54b0c3a65690e0b8d2f2"
+checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e"
 
 [[package]]
 name = "futures-task"
-version = "0.3.27"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fd65540d33b37b16542a0438c12e6aeead10d4ac5d05bd3f805b8f35ab592879"
+checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65"
 
 [[package]]
 name = "futures-util"
-version = "0.3.27"
+version = "0.3.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ef6b17e481503ec85211fed8f39d1970f128935ca1f814cd32ac4a6842e84ab"
+checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533"
 dependencies = [
+ "futures-channel",
  "futures-core",
+ "futures-io",
  "futures-macro",
  "futures-sink",
  "futures-task",
+ "memchr",
  "pin-project-lite",
  "pin-utils",
  "slab",
@@ -470,31 +429,10 @@ dependencies = [
 ]
 
 [[package]]
-name = "hashbrown"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-dependencies = [
- "ahash",
-]
-
-[[package]]
-name = "hashlink"
-version = "0.8.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "69fe1fcf8b4278d860ad0548329f892a3631fb63f82574df68275f34cdbe0ffa"
-dependencies = [
- "hashbrown",
-]
-
-[[package]]
-name = "heck"
-version = "0.4.1"
+name = "glob"
+version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
-dependencies = [
- "unicode-segmentation",
-]
+checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
 
 [[package]]
 name = "hermit-abi"
@@ -575,25 +513,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "indexmap"
-version = "1.9.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399"
-dependencies = [
- "autocfg",
- "hashbrown",
-]
-
-[[package]]
-name = "instant"
-version = "0.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
-dependencies = [
- "cfg-if",
-]
-
-[[package]]
 name = "io-lifetimes"
 version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -616,21 +535,21 @@ dependencies = [
 ]
 
 [[package]]
-name = "itertools"
-version = "0.10.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
-dependencies = [
- "either",
-]
-
-[[package]]
 name = "itoa"
 version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6"
 
 [[package]]
+name = "jobserver"
+version = "0.1.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "936cfd212a0155903bcbc060e316fb6cc7cbf2e1907329391ebadc1fe0ce77c2"
+dependencies = [
+ "libc",
+]
+
+[[package]]
 name = "js-sys"
 version = "0.3.61"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -646,16 +565,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
+name = "lazycell"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
+
+[[package]]
 name = "libc"
 version = "0.2.139"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
 
 [[package]]
-name = "libsqlite3-sys"
-version = "0.24.2"
+name = "libloading"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
+dependencies = [
+ "cfg-if",
+ "winapi",
+]
+
+[[package]]
+name = "librocksdb-sys"
+version = "0.10.0+7.9.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fe4d5874f5ff2bc616e55e8c6086d478fcda13faf9495768a4aa1c22042d30b"
+dependencies = [
+ "bindgen",
+ "bzip2-sys",
+ "cc",
+ "glob",
+ "libc",
+ "libz-sys",
+ "lz4-sys",
+ "zstd-sys",
+]
+
+[[package]]
+name = "libz-sys"
+version = "1.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14"
+checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf"
 dependencies = [
  "cc",
  "pkg-config",
@@ -697,6 +648,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "lz4-sys"
+version = "1.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900"
+dependencies = [
+ "cc",
+ "libc",
+]
+
+[[package]]
 name = "memchr"
 version = "2.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -721,24 +682,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "native-tls"
-version = "0.2.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e"
-dependencies = [
- "lazy_static",
- "libc",
- "log",
- "openssl",
- "openssl-probe",
- "openssl-sys",
- "schannel",
- "security-framework",
- "security-framework-sys",
- "tempfile",
-]
-
-[[package]]
 name = "nom"
 version = "7.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -753,12 +696,13 @@ name = "nostr"
 version = "0.1.0"
 dependencies = [
  "env_logger",
+ "futures",
  "futures-util",
+ "log",
  "nostr-rs-client",
+ "nostr-rs-storage",
  "nostr-rs-types",
- "parking_lot 0.12.1",
  "serde_json",
- "sqlx",
  "thiserror",
  "tokio",
 ]
@@ -767,9 +711,11 @@ dependencies = [
 name = "nostr-rs-client"
 version = "0.1.0"
 dependencies = [
+ "futures",
  "futures-util",
+ "log",
  "nostr-rs-types",
- "parking_lot 0.12.1",
+ "parking_lot",
  "serde_json",
  "thiserror",
  "tokio",
@@ -778,6 +724,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "nostr-rs-storage"
+version = "0.1.0"
+dependencies = [
+ "nostr-rs-types",
+ "rocksdb",
+ "serde_json",
+ "thiserror",
+]
+
+[[package]]
 name = "nostr-rs-types"
 version = "0.1.0"
 dependencies = [
@@ -831,83 +787,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
 
 [[package]]
-name = "openssl"
-version = "0.10.47"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d8b277f87dacc05a6b709965d1cbafac4649d6ce9f3ce9ceb88508b5666dfec9"
-dependencies = [
- "bitflags",
- "cfg-if",
- "foreign-types",
- "libc",
- "once_cell",
- "openssl-macros",
- "openssl-sys",
-]
-
-[[package]]
-name = "openssl-macros"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
-[[package]]
 name = "openssl-probe"
 version = "0.1.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
 
 [[package]]
-name = "openssl-sys"
-version = "0.9.82"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a95792af3c4e0153c3914df2261bedd30a98476f94dc892b67dfe1d89d433a04"
-dependencies = [
- "autocfg",
- "cc",
- "libc",
- "pkg-config",
- "vcpkg",
-]
-
-[[package]]
-name = "parking_lot"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
-dependencies = [
- "instant",
- "lock_api",
- "parking_lot_core 0.8.6",
-]
-
-[[package]]
 name = "parking_lot"
 version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
 dependencies = [
  "lock_api",
- "parking_lot_core 0.9.7",
-]
-
-[[package]]
-name = "parking_lot_core"
-version = "0.8.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc"
-dependencies = [
- "cfg-if",
- "instant",
- "libc",
- "redox_syscall",
- "smallvec",
- "winapi",
+ "parking_lot_core",
 ]
 
 [[package]]
@@ -924,10 +816,10 @@ dependencies = [
 ]
 
 [[package]]
-name = "paste"
-version = "1.0.12"
+name = "peeking_take_while"
+version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79"
+checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
 
 [[package]]
 name = "percent-encoding"
@@ -936,26 +828,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
 
 [[package]]
-name = "pin-project"
-version = "1.0.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc"
-dependencies = [
- "pin-project-internal",
-]
-
-[[package]]
-name = "pin-project-internal"
-version = "1.0.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
-[[package]]
 name = "pin-project-lite"
 version = "0.2.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1062,13 +934,30 @@ dependencies = [
  "cc",
  "libc",
  "once_cell",
- "spin 0.5.2",
+ "spin",
  "untrusted",
  "web-sys",
  "winapi",
 ]
 
 [[package]]
+name = "rocksdb"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "015439787fce1e75d55f279078d33ff14b4af5d93d995e8838ee4631301c8a99"
+dependencies = [
+ "libc",
+ "librocksdb-sys",
+ "serde",
+]
+
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
 name = "rustix"
 version = "0.36.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1247,6 +1136,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "shlex"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3"
+
+[[package]]
 name = "signal-hook-registry"
 version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1287,120 +1182,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
 
 [[package]]
-name = "spin"
-version = "0.9.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5d6e0250b93c8427a177b849d144a96d5acc57006149479403d7861ab721e34"
-dependencies = [
- "lock_api",
-]
-
-[[package]]
-name = "sqlformat"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c12bc9199d1db8234678b7051747c07f517cdcf019262d1847b94ec8b1aee3e"
-dependencies = [
- "itertools",
- "nom",
- "unicode_categories",
-]
-
-[[package]]
-name = "sqlx"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9249290c05928352f71c077cc44a464d880c63f26f7534728cca008e135c0428"
-dependencies = [
- "sqlx-core",
- "sqlx-macros",
-]
-
-[[package]]
-name = "sqlx-core"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dcbc16ddba161afc99e14d1713a453747a2b07fc097d2009f4c300ec99286105"
-dependencies = [
- "ahash",
- "atoi",
- "bitflags",
- "byteorder",
- "bytes",
- "crc",
- "crossbeam-queue",
- "dotenvy",
- "either",
- "event-listener",
- "flume",
- "futures-channel",
- "futures-core",
- "futures-executor",
- "futures-intrusive",
- "futures-util",
- "hashlink",
- "hex",
- "indexmap",
- "itoa",
- "libc",
- "libsqlite3-sys",
- "log",
- "memchr",
- "once_cell",
- "paste",
- "percent-encoding",
- "sha2",
- "smallvec",
- "sqlformat",
- "sqlx-rt",
- "stringprep",
- "thiserror",
- "tokio-stream",
- "url",
-]
-
-[[package]]
-name = "sqlx-macros"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b850fa514dc11f2ee85be9d055c512aa866746adfacd1cb42d867d68e6a5b0d9"
-dependencies = [
- "dotenvy",
- "either",
- "heck",
- "once_cell",
- "proc-macro2",
- "quote",
- "sha2",
- "sqlx-core",
- "sqlx-rt",
- "syn 1.0.109",
- "url",
-]
-
-[[package]]
-name = "sqlx-rt"
-version = "0.6.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "24c5b2d25fa654cc5f841750b8e1cdedbe21189bf9a9382ee90bfa9dd3562396"
-dependencies = [
- "native-tls",
- "once_cell",
- "tokio",
- "tokio-native-tls",
-]
-
-[[package]]
-name = "stringprep"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ee348cb74b87454fff4b551cbf727025810a004f88aeacae7f85b87f4e9a1c1"
-dependencies = [
- "unicode-bidi",
- "unicode-normalization",
-]
-
-[[package]]
 name = "syn"
 version = "1.0.109"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1413,9 +1194,9 @@ dependencies = [
 
 [[package]]
 name = "syn"
-version = "2.0.3"
+version = "2.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8234ae35e70582bfa0f1fedffa6daa248e41dd045310b19800c4a36382c8f60"
+checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1423,19 +1204,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "tempfile"
-version = "3.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af18f7ae1acd354b992402e9ec5864359d693cd8a79dcbef59f76891701c1e95"
-dependencies = [
- "cfg-if",
- "fastrand",
- "redox_syscall",
- "rustix",
- "windows-sys 0.42.0",
-]
-
-[[package]]
 name = "termcolor"
 version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1461,7 +1229,7 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f"
 dependencies = [
  "proc-macro2",
  "quote",
- "syn 2.0.3",
+ "syn 2.0.12",
 ]
 
 [[package]]
@@ -1502,7 +1270,7 @@ dependencies = [
  "memchr",
  "mio",
  "num_cpus",
- "parking_lot 0.12.1",
+ "parking_lot",
  "pin-project-lite",
  "signal-hook-registry",
  "socket2",
@@ -1522,16 +1290,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "tokio-native-tls"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
-dependencies = [
- "native-tls",
- "tokio",
-]
-
-[[package]]
 name = "tokio-rustls"
 version = "0.23.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1543,17 +1301,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "tokio-stream"
-version = "0.1.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8fb52b74f05dbf495a8fba459fdc331812b96aa086d9eb78101fa0d4569c3313"
-dependencies = [
- "futures-core",
- "pin-project-lite",
- "tokio",
-]
-
-[[package]]
 name = "tokio-tungstenite"
 version = "0.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1618,24 +1365,12 @@ dependencies = [
 ]
 
 [[package]]
-name = "unicode-segmentation"
-version = "1.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36"
-
-[[package]]
 name = "unicode-width"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
 
 [[package]]
-name = "unicode_categories"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
-
-[[package]]
 name = "untrusted"
 version = "0.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1867,3 +1602,14 @@ name = "windows_x86_64_msvc"
 version = "0.42.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
+
+[[package]]
+name = "zstd-sys"
+version = "2.0.7+zstd.1.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "94509c3ba2fe55294d752b79842c530ccfab760192521df74a081a78d2b3c7f5"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+]

+ 5 - 3
Cargo.toml

@@ -6,16 +6,18 @@ edition = "2021"
 [workspace]
 members = [
     "crates/types",
-    "crates/client"
+    "crates/client",
+    "crates/storage"
 ]
 
 [dependencies]
 nostr-rs-types = { path = "crates/types" }
 nostr-rs-client = { path = "crates/client" }
+nostr-rs-storage = { path = "crates/storage" }
 tokio = { version = "1.26.0", features = ["full"] }
 env_logger = "0.10.0"
 serde_json = "1.0.94"
-sqlx = { version = "0.6.2", features = ["sqlite", "runtime-tokio-native-tls"] }
 futures-util = "0.3.27"
+log = "0.4.17"
 thiserror = "1.0.40"
-parking_lot = "0.12.1"
+futures = "0.3.28"

+ 3 - 1
crates/client/Cargo.toml

@@ -6,9 +6,11 @@ edition = "2021"
 [dependencies]
 thiserror = "1.0.40"
 nostr-rs-types = { path = "../types" }
-tokio = { version = "1.26.0", features = ["sync", "macros", "rt"] }
+tokio = { version = "1.26.0", features = ["sync", "macros", "rt", "time"] }
 tokio-tungstenite = { version = "0.18.0", features = ["rustls", "rustls-native-certs", "rustls-tls-native-roots"] }
 url = "2.3.1"
 serde_json = "1.0.94"
 futures-util = "0.3.27"
 parking_lot = "0.12.1"
+log = "0.4.17"
+futures = "0.3.28"

+ 148 - 0
crates/client/src/client.rs

@@ -0,0 +1,148 @@
+use crate::Error;
+use futures::Future;
+use futures_util::{SinkExt, StreamExt};
+use nostr_rs_types::{Request, Response};
+use std::pin::Pin;
+use tokio::{
+    sync::{broadcast, mpsc, oneshot},
+    time::{sleep, Duration},
+};
+use tokio_tungstenite::{connect_async, tungstenite::Message};
+use url::Url;
+
+#[derive(Debug)]
+pub struct Client {
+    pub url: String,
+
+    pub send_to_socket: mpsc::Sender<Request>,
+
+    recv_from_socket: broadcast::Receiver<(Response, String)>,
+    stop_service: oneshot::Sender<()>,
+}
+
+impl Client {
+    pub fn new<F>(url: &str, on_connection: Option<F>) -> Result<Self, Error>
+    where
+        F: (Fn(mpsc::Sender<Request>) -> Pin<Box<dyn Future<Output = ()> + Send>>)
+            + Send
+            + Sync
+            + 'static,
+    {
+        let (send_to_socket, receiver) = mpsc::channel(100_000);
+        let (recv_from_socket, stop_service) =
+            Self::spawn_background_client(send_to_socket.clone(), receiver, url, on_connection)?;
+
+        Ok(Self {
+            url: url.to_owned(),
+            send_to_socket,
+            stop_service,
+            recv_from_socket,
+        })
+    }
+
+    fn spawn_background_client<F>(
+        send_to_socket: mpsc::Sender<Request>,
+        mut receiver: mpsc::Receiver<Request>,
+        url_str: &str,
+        on_connection: Option<F>,
+    ) -> Result<(broadcast::Receiver<(Response, String)>, oneshot::Sender<()>), Error>
+    where
+        F: (Fn(mpsc::Sender<Request>) -> Pin<Box<dyn Future<Output = ()> + Send>>)
+            + Send
+            + Sync
+            + 'static,
+    {
+        let (publish_to_listener, recv_from_socket) = broadcast::channel(10_000);
+        let (stop_service, mut stopper_recv) = oneshot::channel();
+
+        let url = url_str.to_owned();
+        let url_parsed = Url::parse(&url)?;
+
+        tokio::spawn(async move {
+            let mut reconnect = true;
+            let mut retries: usize = 0;
+            while reconnect && retries <= 10 {
+                log::warn!("{}: Connect attempt {}", url, retries);
+                retries += 1;
+                let mut socket = if let Ok(x) = connect_async(url_parsed.clone()).await {
+                    x.0
+                } else {
+                    log::warn!("{}: Failed to connect", url);
+                    sleep(Duration::from_secs(5)).await;
+                    continue;
+                };
+
+                log::info!("Connected to {}", url);
+
+                if let Some(on_connection) = &on_connection {
+                    on_connection(send_to_socket.clone()).await;
+                }
+
+                loop {
+                    tokio::select! {
+                        Ok(()) = &mut stopper_recv => {
+                            log::warn!("{}: Breaking client due external signal", url);
+                            reconnect = false;
+                            break;
+                        },
+                        Some(msg) = receiver.recv() => {
+                            if let Ok(json) = serde_json::to_string(&msg) {
+                                log::info!("{}: Sending {}", url, json);
+                                if let Err(x) = socket.send(Message::Text(json)).await {
+                                    log::error!("{} :Reconnecting due {}", url, x);
+                                    break;
+
+                                }
+                            }
+                        }
+                        Some(Ok(msg)) = socket.next() => {
+                            let msg =if let Ok(msg) = msg.into_text() {
+                                    msg
+                                } else {
+                                    continue;
+                                };
+
+                            if msg.is_empty() {
+                                continue;
+                            }
+
+                            log::info!("New message: {}", msg);
+
+                            let msg: Result<Response, _> = serde_json::from_str(&msg);
+
+                            if let Ok(msg) = msg {
+                                if let Err(error) = publish_to_listener.send((msg, url.to_owned())) {
+                                    log::error!("{}: Reconnecting client because of {}", url, error);
+                                    break;
+                                }
+                            }
+                        }
+                        else => {
+                            log::warn!("{}: else", url);
+                        }
+                    }
+                }
+            }
+
+            log::warn!("{}: Disconnected", url);
+        });
+
+        Ok((recv_from_socket, stop_service))
+    }
+
+    pub fn is_running(&self) -> bool {
+        !self.stop_service.is_closed()
+    }
+
+    pub fn subscribe(&self) -> broadcast::Receiver<(Response, String)> {
+        self.recv_from_socket.resubscribe()
+    }
+
+    pub async fn send(&self, request: Request) -> Result<(), Error> {
+        Ok(self.send_to_socket.send(request).await?)
+    }
+
+    pub async fn stop(self) {
+        let _ = self.stop_service.send(());
+    }
+}

+ 15 - 0
crates/client/src/error.rs

@@ -0,0 +1,15 @@
+use nostr_rs_types::Request;
+use tokio::sync::mpsc::error::SendError;
+use tokio_tungstenite::tungstenite::error::Error as TungsteniteError;
+
+#[derive(thiserror::Error, Debug)]
+pub enum Error {
+    #[error("Url: {0}")]
+    Url(#[from] url::ParseError),
+
+    #[error("Tungstenite: {0}")]
+    Tungstenite(#[from] TungsteniteError),
+
+    #[error("Sync: {0}")]
+    Sync(#[from] SendError<Request>),
+}

+ 18 - 149
crates/client/src/lib.rs

@@ -1,152 +1,14 @@
-use futures_util::{stream::FuturesUnordered, SinkExt, StreamExt};
-use nostr_rs_types::{client::Subscribe, Request, Response};
+use futures::Future;
+use futures_util::{stream::FuturesUnordered, StreamExt};
+use nostr_rs_types::{Request, Response};
 use parking_lot::RwLock;
-use std::{collections::HashMap, sync::Arc};
-use tokio::{
-    sync::{
-        broadcast,
-        mpsc::{self, error::SendError},
-        oneshot,
-    },
-    time::{sleep, Duration},
-};
-use tokio_tungstenite::{
-    connect_async, tungstenite::error::Error as TungsteniteError, tungstenite::Message,
-};
-use url::Url;
+use std::{collections::HashMap, pin::Pin, sync::Arc};
+use tokio::sync::mpsc;
 
-#[derive(thiserror::Error, Debug)]
-pub enum Error {
-    #[error("Url: {0}")]
-    Url(#[from] url::ParseError),
+mod client;
+mod error;
 
-    #[error("Tungstenite: {0}")]
-    Tungstenite(#[from] TungsteniteError),
-
-    #[error("Sync: {0}")]
-    Sync(#[from] SendError<Request>),
-}
-
-#[derive(Debug)]
-pub struct Client {
-    pub url: String,
-
-    pub send_to_socket: mpsc::Sender<Request>,
-
-    recv_from_socket: broadcast::Receiver<(Response, String)>,
-    stop_service: oneshot::Sender<()>,
-}
-
-impl Client {
-    pub fn new(url: &str) -> Result<Self, Error> {
-        let (send_to_socket, receiver) = mpsc::channel(10_000);
-        let (recv_from_socket, stop_service) = Self::spawn(receiver, url)?;
-
-        Ok(Self {
-            url: url.to_owned(),
-            send_to_socket,
-            stop_service,
-            recv_from_socket,
-        })
-    }
-
-    fn spawn(
-        mut receiver: mpsc::Receiver<Request>,
-        url_str: &str,
-    ) -> Result<(broadcast::Receiver<(Response, String)>, oneshot::Sender<()>), Error> {
-        let (publish_to_listener, recv_from_socket) = broadcast::channel(10_000);
-        let (stop_service, mut stopper_recv) = oneshot::channel();
-
-        let url = url_str.to_owned();
-        let url_parsed = Url::parse(&url)?;
-
-        tokio::spawn(async move {
-            let mut reconnect = true;
-            let mut retries: usize = 0;
-            while reconnect && retries <= 10 {
-                println!("{}: Connect attempt {}", url, retries);
-                retries += 1;
-                let mut socket = if let Ok(x) = connect_async(url_parsed.clone()).await {
-                    x.0
-                } else {
-                    println!("{}: Failed to connect", url);
-                    sleep(Duration::from_secs(5)).await;
-                    continue;
-                };
-
-                let request: Request = Subscribe::default().into();
-                if let Ok(json) = serde_json::to_string(&request) {
-                    if let Err(err) = socket.send(Message::Text(json)).await {
-                        println!("{}: Failed to send request {}", url, err);
-                        continue;
-                    }
-                }
-
-                loop {
-                    tokio::select! {
-                        Ok(()) = &mut stopper_recv => {
-                            println!("{}: Breaking client due external signal", url);
-                            reconnect = false;
-                            break;
-                        },
-                        Some(msg) = receiver.recv() => {
-                            if let Ok(json) = serde_json::to_string(&msg) {
-                                if let Err(x) = socket.send(Message::Text(json)).await {
-                                    println!("{} :Reconnecting due {}", url, x);
-                                    break;
-
-                                }
-                            }
-                        }
-                        Some(Ok(msg)) = socket.next() => {
-                            let msg =if let Ok(msg) = msg.into_text() {
-                                    msg
-                                } else {
-                                    continue;
-                                };
-
-                            if msg.is_empty() {
-                                continue;
-                            }
-
-                            let msg: Result<Response, _> = serde_json::from_str(&msg);
-
-                            if let Ok(msg) = msg {
-                                if let Err(error) = publish_to_listener.send((msg, url.to_owned())) {
-                                    println!("{}: Reconnecting client because of {}", url, error);
-                                    break;
-                                }
-                            }
-                        }
-                        else => {
-                            println!("{}: else", url);
-                        }
-                    }
-                }
-            }
-
-            println!("{}: Disconnected", url);
-        });
-
-        Ok((recv_from_socket, stop_service))
-    }
-
-    pub fn is_running(&self) -> bool {
-        !self.stop_service.is_closed()
-    }
-
-    pub fn subscribe(&self) -> broadcast::Receiver<(Response, String)> {
-        self.recv_from_socket.resubscribe()
-    }
-
-    pub async fn send(&self, request: Request) -> Result<(), Error> {
-        Ok(self.send_to_socket.send(request).await?)
-    }
-
-    pub async fn stop(self) {
-        let _ = self.stop_service.send(());
-    }
-}
+pub use self::{client::Client, error::Error};
 
 #[derive(Debug, Clone)]
 pub struct Clients {
@@ -182,6 +44,7 @@ impl Clients {
             None
         }
     }
+
     pub fn try_recv(&self) -> Option<(Response, String)> {
         let mut subscriptions = self
             .clients
@@ -226,13 +89,19 @@ impl Clients {
         }
     }
 
-    pub async fn connect_to(&self, url: &str) -> Result<bool, Error> {
+    pub async fn connect_to<F>(&self, url: &str, on_connection: Option<F>) -> Result<bool, Error>
+    where
+        F: (Fn(mpsc::Sender<Request>) -> Pin<Box<dyn Future<Output = ()> + Send>>)
+            + Send
+            + Sync
+            + 'static,
+    {
         let mut clients = self.clients.write();
         Ok(if clients.get(url).is_some() {
             false
         } else {
-            println!("Connecting to {}", url);
-            clients.insert(url.to_owned(), Client::new(url)?);
+            log::warn!("Connecting to {}", url);
+            clients.insert(url.to_owned(), Client::new(url, on_connection)?);
             true
         })
     }

+ 8 - 3
crates/types/src/types/addr.rs

@@ -4,13 +4,12 @@
 //!
 //! It can also parse the bech32 version of the public key if provided (used by
 //! clients mostly)
-use std::{hash::Hash, ops::Deref};
-
 use bech32::{self, FromBase32, ToBase32, Variant};
 use serde::{
     de::{self, Deserialize, Deserializer},
     ser::{self, Serializer},
 };
+use std::{hash::Hash, ops::Deref};
 use thiserror::Error;
 
 /// Errors
@@ -60,7 +59,7 @@ impl ToString for HumanReadablePart {
 ///
 /// Clients may want to use the Bech32 encoded address *but* the protocol only
 /// cares about hex-encoded binary data.
-#[derive(Debug, Clone, PartialEq, Eq)]
+#[derive(Debug, Clone, Eq)]
 pub struct Addr {
     /// Bytes (up to 32 bytes)
     pub bytes: Vec<u8>,
@@ -81,6 +80,12 @@ impl Deref for Addr {
     }
 }
 
+impl PartialEq for Addr {
+    fn eq(&self, other: &Self) -> bool {
+        self.bytes.eq(&other.bytes)
+    }
+}
+
 impl Hash for Addr {
     fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
         self.bytes.hash(state)

+ 1 - 1
crates/types/src/types/id.rs

@@ -49,7 +49,7 @@ impl<'de> Deserialize<'de> for Id {
         D: Deserializer<'de>,
     {
         let s = <String>::deserialize(deserializer)?;
-        s.try_into().map_err(|e| de::Error::custom(e))
+        s.try_into().map_err(de::Error::custom)
     }
 }
 

+ 9 - 1
crates/types/src/types/kind.rs

@@ -13,7 +13,7 @@ use serde::{
 /// Any unsupported Kind will be wrapped under the Unknown type
 ///
 /// The Kind is represented as a u32 on the wire
-#[derive(Debug, PartialEq, PartialOrd, Eq, Clone, Copy)]
+#[derive(Debug, PartialEq, Eq, Clone, Copy)]
 pub enum Kind {
     /// Metadata
     ///
@@ -50,6 +50,14 @@ pub enum Kind {
     Unknown(u32),
 }
 
+impl PartialOrd for Kind {
+    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+        let kind_id: u32 = (*self).into();
+        let other_kind_id: u32 = (*other).into();
+        kind_id.partial_cmp(&other_kind_id)
+    }
+}
+
 impl Ord for Kind {
     fn cmp(&self, other: &Self) -> std::cmp::Ordering {
         let kind_id: u32 = (*self).into();

+ 16 - 466
src/main.rs

@@ -1,37 +1,12 @@
+use futures::Future;
 use nostr_rs_client::{Clients, Error as ClientError};
-use nostr_rs_types::{
-    client::{Close, Subscribe},
-    types::{Addr, Content, Event, Filter, Kind, SubscriptionId, Tag},
-    Response,
-};
-use parking_lot::RwLock;
-use sqlx::{query, FromRow, Pool, Sqlite, SqlitePool};
-use std::{collections::HashMap, sync::Arc};
-use tokio::time::{sleep, Duration};
-
-#[derive(Clone, FromRow, Debug)]
-struct ToFetch {
-    pub id: String,
-    pub typ: i64,
-}
-
-#[derive(Clone, FromRow, Debug)]
-struct Relayer {
-    pub id: i64,
-    pub url: String,
-}
-
-#[derive(Clone, FromRow, Debug)]
-struct RawValue {
-    pub id: String,
-    pub event: String,
-}
+use nostr_rs_storage::Db;
+use nostr_rs_types::{client::Subscribe, Request, Response};
+use std::pin::Pin;
+use tokio::sync::mpsc;
 
 #[derive(Debug, thiserror::Error)]
 pub enum Error {
-    #[error("Sql: {0}")]
-    Sql(#[from] sqlx::Error),
-
     #[error("Nostr: {0}")]
     Addr(#[from] nostr_rs_types::types::addr::Error),
 
@@ -39,453 +14,28 @@ pub enum Error {
     Client(#[from] ClientError),
 }
 
-async fn discover_relayers(conn: Pool<Sqlite>) -> Result<(), Error> {
-    let mut tx = conn.begin().await?;
-    let values = sqlx::query_as::<_, RawValue>(
-        r#"SELECT id, event FROM events WHERE processed = 1 LIMIT 10000"#,
-    )
-    .fetch_all(&mut tx)
-    .await?;
-
-    let mut relayers: HashMap<String, u64> = HashMap::new();
-
-    for value in values {
-        let event: Result<Event, _> = serde_json::from_str(&value.event);
-        match event {
-            Ok(event) => {
-                match event.content() {
-                    Content::Contacts(x) => x
-                        .iter()
-                        .map(|(relayer, _)| {
-                            let relayer = relayer.to_ascii_lowercase();
-                            if !relayer.is_empty() {
-                                if relayers.get_mut(&relayer).map(|x| *x += 1).is_none() {
-                                    relayers.insert(relayer, 1);
-                                }
-                            }
-                        })
-                        .for_each(drop),
-                    _ => {}
-                }
-                for tag in event.inner.tags.iter() {
-                    match tag {
-                        Tag::PubKey(pubkey) => {
-                            if let Some(relayer) = pubkey.relayer_url.as_ref() {
-                                let relayer = relayer.to_ascii_lowercase();
-                                if !relayer.is_empty() {
-                                    if relayers.get_mut(&relayer).map(|x| *x += 1).is_none() {
-                                        relayers.insert(relayer, 1);
-                                    }
-                                }
-                            }
-                        }
-                        Tag::Event(tag) => {
-                            if let Some(relayer) = tag.relayer_url.as_ref() {
-                                let relayer = relayer.to_ascii_lowercase();
-                                if !relayer.is_empty() {
-                                    if relayers.get_mut(&relayer).map(|x| *x += 1).is_none() {
-                                        relayers.insert(relayer, 1);
-                                    }
-                                }
-                            }
-                        }
-                        _ => {}
-                    }
-                }
-            }
-            _ => {}
-        }
-
-        sqlx::query("UPDATE events SET processed = 2 WHERE id = ?")
-            .bind(&value.id)
-            .execute(&mut tx)
-            .await?;
-    }
-
-    for (url, weight) in relayers.iter() {
-        let _ = sqlx::query(
-            r#"
-            INSERT INTO relayers (url, weight) values(?, 0)
-            "#,
-        )
-        .bind(url)
-        .execute(&mut tx)
-        .await;
-
-        let _ = sqlx::query(
-            r#"
-            UPDATE relayers SET weight = weight + ? WHERE url = ?
-            "#,
-        )
-        .bind(weight.to_string())
-        .bind(url)
-        .execute(&mut tx)
-        .await;
-    }
-
-    tx.commit().await?;
-    Ok(())
-}
-
-async fn process_events(conn: Pool<Sqlite>) -> Result<(), Error> {
-    let mut tx = conn.begin().await?;
-    let values = sqlx::query_as::<_, RawValue>(
-        r#"SELECT id, event FROM events WHERE processed = 0 LIMIT 10000"#,
-    )
-    .fetch_all(&mut tx)
-    .await?;
-
-    for value in values {
-        let event: Result<Event, _> = serde_json::from_str(&value.event);
-        match event {
-            Ok(event) => {
-                for tag in event.inner.tags.iter() {
-                    match tag {
-                        Tag::PubKey(pubkey) => {
-                            let _ = sqlx::query("INSERT INTO relationships (source_id, relates_to, type) values(?, ?, 2)")
-                                .bind(&value.id)
-                                .bind(pubkey.id.to_hex())
-                                .execute(&mut tx)
-                                .await;
-                        }
-                        Tag::Event(tag) => {
-                            let _ = sqlx::query("INSERT INTO relationships (source_id, relates_to, type) values(?, ?, 1)")
-                                .bind(&value.id)
-                                .bind(tag.id.to_hex())
-                                .execute(&mut tx)
-                                .await;
-                        }
-                        _ => {}
-                    }
-                }
-            }
-            _ => {}
-        }
-
-        sqlx::query("UPDATE events SET processed = 1 WHERE id = ?")
-            .bind(&value.id)
-            .execute(&mut tx)
-            .await?;
-    }
-
-    tx.commit().await?;
-    Ok(())
-}
-
-async fn fetch_related_content(clients: Clients, conn: Pool<Sqlite>) -> Result<(), Error> {
-    let mut tx = conn.begin().await?;
-    sqlx::query(r#"DELETE FROM to_fetch"#)
-        .execute(&mut tx)
-        .await?;
-
-    println!("Building to_fetch table...");
-
-    sqlx::query(
-        r#"
-    INSERT INTO to_fetch SELECT * FROM (
-        SELECT
-            relates_to,
-            count(*) total,
-            1
-        FROM
-            relationships
-        WHERE type = 1 AND relates_to NOT IN (SELECT id FROM events)
-        GROUP BY relates_to
-    ) s ORDER by total DESC
-    "#,
-    )
-    .execute(&mut tx)
-    .await?;
-
-    sqlx::query(
-        r#"
-        INSERT INTO to_fetch SELECT * FROM (
-            SELECT
-                relates_to,
-                count(*) total,
-                2
-            FROM
-                relationships
-            WHERE
-                type = 2
-                AND relates_to NOT IN (SELECT public_key FROM events WHERE kind = 0)
-                AND relates_to NOT IN (SELECT id FROM to_fetch)
-            GROUP BY relates_to
-        ) s ORDER by total DESC
-        "#,
-    )
-    .execute(&mut tx)
-    .await?;
-
-    tx.commit().await?;
-
-    loop {
-        let data_to_fetch = if let Ok(q) = sqlx::query_as::<_, ToFetch>(
-            r#"
-        SELECT
-            id,
-            type as typ
-        FROM
-            to_fetch
-        ORDER BY refs DESC
-        LIMIT 40
-        "#,
-        )
-        .fetch_all(&conn)
-        .await
-        {
-            q
-        } else {
-            println!("Database locked, retrying...");
-            sleep(Duration::from_secs(1)).await;
-            continue;
-        };
-
-        let mut public_keys = vec![];
-        let mut ids = vec![];
-
-        for to_fetch in data_to_fetch.into_iter() {
-            if to_fetch.id.len() < 64 {
-                continue;
-            }
-
-            let id: Addr = if let Ok(x) = to_fetch.id.try_into() {
-                x
-            } else {
-                continue;
-            };
-
-            match to_fetch.typ {
-                1 => {
-                    ids.push(id);
-                }
-                2 => {
-                    public_keys.push(id);
-                }
-                _ => {}
-            }
-        }
-
-        let mut filters = vec![];
-
-        if !ids.is_empty() {
-            filters.push(Filter {
-                ids: ids,
-                ..Default::default()
-            });
-        }
-
-        if !public_keys.is_empty() {
-            filters.push(Filter {
-                authors: public_keys,
-                kinds: vec![
-                    Kind::Metadata,
-                    Kind::ShortTextNote,
-                    Kind::Contacts,
-                    Kind::Repost,
-                    Kind::Reaction,
-                    Kind::ZapRequest,
-                    Kind::Zap,
-                ],
-                ..Default::default()
-            });
-        }
-
-        if filters.is_empty() {
-            break;
-        }
-
-        let subscription_id = SubscriptionId::default();
-        println!("{} Fetching from related content", &*subscription_id,);
-
-        clients
-            .send(
-                Subscribe {
-                    subscription_id: subscription_id.clone(),
-                    filters,
-                    ..Default::default()
-                }
-                .into(),
-            )
-            .await;
-
-        sleep(Duration::from_millis(15_000)).await;
-
-        println!("{} Unsubscribing from related content", &*subscription_id);
-
-        let _ = clients.send(Close(subscription_id).into()).await;
-
-        let _ = sqlx::query("DELETE FROM to_fetch WHERE id IN (SELECT id FROM to_fetch ORDER BY refs DESC LIMIT 40)")
-            .execute(&conn)
-            .await;
-    }
-
-    Ok(())
+fn on_connection(socket: mpsc::Sender<Request>) -> Pin<Box<dyn Future<Output = ()> + Send>> {
+    Box::pin(async move {
+        log::info!("Connected to relay, subscribing to all events");
+        let _ = socket.send(Subscribe::default().into()).await;
+    })
 }
 
 #[tokio::main]
 async fn main() {
     env_logger::init();
-    let conn = SqlitePool::connect("sqlite://./db.sqlite").await.unwrap();
     let clients = Clients::default();
 
-    let _ = query(
-        r#"
-    CREATE TABLE events(
-        id varchar(64) not null primary key,
-        public_key varchar(64) not null,
-        kind int,
-        event text,
-        discovered_at datetime,
-        discovered_by int,
-        created_at datetime,
-        processed INT DEFAULT 0
-    );
-    CREATE INDEX events_processed_index ON events (processed);
-    CREATE INDEX events_public_key_index ON events (public_key, kind);
-    CREATE INDEX events_kind_index ON events (kind);
-    CREATE TABLE relationships (
-        id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
-        source_id VARCHAR(64) NOT NULL,
-        relates_to VARCHAR(64) NOT NULL,
-        type INT
-    );
-    CREATE INDEX relationships_source_id_index ON relationships (source_id);
-    CREATE TABLE relayers (
-        id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
-        url VARCHAR(64) NOT NULL,
-        weight INT NOT NULL DEFAULT '0'
-    );
-    CREATE UNIQUE INDEX url ON relayers (url);
-    CREATE INDEX relayers_weight_index ON relayers (weight);
-    CREATE TABLE to_fetch(id varchar(64) not null primary key, refs int not null default 0, type int not null default 1);
-    CREATE INDEX refs ON to_fetch (refs);
-    "#,
-    )
-    .execute(&conn)
-    .await;
-
-    let clients_for_worker = clients.clone();
-    let conn_for_worker = conn.clone();
-    tokio::spawn(async move {
-        sleep(Duration::from_millis(35_000)).await;
-        loop {
-            let r1 =
-                fetch_related_content(clients_for_worker.clone(), conn_for_worker.clone()).await;
-            println!("Fetch related content {:?}", r1);
-            sleep(Duration::from_millis(5_000)).await
-        }
-    });
-
-    let conn_for_worker = conn.clone();
-    tokio::spawn(async move {
-        sleep(Duration::from_millis(55_000)).await;
-        loop {
-            let r1 = process_events(conn_for_worker.clone()).await;
-            let r2 = discover_relayers(conn_for_worker.clone()).await;
-            println!("Processed events {:?} {:?}", r1, r2);
-            sleep(Duration::from_millis(5_000)).await;
-        }
-    });
-
-    let clients_for_worker = clients.clone();
-    tokio::spawn(async move {
-        loop {
-            sleep(Duration::from_millis(5_000)).await;
-            println!(
-                "Active connections: {}",
-                clients_for_worker.check_active_connections()
-            );
-        }
-    });
-
-    let queue = Arc::new(RwLock::new(HashMap::<String, (Event, i64)>::new()));
-    let conn_for_queue = conn.clone();
-    let queue_for_worker = queue.clone();
-
-    tokio::spawn(async move {
-        loop {
-            let to_persist = { queue_for_worker.read().clone() };
-
-            if let Ok(mut tx) = conn_for_queue.begin().await {
-                println!("Persisting {}", to_persist.len());
-                let mut skip: u64 = 0;
-                let mut processed: u64 = 0;
-                for (_, (event, relayer_id)) in to_persist.iter() {
-                    if let Ok(Some(_)) = query(r#"SELECT id FROM events WHERE id = ?"#)
-                        .bind(event.id.to_string())
-                        .fetch_optional(&mut tx)
-                        .await
-                    {
-                        skip += 1;
-                        continue;
-                    }
-                    let kind: u32 = event.inner.kind.into();
-                    let created_at = event.inner.created_at.to_rfc3339();
-                    let _ = query(
-                        r#"
-                        INSERT INTO events(id, public_key, kind, event, discovered_by, discovered_at, created_at)
-                        VALUES(?, ?, ?, ?, ?, strftime('%Y-%m-%d %H:%M:%S','now'), ?)
-                        "#,
-                    )
-                    .bind(event.id.to_string())
-                    .bind(event.inner.public_key.to_string())
-                    .bind(kind.to_string())
-                    .bind(serde_json::to_string(&event).unwrap())
-                    .bind(relayer_id)
-                    .bind(created_at)
-                    .execute(&mut tx)
-                    .await;
-                    processed += 1;
-                }
-                if let Ok(_) = tx.commit().await {
-                    let mut queue = queue_for_worker.write();
-                    for (id, _) in to_persist.iter() {
-                        queue.remove(id);
-                    }
-                    println!(
-                        "Persisted {}, skip = {} and (queue new size is {})",
-                        processed,
-                        skip,
-                        queue.len()
-                    );
-                }
-            }
-
-            sleep(Duration::from_millis(60_000)).await;
-        }
-    });
-
-    let relayers = sqlx::query_as::<_, Relayer>(
-        r#"select id, url from relayers where url like 'wss://%.%/' order by weight desc limit 30"#,
-    )
-    .fetch_all(&conn)
-    .await
-    .expect("query")
-    .iter()
-    .map(|r| (r.url.clone(), r.id))
-    .collect::<HashMap<String, i64>>();
-
-    for (relayer, _) in relayers.iter() {
-        let _ = clients.connect_to(&relayer).await;
-    }
-
+    let _ = clients
+        .connect_to("wss://relay.damus.io/", Some(on_connection))
+        .await;
+    let db = Db::new("./db").expect("db");
     loop {
-        if let Some((msg, relayed_by)) = clients.recv().await {
+        if let Some((msg, _relayed_by)) = clients.recv().await {
             if let Response::Event(x) = msg {
                 let event = x.event;
-                let id = event.id.to_string();
-                let mut q = queue.write();
 
-                if !q.contains_key(&id) {
-                    q.insert(
-                        id,
-                        (
-                            event,
-                            relayers.get(&relayed_by).cloned().unwrap_or_default(),
-                        ),
-                    );
-                }
+                let _ = db.store(&event);
             }
         }
     }