diff options
| -rw-r--r-- | Cargo.lock | 179 | ||||
| -rw-r--r-- | Cargo.toml | 11 | ||||
| -rw-r--r-- | src/bin/git_remote_nostr/fetch.rs | 2 | ||||
| -rw-r--r-- | src/bin/git_remote_nostr/main.rs | 4 | ||||
| -rw-r--r-- | src/bin/git_remote_nostr/push.rs | 17 | ||||
| -rw-r--r-- | src/bin/ngit/sub_commands/init.rs | 21 | ||||
| -rw-r--r-- | src/bin/ngit/sub_commands/send.rs | 8 | ||||
| -rw-r--r-- | src/lib/client.rs | 223 | ||||
| -rw-r--r-- | src/lib/git/mod.rs | 2 | ||||
| -rw-r--r-- | src/lib/git/nostr_url.rs | 150 | ||||
| -rw-r--r-- | src/lib/git_events.rs | 42 | ||||
| -rw-r--r-- | src/lib/login/existing.rs | 2 | ||||
| -rw-r--r-- | src/lib/login/fresh.rs | 2 | ||||
| -rw-r--r-- | src/lib/login/key_encryption.rs | 2 | ||||
| -rw-r--r-- | src/lib/login/mod.rs | 4 | ||||
| -rw-r--r-- | src/lib/repo_ref.rs | 103 | ||||
| -rw-r--r-- | test_utils/Cargo.toml | 8 | ||||
| -rw-r--r-- | test_utils/src/git.rs | 12 | ||||
| -rw-r--r-- | test_utils/src/lib.rs | 54 | ||||
| -rw-r--r-- | test_utils/src/relay.rs | 27 | ||||
| -rw-r--r-- | tests/git_remote_nostr/main.rs | 12 | ||||
| -rw-r--r-- | tests/ngit_init.rs | 12 | ||||
| -rw-r--r-- | tests/ngit_list.rs | 15 |
23 files changed, 474 insertions, 438 deletions
| @@ -48,12 +48,6 @@ dependencies = [ | |||
| 48 | ] | 48 | ] |
| 49 | 49 | ||
| 50 | [[package]] | 50 | [[package]] |
| 51 | name = "allocator-api2" | ||
| 52 | version = "0.2.21" | ||
| 53 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 54 | checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" | ||
| 55 | |||
| 56 | [[package]] | ||
| 57 | name = "anstream" | 51 | name = "anstream" |
| 58 | version = "0.6.18" | 52 | version = "0.6.18" |
| 59 | source = "registry+https://github.com/rust-lang/crates.io-index" | 53 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -302,9 +296,9 @@ dependencies = [ | |||
| 302 | 296 | ||
| 303 | [[package]] | 297 | [[package]] |
| 304 | name = "async-utility" | 298 | name = "async-utility" |
| 305 | version = "0.2.0" | 299 | version = "0.3.1" |
| 306 | source = "registry+https://github.com/rust-lang/crates.io-index" | 300 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 307 | checksum = "a349201d80b4aa18d17a34a182bdd7f8ddf845e9e57d2ea130a12e10ef1e3a47" | 301 | checksum = "a34a3b57207a7a1007832416c3e4862378c8451b4e8e093e436f48c2d3d2c151" |
| 308 | dependencies = [ | 302 | dependencies = [ |
| 309 | "futures-util", | 303 | "futures-util", |
| 310 | "gloo-timers", | 304 | "gloo-timers", |
| @@ -314,9 +308,9 @@ dependencies = [ | |||
| 314 | 308 | ||
| 315 | [[package]] | 309 | [[package]] |
| 316 | name = "async-wsocket" | 310 | name = "async-wsocket" |
| 317 | version = "0.10.1" | 311 | version = "0.13.1" |
| 318 | source = "registry+https://github.com/rust-lang/crates.io-index" | 312 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 319 | checksum = "8d50cb541e6d09e119e717c64c46ed33f49be7fa592fa805d56c11d6a7ff093c" | 313 | checksum = "9a7d8c7d34a225ba919dd9ba44d4b9106d20142da545e086be8ae21d1897e043" |
| 320 | dependencies = [ | 314 | dependencies = [ |
| 321 | "async-utility", | 315 | "async-utility", |
| 322 | "futures", | 316 | "futures", |
| @@ -325,7 +319,7 @@ dependencies = [ | |||
| 325 | "tokio", | 319 | "tokio", |
| 326 | "tokio-rustls", | 320 | "tokio-rustls", |
| 327 | "tokio-socks", | 321 | "tokio-socks", |
| 328 | "tokio-tungstenite 0.24.0", | 322 | "tokio-tungstenite 0.26.2", |
| 329 | "url", | 323 | "url", |
| 330 | "wasm-bindgen", | 324 | "wasm-bindgen", |
| 331 | "web-sys", | 325 | "web-sys", |
| @@ -333,12 +327,9 @@ dependencies = [ | |||
| 333 | 327 | ||
| 334 | [[package]] | 328 | [[package]] |
| 335 | name = "atomic-destructor" | 329 | name = "atomic-destructor" |
| 336 | version = "0.2.0" | 330 | version = "0.3.0" |
| 337 | source = "registry+https://github.com/rust-lang/crates.io-index" | 331 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 338 | checksum = "7d919cb60ba95c87ba42777e9e246c4e8d658057299b437b7512531ce0a09a23" | 332 | checksum = "ef49f5882e4b6afaac09ad239a4f8c70a24b8f2b0897edb1f706008efd109cf4" |
| 339 | dependencies = [ | ||
| 340 | "tracing", | ||
| 341 | ] | ||
| 342 | 333 | ||
| 343 | [[package]] | 334 | [[package]] |
| 344 | name = "atomic-waker" | 335 | name = "atomic-waker" |
| @@ -379,16 +370,6 @@ dependencies = [ | |||
| 379 | ] | 370 | ] |
| 380 | 371 | ||
| 381 | [[package]] | 372 | [[package]] |
| 382 | name = "base58ck" | ||
| 383 | version = "0.1.0" | ||
| 384 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 385 | checksum = "2c8d66485a3a2ea485c1913c4572ce0256067a5377ac8c75c4960e1cda98605f" | ||
| 386 | dependencies = [ | ||
| 387 | "bitcoin-internals 0.3.0", | ||
| 388 | "bitcoin_hashes 0.14.0", | ||
| 389 | ] | ||
| 390 | |||
| 391 | [[package]] | ||
| 392 | name = "base64" | 373 | name = "base64" |
| 393 | version = "0.22.1" | 374 | version = "0.22.1" |
| 394 | source = "registry+https://github.com/rust-lang/crates.io-index" | 375 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -418,61 +399,24 @@ dependencies = [ | |||
| 418 | ] | 399 | ] |
| 419 | 400 | ||
| 420 | [[package]] | 401 | [[package]] |
| 421 | name = "bitcoin" | ||
| 422 | version = "0.32.5" | ||
| 423 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 424 | checksum = "ce6bc65742dea50536e35ad42492b234c27904a27f0abdcbce605015cb4ea026" | ||
| 425 | dependencies = [ | ||
| 426 | "base58ck", | ||
| 427 | "bech32", | ||
| 428 | "bitcoin-internals 0.3.0", | ||
| 429 | "bitcoin-io", | ||
| 430 | "bitcoin-units", | ||
| 431 | "bitcoin_hashes 0.14.0", | ||
| 432 | "hex-conservative 0.2.1", | ||
| 433 | "hex_lit", | ||
| 434 | "secp256k1", | ||
| 435 | "serde", | ||
| 436 | ] | ||
| 437 | |||
| 438 | [[package]] | ||
| 439 | name = "bitcoin-internals" | 402 | name = "bitcoin-internals" |
| 440 | version = "0.2.0" | 403 | version = "0.2.0" |
| 441 | source = "registry+https://github.com/rust-lang/crates.io-index" | 404 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 442 | checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" | 405 | checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" |
| 443 | 406 | ||
| 444 | [[package]] | 407 | [[package]] |
| 445 | name = "bitcoin-internals" | ||
| 446 | version = "0.3.0" | ||
| 447 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 448 | checksum = "30bdbe14aa07b06e6cfeffc529a1f099e5fbe249524f8125358604df99a4bed2" | ||
| 449 | dependencies = [ | ||
| 450 | "serde", | ||
| 451 | ] | ||
| 452 | |||
| 453 | [[package]] | ||
| 454 | name = "bitcoin-io" | 408 | name = "bitcoin-io" |
| 455 | version = "0.1.3" | 409 | version = "0.1.3" |
| 456 | source = "registry+https://github.com/rust-lang/crates.io-index" | 410 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 457 | checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" | 411 | checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf" |
| 458 | 412 | ||
| 459 | [[package]] | 413 | [[package]] |
| 460 | name = "bitcoin-units" | ||
| 461 | version = "0.1.2" | ||
| 462 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 463 | checksum = "5285c8bcaa25876d07f37e3d30c303f2609179716e11d688f51e8f1fe70063e2" | ||
| 464 | dependencies = [ | ||
| 465 | "bitcoin-internals 0.3.0", | ||
| 466 | "serde", | ||
| 467 | ] | ||
| 468 | |||
| 469 | [[package]] | ||
| 470 | name = "bitcoin_hashes" | 414 | name = "bitcoin_hashes" |
| 471 | version = "0.13.0" | 415 | version = "0.13.0" |
| 472 | source = "registry+https://github.com/rust-lang/crates.io-index" | 416 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 473 | checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" | 417 | checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" |
| 474 | dependencies = [ | 418 | dependencies = [ |
| 475 | "bitcoin-internals 0.2.0", | 419 | "bitcoin-internals", |
| 476 | "hex-conservative 0.1.2", | 420 | "hex-conservative 0.1.2", |
| 477 | ] | 421 | ] |
| 478 | 422 | ||
| @@ -1038,12 +982,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
| 1038 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" | 982 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" |
| 1039 | 983 | ||
| 1040 | [[package]] | 984 | [[package]] |
| 1041 | name = "foldhash" | ||
| 1042 | version = "0.1.5" | ||
| 1043 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1044 | checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" | ||
| 1045 | |||
| 1046 | [[package]] | ||
| 1047 | name = "form_urlencoded" | 985 | name = "form_urlencoded" |
| 1048 | version = "1.2.1" | 986 | version = "1.2.1" |
| 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" | 987 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1235,9 +1173,9 @@ dependencies = [ | |||
| 1235 | 1173 | ||
| 1236 | [[package]] | 1174 | [[package]] |
| 1237 | name = "gloo-timers" | 1175 | name = "gloo-timers" |
| 1238 | version = "0.2.6" | 1176 | version = "0.3.0" |
| 1239 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1177 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1240 | checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" | 1178 | checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" |
| 1241 | dependencies = [ | 1179 | dependencies = [ |
| 1242 | "futures-channel", | 1180 | "futures-channel", |
| 1243 | "futures-core", | 1181 | "futures-core", |
| @@ -1256,11 +1194,6 @@ name = "hashbrown" | |||
| 1256 | version = "0.15.2" | 1194 | version = "0.15.2" |
| 1257 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1195 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1258 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" | 1196 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" |
| 1259 | dependencies = [ | ||
| 1260 | "allocator-api2", | ||
| 1261 | "equivalent", | ||
| 1262 | "foldhash", | ||
| 1263 | ] | ||
| 1264 | 1197 | ||
| 1265 | [[package]] | 1198 | [[package]] |
| 1266 | name = "heck" | 1199 | name = "heck" |
| @@ -1342,12 +1275,6 @@ dependencies = [ | |||
| 1342 | ] | 1275 | ] |
| 1343 | 1276 | ||
| 1344 | [[package]] | 1277 | [[package]] |
| 1345 | name = "hex_lit" | ||
| 1346 | version = "0.1.1" | ||
| 1347 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 1348 | checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" | ||
| 1349 | |||
| 1350 | [[package]] | ||
| 1351 | name = "hkdf" | 1278 | name = "hkdf" |
| 1352 | version = "0.12.4" | 1279 | version = "0.12.4" |
| 1353 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1280 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -1852,12 +1779,9 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" | |||
| 1852 | 1779 | ||
| 1853 | [[package]] | 1780 | [[package]] |
| 1854 | name = "lru" | 1781 | name = "lru" |
| 1855 | version = "0.12.5" | 1782 | version = "0.13.0" |
| 1856 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1783 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1857 | checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" | 1784 | checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" |
| 1858 | dependencies = [ | ||
| 1859 | "hashbrown 0.15.2", | ||
| 1860 | ] | ||
| 1861 | 1785 | ||
| 1862 | [[package]] | 1786 | [[package]] |
| 1863 | name = "memchr" | 1787 | name = "memchr" |
| @@ -1953,9 +1877,9 @@ checksum = "e664971378a3987224f7a0e10059782035e89899ae403718ee07de85bec42afe" | |||
| 1953 | 1877 | ||
| 1954 | [[package]] | 1878 | [[package]] |
| 1955 | name = "negentropy" | 1879 | name = "negentropy" |
| 1956 | version = "0.4.3" | 1880 | version = "0.5.0" |
| 1957 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1881 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 1958 | checksum = "43a88da9dd148bbcdce323dd6ac47d369b4769d4a3b78c6c52389b9269f77932" | 1882 | checksum = "f0efe882e02d206d8d279c20eb40e03baf7cb5136a1476dc084a324fbc3ec42d" |
| 1959 | 1883 | ||
| 1960 | [[package]] | 1884 | [[package]] |
| 1961 | name = "ngit" | 1885 | name = "ngit" |
| @@ -1980,6 +1904,7 @@ dependencies = [ | |||
| 1980 | "nostr-connect", | 1904 | "nostr-connect", |
| 1981 | "nostr-database", | 1905 | "nostr-database", |
| 1982 | "nostr-lmdb", | 1906 | "nostr-lmdb", |
| 1907 | "nostr-relay-pool", | ||
| 1983 | "nostr-sdk", | 1908 | "nostr-sdk", |
| 1984 | "once_cell", | 1909 | "once_cell", |
| 1985 | "passwords", | 1910 | "passwords", |
| @@ -2026,26 +1951,24 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" | |||
| 2026 | 1951 | ||
| 2027 | [[package]] | 1952 | [[package]] |
| 2028 | name = "nostr" | 1953 | name = "nostr" |
| 2029 | version = "0.37.0" | 1954 | version = "0.40.0" |
| 2030 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1955 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2031 | checksum = "8aad4b767bbed24ac5eb4465bfb83bc1210522eb99d67cf4e547ec2ec7e47786" | 1956 | checksum = "2f900ddcdc28395759fcd44b18a03255e7deee8858551bfe5d5d5a07311d82ea" |
| 2032 | dependencies = [ | 1957 | dependencies = [ |
| 2033 | "aes", | 1958 | "aes", |
| 2034 | "async-trait", | ||
| 2035 | "base64", | 1959 | "base64", |
| 2036 | "bech32", | 1960 | "bech32", |
| 2037 | "bip39", | 1961 | "bip39", |
| 2038 | "bitcoin", | 1962 | "bitcoin_hashes 0.14.0", |
| 2039 | "cbc", | 1963 | "cbc", |
| 2040 | "chacha20", | 1964 | "chacha20", |
| 2041 | "chacha20poly1305", | 1965 | "chacha20poly1305", |
| 2042 | "getrandom 0.2.15", | 1966 | "getrandom 0.2.15", |
| 2043 | "instant", | 1967 | "instant", |
| 2044 | "negentropy 0.3.1", | 1968 | "regex", |
| 2045 | "negentropy 0.4.3", | ||
| 2046 | "once_cell", | ||
| 2047 | "reqwest", | 1969 | "reqwest", |
| 2048 | "scrypt", | 1970 | "scrypt", |
| 1971 | "secp256k1", | ||
| 2049 | "serde", | 1972 | "serde", |
| 2050 | "serde_json", | 1973 | "serde_json", |
| 2051 | "unicode-normalization", | 1974 | "unicode-normalization", |
| @@ -2054,79 +1977,71 @@ dependencies = [ | |||
| 2054 | 1977 | ||
| 2055 | [[package]] | 1978 | [[package]] |
| 2056 | name = "nostr-connect" | 1979 | name = "nostr-connect" |
| 2057 | version = "0.37.0" | 1980 | version = "0.40.0" |
| 2058 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1981 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2059 | checksum = "5b1bf2a6324d2c1739be462e83d27caa2c025fd7ca14b401b4bc4b7cac11d382" | 1982 | checksum = "52a0479b5f2da48ddd36061281bc2b3738610a287ad485aae397c44c148b3c6d" |
| 2060 | dependencies = [ | 1983 | dependencies = [ |
| 2061 | "async-trait", | ||
| 2062 | "async-utility", | 1984 | "async-utility", |
| 2063 | "nostr", | 1985 | "nostr", |
| 2064 | "nostr-relay-pool", | 1986 | "nostr-relay-pool", |
| 2065 | "thiserror 1.0.69", | ||
| 2066 | "tokio", | 1987 | "tokio", |
| 2067 | "tracing", | 1988 | "tracing", |
| 2068 | ] | 1989 | ] |
| 2069 | 1990 | ||
| 2070 | [[package]] | 1991 | [[package]] |
| 2071 | name = "nostr-database" | 1992 | name = "nostr-database" |
| 2072 | version = "0.37.0" | 1993 | version = "0.40.0" |
| 2073 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1994 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2074 | checksum = "23696338d51e45cd44e061823847f4b0d1d362eca80d5033facf9c184149f72f" | 1995 | checksum = "714512e4653f4e7c4f4abb50a0ac82257541b22087dee780b9e3d787276e88d4" |
| 2075 | dependencies = [ | 1996 | dependencies = [ |
| 2076 | "async-trait", | ||
| 2077 | "flatbuffers", | 1997 | "flatbuffers", |
| 2078 | "lru", | 1998 | "lru", |
| 2079 | "nostr", | 1999 | "nostr", |
| 2080 | "thiserror 1.0.69", | ||
| 2081 | "tokio", | 2000 | "tokio", |
| 2082 | "tracing", | ||
| 2083 | ] | 2001 | ] |
| 2084 | 2002 | ||
| 2085 | [[package]] | 2003 | [[package]] |
| 2086 | name = "nostr-lmdb" | 2004 | name = "nostr-lmdb" |
| 2087 | version = "0.37.0" | 2005 | version = "0.40.0" |
| 2088 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2006 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2089 | checksum = "70c97ff4e384735527af2dc74b6c8f0042f02daea476bad6c7bb56be32739250" | 2007 | checksum = "0ca52683835f416e5d4699f19eb616a622de54b75adb954430b1190e94f4e5ca" |
| 2090 | dependencies = [ | 2008 | dependencies = [ |
| 2009 | "async-utility", | ||
| 2091 | "heed", | 2010 | "heed", |
| 2092 | "nostr", | 2011 | "nostr", |
| 2093 | "nostr-database", | 2012 | "nostr-database", |
| 2094 | "thiserror 1.0.69", | ||
| 2095 | "tokio", | 2013 | "tokio", |
| 2096 | "tracing", | 2014 | "tracing", |
| 2097 | ] | 2015 | ] |
| 2098 | 2016 | ||
| 2099 | [[package]] | 2017 | [[package]] |
| 2100 | name = "nostr-relay-pool" | 2018 | name = "nostr-relay-pool" |
| 2101 | version = "0.37.0" | 2019 | version = "0.40.1" |
| 2102 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2020 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2103 | checksum = "15fcc6e3f0ca54d0fc779009bc5f2684cea9147be3b6aa68a7d301ea590f95f5" | 2021 | checksum = "5bde07a729e0a1b306c9a07da81a0d1d55d0487316017090906f3b6660741b8d" |
| 2104 | dependencies = [ | 2022 | dependencies = [ |
| 2105 | "async-utility", | 2023 | "async-utility", |
| 2106 | "async-wsocket", | 2024 | "async-wsocket", |
| 2107 | "atomic-destructor", | 2025 | "atomic-destructor", |
| 2026 | "lru", | ||
| 2108 | "negentropy 0.3.1", | 2027 | "negentropy 0.3.1", |
| 2109 | "negentropy 0.4.3", | 2028 | "negentropy 0.5.0", |
| 2110 | "nostr", | 2029 | "nostr", |
| 2111 | "nostr-database", | 2030 | "nostr-database", |
| 2112 | "thiserror 1.0.69", | ||
| 2113 | "tokio", | 2031 | "tokio", |
| 2114 | "tokio-stream", | ||
| 2115 | "tracing", | 2032 | "tracing", |
| 2116 | ] | 2033 | ] |
| 2117 | 2034 | ||
| 2118 | [[package]] | 2035 | [[package]] |
| 2119 | name = "nostr-sdk" | 2036 | name = "nostr-sdk" |
| 2120 | version = "0.37.0" | 2037 | version = "0.40.0" |
| 2121 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2038 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 2122 | checksum = "491221fc89b1aa189a0de640127127d68b4e7c5c1d44371b04d9a6d10694b5af" | 2039 | checksum = "26238eee805d7dc3abcc8d570068c81cb4285b08e9db4d7999e54e20748c472e" |
| 2123 | dependencies = [ | 2040 | dependencies = [ |
| 2124 | "async-utility", | 2041 | "async-utility", |
| 2125 | "atomic-destructor", | ||
| 2126 | "nostr", | 2042 | "nostr", |
| 2127 | "nostr-database", | 2043 | "nostr-database", |
| 2128 | "nostr-relay-pool", | 2044 | "nostr-relay-pool", |
| 2129 | "thiserror 1.0.69", | ||
| 2130 | "tokio", | 2045 | "tokio", |
| 2131 | "tracing", | 2046 | "tracing", |
| 2132 | ] | 2047 | ] |
| @@ -3023,7 +2938,6 @@ version = "0.29.1" | |||
| 3023 | source = "registry+https://github.com/rust-lang/crates.io-index" | 2938 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 3024 | checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" | 2939 | checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" |
| 3025 | dependencies = [ | 2940 | dependencies = [ |
| 3026 | "bitcoin_hashes 0.14.0", | ||
| 3027 | "rand 0.8.5", | 2941 | "rand 0.8.5", |
| 3028 | "secp256k1-sys", | 2942 | "secp256k1-sys", |
| 3029 | "serde", | 2943 | "serde", |
| @@ -3112,7 +3026,6 @@ version = "1.0.140" | |||
| 3112 | source = "registry+https://github.com/rust-lang/crates.io-index" | 3026 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 3113 | checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" | 3027 | checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" |
| 3114 | dependencies = [ | 3028 | dependencies = [ |
| 3115 | "indexmap", | ||
| 3116 | "itoa", | 3029 | "itoa", |
| 3117 | "memchr", | 3030 | "memchr", |
| 3118 | "ryu", | 3031 | "ryu", |
| @@ -3538,17 +3451,6 @@ dependencies = [ | |||
| 3538 | ] | 3451 | ] |
| 3539 | 3452 | ||
| 3540 | [[package]] | 3453 | [[package]] |
| 3541 | name = "tokio-stream" | ||
| 3542 | version = "0.1.17" | ||
| 3543 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
| 3544 | checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" | ||
| 3545 | dependencies = [ | ||
| 3546 | "futures-core", | ||
| 3547 | "pin-project-lite", | ||
| 3548 | "tokio", | ||
| 3549 | ] | ||
| 3550 | |||
| 3551 | [[package]] | ||
| 3552 | name = "tokio-tungstenite" | 3454 | name = "tokio-tungstenite" |
| 3553 | version = "0.20.1" | 3455 | version = "0.20.1" |
| 3554 | source = "registry+https://github.com/rust-lang/crates.io-index" | 3456 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -3562,9 +3464,9 @@ dependencies = [ | |||
| 3562 | 3464 | ||
| 3563 | [[package]] | 3465 | [[package]] |
| 3564 | name = "tokio-tungstenite" | 3466 | name = "tokio-tungstenite" |
| 3565 | version = "0.24.0" | 3467 | version = "0.26.2" |
| 3566 | source = "registry+https://github.com/rust-lang/crates.io-index" | 3468 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 3567 | checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" | 3469 | checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" |
| 3568 | dependencies = [ | 3470 | dependencies = [ |
| 3569 | "futures-util", | 3471 | "futures-util", |
| 3570 | "log", | 3472 | "log", |
| @@ -3572,7 +3474,7 @@ dependencies = [ | |||
| 3572 | "rustls-pki-types", | 3474 | "rustls-pki-types", |
| 3573 | "tokio", | 3475 | "tokio", |
| 3574 | "tokio-rustls", | 3476 | "tokio-rustls", |
| 3575 | "tungstenite 0.24.0", | 3477 | "tungstenite 0.26.2", |
| 3576 | "webpki-roots", | 3478 | "webpki-roots", |
| 3577 | ] | 3479 | ] |
| 3578 | 3480 | ||
| @@ -3678,21 +3580,20 @@ dependencies = [ | |||
| 3678 | 3580 | ||
| 3679 | [[package]] | 3581 | [[package]] |
| 3680 | name = "tungstenite" | 3582 | name = "tungstenite" |
| 3681 | version = "0.24.0" | 3583 | version = "0.26.2" |
| 3682 | source = "registry+https://github.com/rust-lang/crates.io-index" | 3584 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 3683 | checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" | 3585 | checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" |
| 3684 | dependencies = [ | 3586 | dependencies = [ |
| 3685 | "byteorder", | ||
| 3686 | "bytes", | 3587 | "bytes", |
| 3687 | "data-encoding", | 3588 | "data-encoding", |
| 3688 | "http 1.3.1", | 3589 | "http 1.3.1", |
| 3689 | "httparse", | 3590 | "httparse", |
| 3690 | "log", | 3591 | "log", |
| 3691 | "rand 0.8.5", | 3592 | "rand 0.9.0", |
| 3692 | "rustls", | 3593 | "rustls", |
| 3693 | "rustls-pki-types", | 3594 | "rustls-pki-types", |
| 3694 | "sha1", | 3595 | "sha1", |
| 3695 | "thiserror 1.0.69", | 3596 | "thiserror 2.0.12", |
| 3696 | "utf-8", | 3597 | "utf-8", |
| 3697 | ] | 3598 | ] |
| 3698 | 3599 | ||
| @@ -24,11 +24,12 @@ futures = "0.3.28" | |||
| 24 | git2 = "0.19.0" | 24 | git2 = "0.19.0" |
| 25 | indicatif = "0.17.7" | 25 | indicatif = "0.17.7" |
| 26 | keyring = "2.0.5" | 26 | keyring = "2.0.5" |
| 27 | nostr = { version = "0.37.0", features = ["nip05", "nip49"] } | 27 | nostr = { version = "0.40.0", features = ["nip05", "nip49"] } |
| 28 | nostr-connect = "0.37.0" | 28 | nostr-connect = "0.40.0" |
| 29 | nostr-database = "0.37.0" | 29 | nostr-database = "0.40.0" |
| 30 | nostr-lmdb = "0.37.0" | 30 | nostr-lmdb = "0.40.0" |
| 31 | nostr-sdk = "0.37.0" | 31 | nostr-relay-pool = "0.40.1" |
| 32 | nostr-sdk = "0.40.0" | ||
| 32 | passwords = "3.1.13" | 33 | passwords = "3.1.13" |
| 33 | qrcode = { version = "0.14.1", default-features = false } | 34 | qrcode = { version = "0.14.1", default-features = false } |
| 34 | scrypt = "0.11.0" | 35 | scrypt = "0.11.0" |
diff --git a/src/bin/git_remote_nostr/fetch.rs b/src/bin/git_remote_nostr/fetch.rs index 5ee4271..a7210d0 100644 --- a/src/bin/git_remote_nostr/fetch.rs +++ b/src/bin/git_remote_nostr/fetch.rs | |||
| @@ -115,7 +115,7 @@ pub fn make_commits_for_proposal( | |||
| 115 | author: Some(patch.pubkey), | 115 | author: Some(patch.pubkey), |
| 116 | kind: Some(patch.kind), | 116 | kind: Some(patch.kind), |
| 117 | relays: if let Some(relay) = repo_ref.relays.first() { | 117 | relays: if let Some(relay) = repo_ref.relays.first() { |
| 118 | vec![relay.to_string()] | 118 | vec![relay.to_owned()] |
| 119 | } else { | 119 | } else { |
| 120 | vec![] | 120 | vec![] |
| 121 | }, | 121 | }, |
diff --git a/src/bin/git_remote_nostr/main.rs b/src/bin/git_remote_nostr/main.rs index 44359dd..daa924f 100644 --- a/src/bin/git_remote_nostr/main.rs +++ b/src/bin/git_remote_nostr/main.rs | |||
| @@ -15,7 +15,7 @@ use anyhow::{Context, Result, bail}; | |||
| 15 | use client::{Connect, consolidate_fetch_reports, get_repo_ref_from_cache}; | 15 | use client::{Connect, consolidate_fetch_reports, get_repo_ref_from_cache}; |
| 16 | use git::{RepoActions, nostr_url::NostrUrlDecoded}; | 16 | use git::{RepoActions, nostr_url::NostrUrlDecoded}; |
| 17 | use ngit::{client, git, login::existing::load_existing_login}; | 17 | use ngit::{client, git, login::existing::load_existing_login}; |
| 18 | use nostr::nips::nip01::Coordinate; | 18 | use nostr::nips::nip19::Nip19Coordinate; |
| 19 | use utils::read_line; | 19 | use utils::read_line; |
| 20 | 20 | ||
| 21 | use crate::{client::Client, git::Repo}; | 21 | use crate::{client::Client, git::Repo}; |
| @@ -148,7 +148,7 @@ async fn process_args() -> Result<Option<(NostrUrlDecoded, Repo)>> { | |||
| 148 | async fn fetching_with_report_for_helper( | 148 | async fn fetching_with_report_for_helper( |
| 149 | git_repo_path: &Path, | 149 | git_repo_path: &Path, |
| 150 | client: &Client, | 150 | client: &Client, |
| 151 | trusted_maintainer_coordinate: &Coordinate, | 151 | trusted_maintainer_coordinate: &Nip19Coordinate, |
| 152 | ) -> Result<()> { | 152 | ) -> Result<()> { |
| 153 | let term = console::Term::stderr(); | 153 | let term = console::Term::stderr(); |
| 154 | term.write_line("nostr: fetching...")?; | 154 | term.write_line("nostr: fetching...")?; |
diff --git a/src/bin/git_remote_nostr/push.rs b/src/bin/git_remote_nostr/push.rs index c0085bd..15adc13 100644 --- a/src/bin/git_remote_nostr/push.rs +++ b/src/bin/git_remote_nostr/push.rs | |||
| @@ -32,7 +32,7 @@ use ngit::{ | |||
| 32 | }; | 32 | }; |
| 33 | use nostr::nips::nip10::Marker; | 33 | use nostr::nips::nip10::Marker; |
| 34 | use nostr_sdk::{ | 34 | use nostr_sdk::{ |
| 35 | Event, EventBuilder, EventId, Kind, NostrSigner, PublicKey, RelayUrl, Tag, | 35 | Event, EventBuilder, EventId, Kind, NostrSigner, PublicKey, RelayUrl, Tag, TagStandard, |
| 36 | hashes::sha1::Hash as Sha1Hash, | 36 | hashes::sha1::Hash as Sha1Hash, |
| 37 | }; | 37 | }; |
| 38 | use repo_ref::RepoRef; | 38 | use repo_ref::RepoRef; |
| @@ -1312,7 +1312,13 @@ async fn create_merge_status( | |||
| 1312 | repo_ref | 1312 | repo_ref |
| 1313 | .coordinates() | 1313 | .coordinates() |
| 1314 | .iter() | 1314 | .iter() |
| 1315 | .map(|c| Tag::coordinate(c.clone())) | 1315 | .map(|c| { |
| 1316 | Tag::from_standardized(TagStandard::Coordinate { | ||
| 1317 | coordinate: c.coordinate.clone(), | ||
| 1318 | relay_url: c.relays.first().cloned(), | ||
| 1319 | uppercase: false, | ||
| 1320 | }) | ||
| 1321 | }) | ||
| 1316 | .collect::<Vec<Tag>>(), | 1322 | .collect::<Vec<Tag>>(), |
| 1317 | vec![ | 1323 | vec![ |
| 1318 | Tag::from_standardized(nostr::TagStandard::Reference( | 1324 | Tag::from_standardized(nostr::TagStandard::Reference( |
| @@ -1358,7 +1364,7 @@ async fn get_proposal_and_revision_root_from_patch( | |||
| 1358 | patch.clone() | 1364 | patch.clone() |
| 1359 | } else { | 1365 | } else { |
| 1360 | let proposal_or_revision_id = EventId::parse( | 1366 | let proposal_or_revision_id = EventId::parse( |
| 1361 | if let Some(t) = patch.tags.iter().find(|t| t.is_root()) { | 1367 | &if let Some(t) = patch.tags.iter().find(|t| t.is_root()) { |
| 1362 | t.clone() | 1368 | t.clone() |
| 1363 | } else if let Some(t) = patch.tags.iter().find(|t| t.is_reply()) { | 1369 | } else if let Some(t) = patch.tags.iter().find(|t| t.is_reply()) { |
| 1364 | t.clone() | 1370 | t.clone() |
| @@ -1389,13 +1395,12 @@ async fn get_proposal_and_revision_root_from_patch( | |||
| 1389 | { | 1395 | { |
| 1390 | Ok(( | 1396 | Ok(( |
| 1391 | EventId::parse( | 1397 | EventId::parse( |
| 1392 | proposal_or_revision | 1398 | &proposal_or_revision |
| 1393 | .tags | 1399 | .tags |
| 1394 | .iter() | 1400 | .iter() |
| 1395 | .find(|t| t.is_reply()) | 1401 | .find(|t| t.is_reply()) |
| 1396 | .unwrap() | 1402 | .unwrap() |
| 1397 | .as_slice()[1] | 1403 | .as_slice()[1], |
| 1398 | .clone(), | ||
| 1399 | )?, | 1404 | )?, |
| 1400 | Some(proposal_or_revision.id), | 1405 | Some(proposal_or_revision.id), |
| 1401 | )) | 1406 | )) |
diff --git a/src/bin/ngit/sub_commands/init.rs b/src/bin/ngit/sub_commands/init.rs index 4aa7ced..3731e3a 100644 --- a/src/bin/ngit/sub_commands/init.rs +++ b/src/bin/ngit/sub_commands/init.rs | |||
| @@ -11,6 +11,7 @@ use nostr::{ | |||
| 11 | nips::{ | 11 | nips::{ |
| 12 | nip01::Coordinate, | 12 | nip01::Coordinate, |
| 13 | nip05::{self}, | 13 | nip05::{self}, |
| 14 | nip19::Nip19Coordinate, | ||
| 14 | }, | 15 | }, |
| 15 | }; | 16 | }; |
| 16 | use nostr_sdk::{Kind, RelayUrl}; | 17 | use nostr_sdk::{Kind, RelayUrl}; |
| @@ -437,10 +438,12 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> { | |||
| 437 | // TODO - does this git config item do more harm than good? | 438 | // TODO - does this git config item do more harm than good? |
| 438 | git_repo.save_git_config_item( | 439 | git_repo.save_git_config_item( |
| 439 | "nostr.repo", | 440 | "nostr.repo", |
| 440 | &Coordinate { | 441 | &Nip19Coordinate { |
| 441 | kind: Kind::GitRepoAnnouncement, | 442 | coordinate: Coordinate { |
| 442 | public_key: user_ref.public_key, | 443 | kind: Kind::GitRepoAnnouncement, |
| 443 | identifier: identifier.clone(), | 444 | public_key: user_ref.public_key, |
| 445 | identifier: identifier.clone(), | ||
| 446 | }, | ||
| 444 | relays: vec![], | 447 | relays: vec![], |
| 445 | } | 448 | } |
| 446 | .to_bech32()?, | 449 | .to_bech32()?, |
| @@ -471,10 +474,12 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> { | |||
| 471 | repo_ref.set_nostr_git_url(NostrUrlDecoded { | 474 | repo_ref.set_nostr_git_url(NostrUrlDecoded { |
| 472 | original_string: String::new(), | 475 | original_string: String::new(), |
| 473 | nip05: Some(nip05.clone()), | 476 | nip05: Some(nip05.clone()), |
| 474 | coordinate: Coordinate { | 477 | coordinate: Nip19Coordinate { |
| 475 | kind: Kind::GitRepoAnnouncement, | 478 | coordinate: Coordinate { |
| 476 | public_key: user_ref.public_key, | 479 | kind: Kind::GitRepoAnnouncement, |
| 477 | identifier: repo_ref.identifier.clone(), | 480 | public_key: user_ref.public_key, |
| 481 | identifier: repo_ref.identifier.clone(), | ||
| 482 | }, | ||
| 478 | relays: if inter.next().is_some() || relays.is_empty() { | 483 | relays: if inter.next().is_some() || relays.is_empty() { |
| 479 | vec![] | 484 | vec![] |
| 480 | } else { | 485 | } else { |
diff --git a/src/bin/ngit/sub_commands/send.rs b/src/bin/ngit/sub_commands/send.rs index 7c898bc..9fc00d9 100644 --- a/src/bin/ngit/sub_commands/send.rs +++ b/src/bin/ngit/sub_commands/send.rs | |||
| @@ -238,7 +238,13 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs, no_fetch: bool) -> Re | |||
| 238 | if root_proposal_id.is_none() { | 238 | if root_proposal_id.is_none() { |
| 239 | if let Some(event) = events.first() { | 239 | if let Some(event) = events.first() { |
| 240 | let event_bech32 = if let Some(relay) = repo_ref.relays.first() { | 240 | let event_bech32 = if let Some(relay) = repo_ref.relays.first() { |
| 241 | Nip19Event::new(event.id, vec![relay.to_string()]).to_bech32()? | 241 | Nip19Event { |
| 242 | event_id: event.id, | ||
| 243 | relays: vec![relay.clone()], | ||
| 244 | author: None, | ||
| 245 | kind: None, | ||
| 246 | } | ||
| 247 | .to_bech32()? | ||
| 242 | } else { | 248 | } else { |
| 243 | event.id.to_bech32()? | 249 | event.id.to_bech32()? |
| 244 | }; | 250 | }; |
diff --git a/src/lib/client.rs b/src/lib/client.rs index 59ec583..142df64 100644 --- a/src/lib/client.rs +++ b/src/lib/client.rs | |||
| @@ -29,9 +29,14 @@ use futures::{ | |||
| 29 | use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressState, ProgressStyle}; | 29 | use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressState, ProgressStyle}; |
| 30 | #[cfg(test)] | 30 | #[cfg(test)] |
| 31 | use mockall::*; | 31 | use mockall::*; |
| 32 | use nostr::{Event, nips::nip01::Coordinate, signer::SignerBackend}; | 32 | use nostr::{ |
| 33 | use nostr_database::NostrEventsDatabase; | 33 | Event, |
| 34 | nips::{nip01::Coordinate, nip19::Nip19Coordinate}, | ||
| 35 | signer::SignerBackend, | ||
| 36 | }; | ||
| 37 | use nostr_database::{NostrEventsDatabase, SaveEventStatus}; | ||
| 34 | use nostr_lmdb::NostrLMDB; | 38 | use nostr_lmdb::NostrLMDB; |
| 39 | use nostr_relay_pool::relay::ReqExitPolicy; | ||
| 35 | use nostr_sdk::{ | 40 | use nostr_sdk::{ |
| 36 | EventBuilder, EventId, Kind, NostrSigner, Options, PublicKey, RelayUrl, SingleLetterTag, | 41 | EventBuilder, EventId, Kind, NostrSigner, Options, PublicKey, RelayUrl, SingleLetterTag, |
| 37 | Timestamp, prelude::RelayLimits, | 42 | Timestamp, prelude::RelayLimits, |
| @@ -89,7 +94,7 @@ pub trait Connect { | |||
| 89 | async fn fetch_all<'a>( | 94 | async fn fetch_all<'a>( |
| 90 | &self, | 95 | &self, |
| 91 | git_repo_path: Option<&'a Path>, | 96 | git_repo_path: Option<&'a Path>, |
| 92 | repo_coordinates: Option<&'a Coordinate>, | 97 | repo_coordinates: Option<&'a Nip19Coordinate>, |
| 93 | user_profiles: &HashSet<PublicKey>, | 98 | user_profiles: &HashSet<PublicKey>, |
| 94 | ) -> Result<(Vec<Result<FetchReport>>, MultiProgress)>; | 99 | ) -> Result<(Vec<Result<FetchReport>>, MultiProgress)>; |
| 95 | async fn fetch_all_from_relay<'a>( | 100 | async fn fetch_all_from_relay<'a>( |
| @@ -182,8 +187,8 @@ impl Connect for Client { | |||
| 182 | 187 | ||
| 183 | if !relay.is_connected() { | 188 | if !relay.is_connected() { |
| 184 | #[allow(clippy::large_futures)] | 189 | #[allow(clippy::large_futures)] |
| 185 | relay | 190 | let _ = relay |
| 186 | .connect(Some(std::time::Duration::from_secs(CONNECTION_TIMEOUT))) | 191 | .try_connect(std::time::Duration::from_secs(CONNECTION_TIMEOUT)) |
| 187 | .await; | 192 | .await; |
| 188 | } | 193 | } |
| 189 | 194 | ||
| @@ -194,7 +199,7 @@ impl Connect for Client { | |||
| 194 | } | 199 | } |
| 195 | 200 | ||
| 196 | async fn disconnect(&self) -> Result<()> { | 201 | async fn disconnect(&self) -> Result<()> { |
| 197 | self.client.disconnect().await?; | 202 | self.client.disconnect().await; |
| 198 | Ok(()) | 203 | Ok(()) |
| 199 | } | 204 | } |
| 200 | 205 | ||
| @@ -223,11 +228,7 @@ impl Connect for Client { | |||
| 223 | self.client.add_relay(url).await?; | 228 | self.client.add_relay(url).await?; |
| 224 | #[allow(clippy::large_futures)] | 229 | #[allow(clippy::large_futures)] |
| 225 | self.client.connect_relay(url).await?; | 230 | self.client.connect_relay(url).await?; |
| 226 | self.client | 231 | self.client.relay(url).await?.send_event(&event).await?; |
| 227 | .relay(url) | ||
| 228 | .await? | ||
| 229 | .send_event(event.clone()) | ||
| 230 | .await?; | ||
| 231 | if let Some(git_repo_path) = git_repo_path { | 232 | if let Some(git_repo_path) = git_repo_path { |
| 232 | save_event_in_local_cache(git_repo_path, &event).await?; | 233 | save_event_in_local_cache(git_repo_path, &event).await?; |
| 233 | } | 234 | } |
| @@ -329,7 +330,7 @@ impl Connect for Client { | |||
| 329 | async fn fetch_all<'a>( | 330 | async fn fetch_all<'a>( |
| 330 | &self, | 331 | &self, |
| 331 | git_repo_path: Option<&'a Path>, | 332 | git_repo_path: Option<&'a Path>, |
| 332 | trusted_maintainer_coordinate: Option<&'a Coordinate>, | 333 | trusted_maintainer_coordinate: Option<&'a Nip19Coordinate>, |
| 333 | user_profiles: &HashSet<PublicKey>, | 334 | user_profiles: &HashSet<PublicKey>, |
| 334 | ) -> Result<(Vec<Result<FetchReport>>, MultiProgress)> { | 335 | ) -> Result<(Vec<Result<FetchReport>>, MultiProgress)> { |
| 335 | let fallback_relays = &self | 336 | let fallback_relays = &self |
| @@ -504,7 +505,7 @@ impl Connect for Client { | |||
| 504 | request: FetchRequest, | 505 | request: FetchRequest, |
| 505 | pb: &Option<ProgressBar>, | 506 | pb: &Option<ProgressBar>, |
| 506 | ) -> Result<FetchReport> { | 507 | ) -> Result<FetchReport> { |
| 507 | let mut fresh_coordinates: HashSet<Coordinate> = HashSet::new(); | 508 | let mut fresh_coordinates: HashSet<Nip19Coordinate> = HashSet::new(); |
| 508 | for (c, _) in request.repo_coordinates_without_relays.clone() { | 509 | for (c, _) in request.repo_coordinates_without_relays.clone() { |
| 509 | fresh_coordinates.insert(c); | 510 | fresh_coordinates.insert(c); |
| 510 | } | 511 | } |
| @@ -617,8 +618,8 @@ async fn get_events_of( | |||
| 617 | 618 | ||
| 618 | if !relay.is_connected() { | 619 | if !relay.is_connected() { |
| 619 | #[allow(clippy::large_futures)] | 620 | #[allow(clippy::large_futures)] |
| 620 | relay | 621 | let _ = relay |
| 621 | .connect(Some(std::time::Duration::from_secs(CONNECTION_TIMEOUT))) | 622 | .try_connect(std::time::Duration::from_secs(CONNECTION_TIMEOUT)) |
| 622 | .await; | 623 | .await; |
| 623 | } | 624 | } |
| 624 | 625 | ||
| @@ -627,16 +628,27 @@ async fn get_events_of( | |||
| 627 | } else if let Some(pb) = pb { | 628 | } else if let Some(pb) = pb { |
| 628 | pb.set_prefix(format!("connected {}", relay.url())); | 629 | pb.set_prefix(format!("connected {}", relay.url())); |
| 629 | } | 630 | } |
| 630 | let events = relay | 631 | |
| 631 | .fetch_events( | 632 | let events_res = join_all(filters.into_iter().map(|filter| async { |
| 632 | filters, | 633 | relay |
| 633 | // 20 is nostr_sdk default | 634 | .fetch_events( |
| 634 | std::time::Duration::from_secs(GET_EVENTS_TIMEOUT), | 635 | filter, |
| 635 | nostr_sdk::FilterOptions::ExitOnEOSE, | 636 | // 20 is nostr_sdk default |
| 636 | ) | 637 | std::time::Duration::from_secs(GET_EVENTS_TIMEOUT), |
| 637 | .await? | 638 | ReqExitPolicy::ExitOnEOSE, |
| 638 | .to_vec(); | 639 | ) |
| 639 | Ok(events) | 640 | .await |
| 641 | })) | ||
| 642 | .await; | ||
| 643 | |||
| 644 | // no Event is being mutated, just new items added to the set | ||
| 645 | #[allow(clippy::mutable_key_type)] | ||
| 646 | let mut events: HashSet<Event> = HashSet::new(); | ||
| 647 | |||
| 648 | for res in events_res { | ||
| 649 | events.extend(res?); | ||
| 650 | } | ||
| 651 | Ok(events.into_iter().collect()) | ||
| 640 | } | 652 | } |
| 641 | 653 | ||
| 642 | #[derive(Default)] | 654 | #[derive(Default)] |
| @@ -770,50 +782,81 @@ pub async fn get_events_from_local_cache( | |||
| 770 | git_repo_path: &Path, | 782 | git_repo_path: &Path, |
| 771 | filters: Vec<nostr::Filter>, | 783 | filters: Vec<nostr::Filter>, |
| 772 | ) -> Result<Vec<nostr::Event>> { | 784 | ) -> Result<Vec<nostr::Event>> { |
| 773 | Ok(get_local_cache_database(git_repo_path) | 785 | let db = get_local_cache_database(git_repo_path).await?; |
| 774 | .await? | 786 | |
| 775 | .query(filters.clone()) | 787 | let query_results = join_all(filters.into_iter().map(|filter| async { |
| 776 | .await | 788 | db.query(filter) |
| 777 | .context( | 789 | .await |
| 778 | "failed to execute query on opened git repo nostr cache database .git/nostr-cache.lmdb", | 790 | .context("failed to execute query on opened ngit nostr cache database") |
| 779 | )? | 791 | })) |
| 780 | .to_vec()) | 792 | .await; |
| 793 | |||
| 794 | // no Event is being mutated, just new items added to the set | ||
| 795 | #[allow(clippy::mutable_key_type)] | ||
| 796 | let mut events: HashSet<Event> = HashSet::new(); | ||
| 797 | |||
| 798 | for result in query_results { | ||
| 799 | events.extend(result?); | ||
| 800 | } | ||
| 801 | |||
| 802 | Ok(events.into_iter().collect()) | ||
| 781 | } | 803 | } |
| 782 | 804 | ||
| 783 | pub async fn get_event_from_global_cache( | 805 | pub async fn get_event_from_global_cache( |
| 784 | git_repo_path: Option<&Path>, | 806 | git_repo_path: Option<&Path>, |
| 785 | filters: Vec<nostr::Filter>, | 807 | filters: Vec<nostr::Filter>, |
| 786 | ) -> Result<Vec<nostr::Event>> { | 808 | ) -> Result<Vec<nostr::Event>> { |
| 787 | Ok(get_global_cache_database(git_repo_path) | 809 | let db = get_global_cache_database(git_repo_path).await?; |
| 788 | .await? | 810 | |
| 789 | .query(filters.clone()) | 811 | let query_results = join_all(filters.into_iter().map(|filter| async { |
| 790 | .await | 812 | db.query(filter) |
| 791 | .context("failed to execute query on opened ngit nostr cache database")? | 813 | .await |
| 792 | .to_vec()) | 814 | .context("failed to execute query on opened ngit nostr cache database") |
| 815 | })) | ||
| 816 | .await; | ||
| 817 | |||
| 818 | // no Event is being mutated, just new items added to the set | ||
| 819 | #[allow(clippy::mutable_key_type)] | ||
| 820 | let mut events: HashSet<Event> = HashSet::new(); | ||
| 821 | |||
| 822 | for result in query_results { | ||
| 823 | events.extend(result?); | ||
| 824 | } | ||
| 825 | |||
| 826 | Ok(events.into_iter().collect()) | ||
| 793 | } | 827 | } |
| 794 | 828 | ||
| 795 | pub async fn save_event_in_local_cache(git_repo_path: &Path, event: &nostr::Event) -> Result<bool> { | 829 | pub async fn save_event_in_local_cache(git_repo_path: &Path, event: &nostr::Event) -> Result<bool> { |
| 796 | get_local_cache_database(git_repo_path) | 830 | match get_local_cache_database(git_repo_path) |
| 797 | .await? | 831 | .await? |
| 798 | .save_event(event) | 832 | .save_event(event) |
| 799 | .await | 833 | .await |
| 800 | .context("failed to save event in local cache") | 834 | .context("failed to save event in local cache")? |
| 835 | { | ||
| 836 | SaveEventStatus::Success => Ok(true), | ||
| 837 | _ => Ok(false), | ||
| 838 | } | ||
| 801 | } | 839 | } |
| 802 | 840 | ||
| 803 | pub async fn save_event_in_global_cache( | 841 | pub async fn save_event_in_global_cache( |
| 804 | git_repo_path: Option<&Path>, | 842 | git_repo_path: Option<&Path>, |
| 805 | event: &nostr::Event, | 843 | event: &nostr::Event, |
| 806 | ) -> Result<bool> { | 844 | ) -> Result<bool> { |
| 807 | get_global_cache_database(git_repo_path) | 845 | match get_global_cache_database(git_repo_path) |
| 808 | .await? | 846 | .await? |
| 809 | .save_event(event) | 847 | .save_event(event) |
| 810 | .await | 848 | .await |
| 811 | .context("failed to save event in local cache") | 849 | .context("failed to save event in local cache") |
| 850 | { | ||
| 851 | Ok(SaveEventStatus::Success) => Ok(true), | ||
| 852 | Ok(_) => Ok(false), | ||
| 853 | Err(e) => Err(e).context("failed to save event in local cache"), | ||
| 854 | } | ||
| 812 | } | 855 | } |
| 813 | 856 | ||
| 814 | pub async fn get_repo_ref_from_cache( | 857 | pub async fn get_repo_ref_from_cache( |
| 815 | git_repo_path: Option<&Path>, | 858 | git_repo_path: Option<&Path>, |
| 816 | repo_coordinate: &Coordinate, | 859 | repo_coordinate: &Nip19Coordinate, |
| 817 | ) -> Result<RepoRef> { | 860 | ) -> Result<RepoRef> { |
| 818 | let mut maintainers = HashSet::new(); | 861 | let mut maintainers = HashSet::new(); |
| 819 | let mut new_coordinate: bool; | 862 | let mut new_coordinate: bool; |
| @@ -824,10 +867,12 @@ pub async fn get_repo_ref_from_cache( | |||
| 824 | new_coordinate = false; | 867 | new_coordinate = false; |
| 825 | let repo_events_filter = | 868 | let repo_events_filter = |
| 826 | get_filter_repo_events(&HashSet::from_iter(maintainers.iter().map(|m| { | 869 | get_filter_repo_events(&HashSet::from_iter(maintainers.iter().map(|m| { |
| 827 | Coordinate { | 870 | Nip19Coordinate { |
| 828 | kind: Kind::GitRepoAnnouncement, | 871 | coordinate: Coordinate { |
| 829 | public_key: *m, | 872 | kind: Kind::GitRepoAnnouncement, |
| 830 | identifier: repo_coordinate.identifier.to_string(), | 873 | public_key: *m, |
| 874 | identifier: repo_coordinate.identifier.to_string(), | ||
| 875 | }, | ||
| 831 | relays: vec![], | 876 | relays: vec![], |
| 832 | } | 877 | } |
| 833 | }))); | 878 | }))); |
| @@ -859,19 +904,21 @@ pub async fn get_repo_ref_from_cache( | |||
| 859 | let repo_ref = RepoRef::try_from(( | 904 | let repo_ref = RepoRef::try_from(( |
| 860 | repo_events | 905 | repo_events |
| 861 | .first() | 906 | .first() |
| 862 | .context("no repo announcement event found at specified coordinates. if you are the repository maintainer consider running `ngit init` to create one")? | 907 | .context("no repo announcement event found at specified Nip19Coordinates. if you are the repository maintainer consider running `ngit init` to create one")? |
| 863 | .clone(), | 908 | .clone(), |
| 864 | Some(repo_coordinate.public_key), | 909 | Some(repo_coordinate.public_key), |
| 865 | ))?; | 910 | ))?; |
| 866 | 911 | ||
| 867 | let mut events: HashMap<Coordinate, nostr::Event> = HashMap::new(); | 912 | let mut events: HashMap<Nip19Coordinate, nostr::Event> = HashMap::new(); |
| 868 | for m in &maintainers { | 913 | for m in &maintainers { |
| 869 | if let Some(e) = repo_events.iter().find(|e| e.pubkey.eq(m)) { | 914 | if let Some(e) = repo_events.iter().find(|e| e.pubkey.eq(m)) { |
| 870 | events.insert( | 915 | events.insert( |
| 871 | Coordinate { | 916 | Nip19Coordinate { |
| 872 | kind: e.kind, | 917 | coordinate: Coordinate { |
| 873 | identifier: e.tags.identifier().unwrap().to_string(), | 918 | kind: e.kind, |
| 874 | public_key: e.pubkey, | 919 | identifier: e.tags.identifier().unwrap().to_string(), |
| 920 | public_key: e.pubkey, | ||
| 921 | }, | ||
| 875 | relays: vec![], | 922 | relays: vec![], |
| 876 | }, | 923 | }, |
| 877 | e.clone(), | 924 | e.clone(), |
| @@ -912,7 +959,7 @@ pub async fn get_state_from_cache( | |||
| 912 | #[allow(clippy::too_many_lines)] | 959 | #[allow(clippy::too_many_lines)] |
| 913 | async fn create_relays_request( | 960 | async fn create_relays_request( |
| 914 | git_repo_path: Option<&Path>, | 961 | git_repo_path: Option<&Path>, |
| 915 | trusted_maintainer_coordinate: Option<&Coordinate>, | 962 | trusted_maintainer_coordinate: Option<&Nip19Coordinate>, |
| 916 | user_profiles: &HashSet<PublicKey>, | 963 | user_profiles: &HashSet<PublicKey>, |
| 917 | fallback_relays: HashSet<RelayUrl>, | 964 | fallback_relays: HashSet<RelayUrl>, |
| 918 | ) -> Result<FetchRequest> { | 965 | ) -> Result<FetchRequest> { |
| @@ -929,9 +976,9 @@ async fn create_relays_request( | |||
| 929 | }; | 976 | }; |
| 930 | 977 | ||
| 931 | let repo_coordinates = { | 978 | let repo_coordinates = { |
| 932 | // add coordinates of users listed in maintainers to explicitly specified | 979 | // add Nip19Coordinates of users listed in maintainers to explicitly |
| 933 | // coodinates | 980 | // specified coodinates |
| 934 | let mut set: HashSet<Coordinate> = HashSet::new(); | 981 | let mut set: HashSet<Nip19Coordinate> = HashSet::new(); |
| 935 | if let Some(trusted_maintainer_coordinate) = trusted_maintainer_coordinate { | 982 | if let Some(trusted_maintainer_coordinate) = trusted_maintainer_coordinate { |
| 936 | set.insert(trusted_maintainer_coordinate.clone()); | 983 | set.insert(trusted_maintainer_coordinate.clone()); |
| 937 | } | 984 | } |
| @@ -951,10 +998,12 @@ async fn create_relays_request( | |||
| 951 | let repo_coordinates_without_relays = { | 998 | let repo_coordinates_without_relays = { |
| 952 | let mut set = HashSet::new(); | 999 | let mut set = HashSet::new(); |
| 953 | for c in &repo_coordinates { | 1000 | for c in &repo_coordinates { |
| 954 | set.insert(Coordinate { | 1001 | set.insert(Nip19Coordinate { |
| 955 | kind: c.kind, | 1002 | coordinate: Coordinate { |
| 956 | identifier: c.identifier.clone(), | 1003 | kind: c.kind, |
| 957 | public_key: c.public_key, | 1004 | identifier: c.identifier.clone(), |
| 1005 | public_key: c.public_key, | ||
| 1006 | }, | ||
| 958 | relays: vec![], | 1007 | relays: vec![], |
| 959 | }); | 1008 | }); |
| 960 | } | 1009 | } |
| @@ -976,11 +1025,11 @@ async fn create_relays_request( | |||
| 976 | for event in &get_events_from_local_cache(git_repo_path, vec![ | 1025 | for event in &get_events_from_local_cache(git_repo_path, vec![ |
| 977 | nostr::Filter::default() | 1026 | nostr::Filter::default() |
| 978 | .kinds(vec![Kind::GitPatch]) | 1027 | .kinds(vec![Kind::GitPatch]) |
| 979 | .custom_tag( | 1028 | .custom_tags( |
| 980 | SingleLetterTag::lowercase(nostr_sdk::Alphabet::A), | 1029 | SingleLetterTag::lowercase(nostr_sdk::Alphabet::A), |
| 981 | repo_coordinates_without_relays | 1030 | repo_coordinates_without_relays |
| 982 | .iter() | 1031 | .iter() |
| 983 | .map(std::string::ToString::to_string) | 1032 | .map(|c| c.coordinate.to_string()) |
| 984 | .collect::<Vec<String>>(), | 1033 | .collect::<Vec<String>>(), |
| 985 | ), | 1034 | ), |
| 986 | ]) | 1035 | ]) |
| @@ -1153,7 +1202,7 @@ async fn process_fetched_events( | |||
| 1153 | events: Vec<nostr::Event>, | 1202 | events: Vec<nostr::Event>, |
| 1154 | request: &FetchRequest, | 1203 | request: &FetchRequest, |
| 1155 | git_repo_path: Option<&Path>, | 1204 | git_repo_path: Option<&Path>, |
| 1156 | fresh_coordinates: &mut HashSet<Coordinate>, | 1205 | fresh_coordinates: &mut HashSet<Nip19Coordinate>, |
| 1157 | fresh_proposal_roots: &mut HashSet<EventId>, | 1206 | fresh_proposal_roots: &mut HashSet<EventId>, |
| 1158 | fresh_profiles: &mut HashSet<PublicKey>, | 1207 | fresh_profiles: &mut HashSet<PublicKey>, |
| 1159 | report: &mut FetchReport, | 1208 | report: &mut FetchReport, |
| @@ -1188,10 +1237,12 @@ async fn process_fetched_events( | |||
| 1188 | }); | 1237 | }); |
| 1189 | if update_to_existing { | 1238 | if update_to_existing { |
| 1190 | report.updated_repo_announcements.push(( | 1239 | report.updated_repo_announcements.push(( |
| 1191 | Coordinate { | 1240 | Nip19Coordinate { |
| 1192 | kind: event.kind, | 1241 | coordinate: Coordinate { |
| 1193 | public_key: event.pubkey, | 1242 | kind: event.kind, |
| 1194 | identifier: event.tags.identifier().unwrap().to_owned(), | 1243 | public_key: event.pubkey, |
| 1244 | identifier: event.tags.identifier().unwrap().to_owned(), | ||
| 1245 | }, | ||
| 1195 | relays: vec![], | 1246 | relays: vec![], |
| 1196 | }, | 1247 | }, |
| 1197 | event.created_at, | 1248 | event.created_at, |
| @@ -1204,14 +1255,16 @@ async fn process_fetched_events( | |||
| 1204 | .repo_coordinates_without_relays // prexisting maintainers | 1255 | .repo_coordinates_without_relays // prexisting maintainers |
| 1205 | .iter() | 1256 | .iter() |
| 1206 | .map(|(c, _)| c.clone()) | 1257 | .map(|(c, _)| c.clone()) |
| 1207 | .collect::<HashSet<Coordinate>>() | 1258 | .collect::<HashSet<Nip19Coordinate>>() |
| 1208 | .union(&report.repo_coordinates_without_relays) // already added maintainers | 1259 | .union(&report.repo_coordinates_without_relays) // already added maintainers |
| 1209 | .any(|c| c.identifier.eq(&repo_ref.identifier) && m.eq(&c.public_key)) | 1260 | .any(|c| c.identifier.eq(&repo_ref.identifier) && m.eq(&c.public_key)) |
| 1210 | { | 1261 | { |
| 1211 | let c = Coordinate { | 1262 | let c = Nip19Coordinate { |
| 1212 | kind: event.kind, | 1263 | coordinate: Coordinate { |
| 1213 | public_key: *m, | 1264 | kind: event.kind, |
| 1214 | identifier: repo_ref.identifier.clone(), | 1265 | public_key: *m, |
| 1266 | identifier: repo_ref.identifier.clone(), | ||
| 1267 | }, | ||
| 1215 | relays: vec![], | 1268 | relays: vec![], |
| 1216 | }; | 1269 | }; |
| 1217 | fresh_coordinates.insert(c.clone()); | 1270 | fresh_coordinates.insert(c.clone()); |
| @@ -1343,7 +1396,7 @@ pub fn consolidate_fetch_reports(reports: Vec<Result<FetchReport>>) -> FetchRepo | |||
| 1343 | report | 1396 | report |
| 1344 | } | 1397 | } |
| 1345 | pub fn get_fetch_filters( | 1398 | pub fn get_fetch_filters( |
| 1346 | repo_coordinates: &HashSet<Coordinate>, | 1399 | repo_coordinates: &HashSet<Nip19Coordinate>, |
| 1347 | proposal_ids: &HashSet<EventId>, | 1400 | proposal_ids: &HashSet<EventId>, |
| 1348 | required_profiles: &HashSet<PublicKey>, | 1401 | required_profiles: &HashSet<PublicKey>, |
| 1349 | ) -> Vec<nostr::Filter> { | 1402 | ) -> Vec<nostr::Filter> { |
| @@ -1356,11 +1409,11 @@ pub fn get_fetch_filters( | |||
| 1356 | get_filter_repo_events(repo_coordinates), | 1409 | get_filter_repo_events(repo_coordinates), |
| 1357 | nostr::Filter::default() | 1410 | nostr::Filter::default() |
| 1358 | .kinds(vec![Kind::GitPatch, Kind::EventDeletion]) | 1411 | .kinds(vec![Kind::GitPatch, Kind::EventDeletion]) |
| 1359 | .custom_tag( | 1412 | .custom_tags( |
| 1360 | SingleLetterTag::lowercase(nostr_sdk::Alphabet::A), | 1413 | SingleLetterTag::lowercase(nostr_sdk::Alphabet::A), |
| 1361 | repo_coordinates | 1414 | repo_coordinates |
| 1362 | .iter() | 1415 | .iter() |
| 1363 | .map(std::string::ToString::to_string) | 1416 | .map(|c| c.coordinate.to_string()) |
| 1364 | .collect::<Vec<String>>(), | 1417 | .collect::<Vec<String>>(), |
| 1365 | ), | 1418 | ), |
| 1366 | ] | 1419 | ] |
| @@ -1383,7 +1436,7 @@ pub fn get_fetch_filters( | |||
| 1383 | .concat() | 1436 | .concat() |
| 1384 | } | 1437 | } |
| 1385 | 1438 | ||
| 1386 | pub fn get_filter_repo_events(repo_coordinates: &HashSet<Coordinate>) -> nostr::Filter { | 1439 | pub fn get_filter_repo_events(repo_coordinates: &HashSet<Nip19Coordinate>) -> nostr::Filter { |
| 1387 | nostr::Filter::default() | 1440 | nostr::Filter::default() |
| 1388 | .kind(Kind::GitRepoAnnouncement) | 1441 | .kind(Kind::GitRepoAnnouncement) |
| 1389 | .identifiers( | 1442 | .identifiers( |
| @@ -1401,7 +1454,7 @@ pub fn get_filter_repo_events(repo_coordinates: &HashSet<Coordinate>) -> nostr:: | |||
| 1401 | } | 1454 | } |
| 1402 | 1455 | ||
| 1403 | pub static STATE_KIND: nostr::Kind = Kind::Custom(30618); | 1456 | pub static STATE_KIND: nostr::Kind = Kind::Custom(30618); |
| 1404 | pub fn get_filter_state_events(repo_coordinates: &HashSet<Coordinate>) -> nostr::Filter { | 1457 | pub fn get_filter_state_events(repo_coordinates: &HashSet<Nip19Coordinate>) -> nostr::Filter { |
| 1405 | nostr::Filter::default() | 1458 | nostr::Filter::default() |
| 1406 | .kind(STATE_KIND) | 1459 | .kind(STATE_KIND) |
| 1407 | .identifiers( | 1460 | .identifiers( |
| @@ -1426,8 +1479,8 @@ pub fn get_filter_contributor_profiles(contributors: HashSet<PublicKey>) -> nost | |||
| 1426 | 1479 | ||
| 1427 | #[derive(Default)] | 1480 | #[derive(Default)] |
| 1428 | pub struct FetchReport { | 1481 | pub struct FetchReport { |
| 1429 | repo_coordinates_without_relays: HashSet<Coordinate>, | 1482 | repo_coordinates_without_relays: HashSet<Nip19Coordinate>, |
| 1430 | updated_repo_announcements: Vec<(Coordinate, Timestamp)>, | 1483 | updated_repo_announcements: Vec<(Nip19Coordinate, Timestamp)>, |
| 1431 | updated_state: Option<(Timestamp, EventId)>, | 1484 | updated_state: Option<(Timestamp, EventId)>, |
| 1432 | proposals: HashSet<EventId>, | 1485 | proposals: HashSet<EventId>, |
| 1433 | /// commits against existing propoals | 1486 | /// commits against existing propoals |
| @@ -1518,7 +1571,7 @@ pub struct FetchRequest { | |||
| 1518 | repo_relays: HashSet<RelayUrl>, | 1571 | repo_relays: HashSet<RelayUrl>, |
| 1519 | selected_relay: Option<RelayUrl>, | 1572 | selected_relay: Option<RelayUrl>, |
| 1520 | relay_column_width: usize, | 1573 | relay_column_width: usize, |
| 1521 | repo_coordinates_without_relays: Vec<(Coordinate, Option<Timestamp>)>, | 1574 | repo_coordinates_without_relays: Vec<(Nip19Coordinate, Option<Timestamp>)>, |
| 1522 | state: Option<(Timestamp, EventId)>, | 1575 | state: Option<(Timestamp, EventId)>, |
| 1523 | proposals: HashSet<EventId>, | 1576 | proposals: HashSet<EventId>, |
| 1524 | contributors: HashSet<PublicKey>, | 1577 | contributors: HashSet<PublicKey>, |
| @@ -1532,7 +1585,7 @@ pub async fn fetching_with_report( | |||
| 1532 | git_repo_path: &Path, | 1585 | git_repo_path: &Path, |
| 1533 | #[cfg(test)] client: &crate::client::MockConnect, | 1586 | #[cfg(test)] client: &crate::client::MockConnect, |
| 1534 | #[cfg(not(test))] client: &Client, | 1587 | #[cfg(not(test))] client: &Client, |
| 1535 | trusted_maintainer_coordinate: &Coordinate, | 1588 | trusted_maintainer_coordinate: &Nip19Coordinate, |
| 1536 | ) -> Result<FetchReport> { | 1589 | ) -> Result<FetchReport> { |
| 1537 | let term = console::Term::stderr(); | 1590 | let term = console::Term::stderr(); |
| 1538 | term.write_line("fetching updates...")?; | 1591 | term.write_line("fetching updates...")?; |
| @@ -1557,16 +1610,16 @@ pub async fn fetching_with_report( | |||
| 1557 | 1610 | ||
| 1558 | pub async fn get_proposals_and_revisions_from_cache( | 1611 | pub async fn get_proposals_and_revisions_from_cache( |
| 1559 | git_repo_path: &Path, | 1612 | git_repo_path: &Path, |
| 1560 | repo_coordinates: HashSet<Coordinate>, | 1613 | repo_coordinates: HashSet<Nip19Coordinate>, |
| 1561 | ) -> Result<Vec<nostr::Event>> { | 1614 | ) -> Result<Vec<nostr::Event>> { |
| 1562 | let mut proposals = get_events_from_local_cache(git_repo_path, vec![ | 1615 | let mut proposals = get_events_from_local_cache(git_repo_path, vec![ |
| 1563 | nostr::Filter::default() | 1616 | nostr::Filter::default() |
| 1564 | .kind(nostr::Kind::GitPatch) | 1617 | .kind(nostr::Kind::GitPatch) |
| 1565 | .custom_tag( | 1618 | .custom_tags( |
| 1566 | nostr::SingleLetterTag::lowercase(nostr_sdk::Alphabet::A), | 1619 | nostr::SingleLetterTag::lowercase(nostr_sdk::Alphabet::A), |
| 1567 | repo_coordinates | 1620 | repo_coordinates |
| 1568 | .iter() | 1621 | .iter() |
| 1569 | .map(std::string::ToString::to_string) | 1622 | .map(|c| c.coordinate.to_string()) |
| 1570 | .collect::<Vec<String>>(), | 1623 | .collect::<Vec<String>>(), |
| 1571 | ), | 1624 | ), |
| 1572 | ]) | 1625 | ]) |
diff --git a/src/lib/git/mod.rs b/src/lib/git/mod.rs index 2b78f38..1329820 100644 --- a/src/lib/git/mod.rs +++ b/src/lib/git/mod.rs | |||
| @@ -1141,7 +1141,7 @@ mod tests { | |||
| 1141 | fn test(time: git2::Time) -> Result<()> { | 1141 | fn test(time: git2::Time) -> Result<()> { |
| 1142 | assert_eq!( | 1142 | assert_eq!( |
| 1143 | extract_sig_from_patch_tags( | 1143 | extract_sig_from_patch_tags( |
| 1144 | &Tags::new(vec![nostr::Tag::custom( | 1144 | &Tags::from_list(vec![nostr::Tag::custom( |
| 1145 | nostr::TagKind::Custom("author".to_string().into()), | 1145 | nostr::TagKind::Custom("author".to_string().into()), |
| 1146 | prep(&time)?, | 1146 | prep(&time)?, |
| 1147 | )]), | 1147 | )]), |
diff --git a/src/lib/git/nostr_url.rs b/src/lib/git/nostr_url.rs index ae0ac5f..54be292 100644 --- a/src/lib/git/nostr_url.rs +++ b/src/lib/git/nostr_url.rs | |||
| @@ -2,8 +2,8 @@ use core::fmt; | |||
| 2 | use std::{collections::HashMap, str::FromStr}; | 2 | use std::{collections::HashMap, str::FromStr}; |
| 3 | 3 | ||
| 4 | use anyhow::{Context, Error, Result, anyhow, bail}; | 4 | use anyhow::{Context, Error, Result, anyhow, bail}; |
| 5 | use nostr::nips::{nip01::Coordinate, nip05}; | 5 | use nostr::nips::{nip01::Coordinate, nip05, nip19::Nip19Coordinate}; |
| 6 | use nostr_sdk::{PublicKey, RelayUrl, ToBech32, Url}; | 6 | use nostr_sdk::{FromBech32, PublicKey, RelayUrl, ToBech32, Url}; |
| 7 | 7 | ||
| 8 | use super::{Repo, get_git_config_item, save_git_config_item}; | 8 | use super::{Repo, get_git_config_item, save_git_config_item}; |
| 9 | 9 | ||
| @@ -58,7 +58,7 @@ impl FromStr for ServerProtocol { | |||
| 58 | #[derive(Debug, PartialEq, Clone)] | 58 | #[derive(Debug, PartialEq, Clone)] |
| 59 | pub struct NostrUrlDecoded { | 59 | pub struct NostrUrlDecoded { |
| 60 | pub original_string: String, | 60 | pub original_string: String, |
| 61 | pub coordinate: Coordinate, | 61 | pub coordinate: Nip19Coordinate, |
| 62 | pub protocol: Option<ServerProtocol>, | 62 | pub protocol: Option<ServerProtocol>, |
| 63 | pub user: Option<String>, | 63 | pub user: Option<String>, |
| 64 | pub nip05: Option<String>, | 64 | pub nip05: Option<String>, |
| @@ -166,7 +166,7 @@ impl NostrUrlDecoded { | |||
| 166 | // extract naddr npub/<optional-relays>/identifer | 166 | // extract naddr npub/<optional-relays>/identifer |
| 167 | let part = parts.first().context(INCORRECT_NOSTR_URL_FORMAT_ERROR)?; | 167 | let part = parts.first().context(INCORRECT_NOSTR_URL_FORMAT_ERROR)?; |
| 168 | // naddr used | 168 | // naddr used |
| 169 | let coordinate = if let Ok(coordinate) = Coordinate::parse(part) { | 169 | let coordinate = if let Ok(coordinate) = Nip19Coordinate::from_bech32(part) { |
| 170 | if coordinate.kind.eq(&nostr_sdk::Kind::GitRepoAnnouncement) { | 170 | if coordinate.kind.eq(&nostr_sdk::Kind::GitRepoAnnouncement) { |
| 171 | coordinate | 171 | coordinate |
| 172 | } else { | 172 | } else { |
| @@ -225,10 +225,12 @@ impl NostrUrlDecoded { | |||
| 225 | } | 225 | } |
| 226 | } | 226 | } |
| 227 | }; | 227 | }; |
| 228 | Coordinate { | 228 | Nip19Coordinate { |
| 229 | identifier, | 229 | coordinate: Coordinate { |
| 230 | public_key, | 230 | identifier, |
| 231 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | 231 | public_key, |
| 232 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 233 | }, | ||
| 232 | relays, | 234 | relays, |
| 233 | } | 235 | } |
| 234 | }; | 236 | }; |
| @@ -959,7 +961,7 @@ mod tests { | |||
| 959 | } | 961 | } |
| 960 | } | 962 | } |
| 961 | mod nostr_git_url_format { | 963 | mod nostr_git_url_format { |
| 962 | use nostr::nips::nip01::Coordinate; | 964 | use nostr::nips::nip19::Nip19Coordinate; |
| 963 | use nostr_sdk::PublicKey; | 965 | use nostr_sdk::PublicKey; |
| 964 | 966 | ||
| 965 | use super::*; | 967 | use super::*; |
| @@ -970,13 +972,15 @@ mod tests { | |||
| 970 | assert_eq!( | 972 | assert_eq!( |
| 971 | format!("{}", NostrUrlDecoded { | 973 | format!("{}", NostrUrlDecoded { |
| 972 | original_string: String::new(), | 974 | original_string: String::new(), |
| 973 | coordinate: Coordinate { | 975 | coordinate: Nip19Coordinate { |
| 974 | identifier: "ngit".to_string(), | 976 | coordinate: Coordinate { |
| 975 | public_key: PublicKey::parse( | 977 | identifier: "ngit".to_string(), |
| 976 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | 978 | public_key: PublicKey::parse( |
| 977 | ) | 979 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", |
| 978 | .unwrap(), | 980 | ) |
| 979 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | 981 | .unwrap(), |
| 982 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 983 | }, | ||
| 980 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], | 984 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], |
| 981 | }, | 985 | }, |
| 982 | protocol: None, | 986 | protocol: None, |
| @@ -993,13 +997,15 @@ mod tests { | |||
| 993 | assert_eq!( | 997 | assert_eq!( |
| 994 | format!("{}", NostrUrlDecoded { | 998 | format!("{}", NostrUrlDecoded { |
| 995 | original_string: String::new(), | 999 | original_string: String::new(), |
| 996 | coordinate: Coordinate { | 1000 | coordinate: Nip19Coordinate { |
| 997 | identifier: "ngit".to_string(), | 1001 | coordinate: Coordinate { |
| 998 | public_key: PublicKey::parse( | 1002 | identifier: "ngit".to_string(), |
| 999 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | 1003 | public_key: PublicKey::parse( |
| 1000 | ) | 1004 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", |
| 1001 | .unwrap(), | 1005 | ) |
| 1002 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | 1006 | .unwrap(), |
| 1007 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 1008 | }, | ||
| 1003 | relays: vec![], | 1009 | relays: vec![], |
| 1004 | }, | 1010 | }, |
| 1005 | protocol: None, | 1011 | protocol: None, |
| @@ -1016,13 +1022,15 @@ mod tests { | |||
| 1016 | assert_eq!( | 1022 | assert_eq!( |
| 1017 | format!("{}", NostrUrlDecoded { | 1023 | format!("{}", NostrUrlDecoded { |
| 1018 | original_string: String::new(), | 1024 | original_string: String::new(), |
| 1019 | coordinate: Coordinate { | 1025 | coordinate: Nip19Coordinate { |
| 1020 | identifier: "ngit".to_string(), | 1026 | coordinate: Coordinate { |
| 1021 | public_key: PublicKey::parse( | 1027 | identifier: "ngit".to_string(), |
| 1022 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | 1028 | public_key: PublicKey::parse( |
| 1023 | ) | 1029 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", |
| 1024 | .unwrap(), | 1030 | ) |
| 1025 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | 1031 | .unwrap(), |
| 1032 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 1033 | }, | ||
| 1026 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], | 1034 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], |
| 1027 | }, | 1035 | }, |
| 1028 | protocol: Some(ServerProtocol::Ssh), | 1036 | protocol: Some(ServerProtocol::Ssh), |
| @@ -1039,13 +1047,15 @@ mod tests { | |||
| 1039 | assert_eq!( | 1047 | assert_eq!( |
| 1040 | format!("{}", NostrUrlDecoded { | 1048 | format!("{}", NostrUrlDecoded { |
| 1041 | original_string: String::new(), | 1049 | original_string: String::new(), |
| 1042 | coordinate: Coordinate { | 1050 | coordinate: Nip19Coordinate { |
| 1043 | identifier: "ngit".to_string(), | 1051 | coordinate: Coordinate { |
| 1044 | public_key: PublicKey::parse( | 1052 | identifier: "ngit".to_string(), |
| 1045 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | 1053 | public_key: PublicKey::parse( |
| 1046 | ) | 1054 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", |
| 1047 | .unwrap(), | 1055 | ) |
| 1048 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | 1056 | .unwrap(), |
| 1057 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 1058 | }, | ||
| 1049 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], | 1059 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], |
| 1050 | }, | 1060 | }, |
| 1051 | protocol: Some(ServerProtocol::Ssh), | 1061 | protocol: Some(ServerProtocol::Ssh), |
| @@ -1061,14 +1071,16 @@ mod tests { | |||
| 1061 | mod nostr_url_decoded_paramemters_from_str { | 1071 | mod nostr_url_decoded_paramemters_from_str { |
| 1062 | use super::*; | 1072 | use super::*; |
| 1063 | 1073 | ||
| 1064 | fn get_model_coordinate(relays: bool) -> Coordinate { | 1074 | fn get_model_coordinate(relays: bool) -> Nip19Coordinate { |
| 1065 | Coordinate { | 1075 | Nip19Coordinate { |
| 1066 | identifier: "ngit".to_string(), | 1076 | coordinate: Coordinate { |
| 1067 | public_key: PublicKey::parse( | 1077 | identifier: "ngit".to_string(), |
| 1068 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | 1078 | public_key: PublicKey::parse( |
| 1069 | ) | 1079 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", |
| 1070 | .unwrap(), | 1080 | ) |
| 1071 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | 1081 | .unwrap(), |
| 1082 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 1083 | }, | ||
| 1072 | relays: if relays { | 1084 | relays: if relays { |
| 1073 | vec![RelayUrl::parse("wss://nos.lol").unwrap()] | 1085 | vec![RelayUrl::parse("wss://nos.lol").unwrap()] |
| 1074 | } else { | 1086 | } else { |
| @@ -1084,13 +1096,15 @@ mod tests { | |||
| 1084 | NostrUrlDecoded::parse_and_resolve(&url, &None).await?, | 1096 | NostrUrlDecoded::parse_and_resolve(&url, &None).await?, |
| 1085 | NostrUrlDecoded { | 1097 | NostrUrlDecoded { |
| 1086 | original_string: url.clone(), | 1098 | original_string: url.clone(), |
| 1087 | coordinate: Coordinate { | 1099 | coordinate: Nip19Coordinate { |
| 1088 | identifier: "ngit".to_string(), | 1100 | coordinate: Coordinate { |
| 1089 | public_key: PublicKey::parse( | 1101 | identifier: "ngit".to_string(), |
| 1090 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | 1102 | public_key: PublicKey::parse( |
| 1091 | ) | 1103 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", |
| 1092 | .unwrap(), | 1104 | ) |
| 1093 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | 1105 | .unwrap(), |
| 1106 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 1107 | }, | ||
| 1094 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], /* wont add the | 1108 | relays: vec![RelayUrl::parse("wss://nos.lol").unwrap()], /* wont add the |
| 1095 | * slash */ | 1109 | * slash */ |
| 1096 | }, | 1110 | }, |
| @@ -1172,13 +1186,15 @@ mod tests { | |||
| 1172 | NostrUrlDecoded::parse_and_resolve(&url, &None).await?, | 1186 | NostrUrlDecoded::parse_and_resolve(&url, &None).await?, |
| 1173 | NostrUrlDecoded { | 1187 | NostrUrlDecoded { |
| 1174 | original_string: url.clone(), | 1188 | original_string: url.clone(), |
| 1175 | coordinate: Coordinate { | 1189 | coordinate: Nip19Coordinate { |
| 1176 | identifier: "ngit".to_string(), | 1190 | coordinate: Coordinate { |
| 1177 | public_key: PublicKey::parse( | 1191 | identifier: "ngit".to_string(), |
| 1178 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | 1192 | public_key: PublicKey::parse( |
| 1179 | ) | 1193 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", |
| 1180 | .unwrap(), | 1194 | ) |
| 1181 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | 1195 | .unwrap(), |
| 1196 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 1197 | }, | ||
| 1182 | relays: vec![ | 1198 | relays: vec![ |
| 1183 | RelayUrl::parse("wss://nos.lol/").unwrap(), | 1199 | RelayUrl::parse("wss://nos.lol/").unwrap(), |
| 1184 | RelayUrl::parse("wss://relay.damus.io/").unwrap(), | 1200 | RelayUrl::parse("wss://relay.damus.io/").unwrap(), |
| @@ -1274,13 +1290,15 @@ mod tests { | |||
| 1274 | NostrUrlDecoded::parse_and_resolve(&url, &None).await?, | 1290 | NostrUrlDecoded::parse_and_resolve(&url, &None).await?, |
| 1275 | NostrUrlDecoded { | 1291 | NostrUrlDecoded { |
| 1276 | original_string: url.clone(), | 1292 | original_string: url.clone(), |
| 1277 | coordinate: Coordinate { | 1293 | coordinate: Nip19Coordinate { |
| 1278 | identifier: "ngit".to_string(), | 1294 | coordinate: Coordinate { |
| 1279 | public_key: PublicKey::parse( | 1295 | identifier: "ngit".to_string(), |
| 1280 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", | 1296 | public_key: PublicKey::parse( |
| 1281 | ) | 1297 | "npub15qydau2hjma6ngxkl2cyar74wzyjshvl65za5k5rl69264ar2exs5cyejr", |
| 1282 | .unwrap(), | 1298 | ) |
| 1283 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | 1299 | .unwrap(), |
| 1300 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | ||
| 1301 | }, | ||
| 1284 | relays: vec![ | 1302 | relays: vec![ |
| 1285 | RelayUrl::parse("wss://nos.lol/").unwrap(), | 1303 | RelayUrl::parse("wss://nos.lol/").unwrap(), |
| 1286 | RelayUrl::parse("wss://relay.damus.io/").unwrap(), | 1304 | RelayUrl::parse("wss://relay.damus.io/").unwrap(), |
diff --git a/src/lib/git_events.rs b/src/lib/git_events.rs index 559155a..2b3df42 100644 --- a/src/lib/git_events.rs +++ b/src/lib/git_events.rs | |||
| @@ -3,7 +3,7 @@ use std::{str::FromStr, sync::Arc}; | |||
| 3 | use anyhow::{Context, Result, bail}; | 3 | use anyhow::{Context, Result, bail}; |
| 4 | use nostr::nips::{nip01::Coordinate, nip10::Marker, nip19::Nip19}; | 4 | use nostr::nips::{nip01::Coordinate, nip10::Marker, nip19::Nip19}; |
| 5 | use nostr_sdk::{ | 5 | use nostr_sdk::{ |
| 6 | Event, EventBuilder, EventId, FromBech32, Kind, NostrSigner, PublicKey, RelayUrl, Tag, TagKind, | 6 | Event, EventBuilder, EventId, FromBech32, Kind, NostrSigner, PublicKey, Tag, TagKind, |
| 7 | TagStandard, hashes::sha1::Hash as Sha1Hash, | 7 | TagStandard, hashes::sha1::Hash as Sha1Hash, |
| 8 | }; | 8 | }; |
| 9 | 9 | ||
| @@ -115,11 +115,14 @@ pub async fn generate_patch_event( | |||
| 115 | .maintainers | 115 | .maintainers |
| 116 | .iter() | 116 | .iter() |
| 117 | .map(|m| { | 117 | .map(|m| { |
| 118 | Tag::coordinate(Coordinate { | 118 | Tag::from_standardized(TagStandard::Coordinate { |
| 119 | kind: nostr::Kind::GitRepoAnnouncement, | 119 | coordinate: Coordinate { |
| 120 | public_key: *m, | 120 | kind: nostr::Kind::GitRepoAnnouncement, |
| 121 | identifier: repo_ref.identifier.to_string(), | 121 | public_key: *m, |
| 122 | relays: repo_ref.relays.clone(), | 122 | identifier: repo_ref.identifier.to_string(), |
| 123 | }, | ||
| 124 | relay_url: repo_ref.relays.first().cloned(), | ||
| 125 | uppercase: false, | ||
| 123 | }) | 126 | }) |
| 124 | }) | 127 | }) |
| 125 | .collect::<Vec<Tag>>(), | 128 | .collect::<Vec<Tag>>(), |
| @@ -257,12 +260,12 @@ pub fn event_tag_from_nip19_or_hex( | |||
| 257 | PromptInputParms::default().with_prompt(format!("{reference_name} reference")), | 260 | PromptInputParms::default().with_prompt(format!("{reference_name} reference")), |
| 258 | )?; | 261 | )?; |
| 259 | } | 262 | } |
| 260 | if let Ok(nip19) = Nip19::from_bech32(bech32.clone()) { | 263 | if let Ok(nip19) = Nip19::from_bech32(&bech32) { |
| 261 | match nip19 { | 264 | match nip19 { |
| 262 | Nip19::Event(n) => { | 265 | Nip19::Event(n) => { |
| 263 | break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Event { | 266 | break Ok(Tag::from_standardized(nostr_sdk::TagStandard::Event { |
| 264 | event_id: n.event_id, | 267 | event_id: n.event_id, |
| 265 | relay_url: n.relays.first().and_then(|url| RelayUrl::parse(url).ok()), | 268 | relay_url: n.relays.first().cloned(), |
| 266 | marker: Some(marker), | 269 | marker: Some(marker), |
| 267 | public_key: None, | 270 | public_key: None, |
| 268 | uppercase: false, | 271 | uppercase: false, |
| @@ -278,7 +281,11 @@ pub fn event_tag_from_nip19_or_hex( | |||
| 278 | })); | 281 | })); |
| 279 | } | 282 | } |
| 280 | Nip19::Coordinate(coordinate) => { | 283 | Nip19::Coordinate(coordinate) => { |
| 281 | break Ok(Tag::coordinate(coordinate)); | 284 | break Ok(Tag::from_standardized(TagStandard::Coordinate { |
| 285 | coordinate: coordinate.coordinate, | ||
| 286 | relay_url: coordinate.relays.first().cloned(), | ||
| 287 | uppercase: false, | ||
| 288 | })); | ||
| 282 | } | 289 | } |
| 283 | Nip19::Profile(profile) => { | 290 | Nip19::Profile(profile) => { |
| 284 | if allow_npub_reference { | 291 | if allow_npub_reference { |
| @@ -338,12 +345,17 @@ pub async fn generate_cover_letter_and_patch_events( | |||
| 338 | )) | 345 | )) |
| 339 | .tags( | 346 | .tags( |
| 340 | [ | 347 | [ |
| 341 | repo_ref.maintainers.iter().map(|m| Tag::coordinate(Coordinate { | 348 | repo_ref.maintainers.iter().map(|m| |
| 342 | kind: nostr::Kind::GitRepoAnnouncement, | 349 | Tag::from_standardized(TagStandard::Coordinate { |
| 343 | public_key: *m, | 350 | coordinate: Coordinate { |
| 344 | identifier: repo_ref.identifier.to_string(), | 351 | kind: nostr::Kind::GitRepoAnnouncement, |
| 345 | relays: repo_ref.relays.clone(), | 352 | public_key: *m, |
| 346 | })).collect::<Vec<Tag>>(), | 353 | identifier: repo_ref.identifier.to_string(), |
| 354 | }, | ||
| 355 | relay_url: repo_ref.relays.first().cloned(), | ||
| 356 | uppercase: false, | ||
| 357 | }) | ||
| 358 | ).collect::<Vec<Tag>>(), | ||
| 347 | vec![ | 359 | vec![ |
| 348 | Tag::from_standardized(TagStandard::Reference(format!("{root_commit}"))), | 360 | Tag::from_standardized(TagStandard::Reference(format!("{root_commit}"))), |
| 349 | Tag::hashtag("cover-letter"), | 361 | Tag::hashtag("cover-letter"), |
diff --git a/src/lib/login/existing.rs b/src/lib/login/existing.rs index efe187e..e60621d 100644 --- a/src/lib/login/existing.rs +++ b/src/lib/login/existing.rs | |||
| @@ -208,7 +208,7 @@ async fn get_signer( | |||
| 208 | Duration::from_secs(10 * 60), | 208 | Duration::from_secs(10 * 60), |
| 209 | None, | 209 | None, |
| 210 | )?; | 210 | )?; |
| 211 | if let Some(public_key) = npub.clone().and_then(|npub| PublicKey::parse(npub).ok()) { | 211 | if let Some(public_key) = npub.clone().and_then(|npub| PublicKey::parse(&npub).ok()) { |
| 212 | s.non_secure_set_user_public_key(public_key)?; | 212 | s.non_secure_set_user_public_key(public_key)?; |
| 213 | let signer: Arc<dyn NostrSigner> = Arc::new(s); | 213 | let signer: Arc<dyn NostrSigner> = Arc::new(s); |
| 214 | Ok((signer, public_key)) | 214 | Ok((signer, public_key)) |
diff --git a/src/lib/login/fresh.rs b/src/lib/login/fresh.rs index 635c0b3..76998ff 100644 --- a/src/lib/login/fresh.rs +++ b/src/lib/login/fresh.rs | |||
| @@ -372,7 +372,7 @@ pub fn generate_nostr_connect_app( | |||
| 372 | client | 372 | client |
| 373 | .get_fallback_signer_relays() | 373 | .get_fallback_signer_relays() |
| 374 | .iter() | 374 | .iter() |
| 375 | .flat_map(RelayUrl::parse) | 375 | .flat_map(|s| RelayUrl::parse(s)) |
| 376 | .collect::<Vec<RelayUrl>>() | 376 | .collect::<Vec<RelayUrl>>() |
| 377 | } else { | 377 | } else { |
| 378 | vec![] | 378 | vec![] |
diff --git a/src/lib/login/key_encryption.rs b/src/lib/login/key_encryption.rs index efb38d1..d57b3b5 100644 --- a/src/lib/login/key_encryption.rs +++ b/src/lib/login/key_encryption.rs | |||
| @@ -7,7 +7,7 @@ pub fn decrypt_key(encrypted_key: &str, password: &str) -> Result<nostr::Keys> { | |||
| 7 | if encrypted_key.log_n() > 14 { | 7 | if encrypted_key.log_n() > 14 { |
| 8 | println!("this may take a few seconds..."); | 8 | println!("this may take a few seconds..."); |
| 9 | } | 9 | } |
| 10 | Ok(nostr::Keys::new(encrypted_key.to_secret_key(password)?)) | 10 | Ok(nostr::Keys::new(encrypted_key.decrypt(password)?)) |
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | #[cfg(test)] | 13 | #[cfg(test)] |
diff --git a/src/lib/login/mod.rs b/src/lib/login/mod.rs index a1c45d5..c37375f 100644 --- a/src/lib/login/mod.rs +++ b/src/lib/login/mod.rs | |||
| @@ -93,7 +93,7 @@ pub async fn get_likely_logged_in_user(git_repo_path: &Path) -> Result<Option<Pu | |||
| 93 | let git_repo = Repo::from_path(&git_repo_path.to_path_buf())?; | 93 | let git_repo = Repo::from_path(&git_repo_path.to_path_buf())?; |
| 94 | Ok( | 94 | Ok( |
| 95 | if let Some(npub) = git_repo.get_git_config_item("nostr.npub", None)? { | 95 | if let Some(npub) = git_repo.get_git_config_item("nostr.npub", None)? { |
| 96 | if let Ok(pubic_key) = PublicKey::parse(npub) { | 96 | if let Ok(pubic_key) = PublicKey::parse(&npub) { |
| 97 | Some(pubic_key) | 97 | Some(pubic_key) |
| 98 | } else { | 98 | } else { |
| 99 | None | 99 | None |
| @@ -107,7 +107,7 @@ pub async fn get_likely_logged_in_user(git_repo_path: &Path) -> Result<Option<Pu | |||
| 107 | pub fn get_curent_user(git_repo: &Repo) -> Result<Option<PublicKey>> { | 107 | pub fn get_curent_user(git_repo: &Repo) -> Result<Option<PublicKey>> { |
| 108 | Ok( | 108 | Ok( |
| 109 | if let Some(npub) = git_repo.get_git_config_item("nostr.npub", None)? { | 109 | if let Some(npub) = git_repo.get_git_config_item("nostr.npub", None)? { |
| 110 | if let Ok(public_key) = PublicKey::parse(npub) { | 110 | if let Ok(public_key) = PublicKey::parse(&npub) { |
| 111 | Some(public_key) | 111 | Some(public_key) |
| 112 | } else { | 112 | } else { |
| 113 | None | 113 | None |
diff --git a/src/lib/repo_ref.rs b/src/lib/repo_ref.rs index 38f6774..b21a911 100644 --- a/src/lib/repo_ref.rs +++ b/src/lib/repo_ref.rs | |||
| @@ -8,7 +8,10 @@ use std::{ | |||
| 8 | 8 | ||
| 9 | use anyhow::{Context, Result, bail}; | 9 | use anyhow::{Context, Result, bail}; |
| 10 | use console::Style; | 10 | use console::Style; |
| 11 | use nostr::{FromBech32, PublicKey, Tag, TagStandard, ToBech32, nips::nip01::Coordinate}; | 11 | use nostr::{ |
| 12 | FromBech32, PublicKey, Tag, TagStandard, ToBech32, | ||
| 13 | nips::{nip01::Coordinate, nip19::Nip19Coordinate}, | ||
| 14 | }; | ||
| 12 | use nostr_sdk::{Kind, NostrSigner, RelayUrl, Timestamp}; | 15 | use nostr_sdk::{Kind, NostrSigner, RelayUrl, Timestamp}; |
| 13 | use serde::{Deserialize, Serialize}; | 16 | use serde::{Deserialize, Serialize}; |
| 14 | 17 | ||
| @@ -37,7 +40,7 @@ pub struct RepoRef { | |||
| 37 | pub relays: Vec<RelayUrl>, | 40 | pub relays: Vec<RelayUrl>, |
| 38 | pub maintainers: Vec<PublicKey>, | 41 | pub maintainers: Vec<PublicKey>, |
| 39 | pub trusted_maintainer: PublicKey, | 42 | pub trusted_maintainer: PublicKey, |
| 40 | pub events: HashMap<Coordinate, nostr::Event>, | 43 | pub events: HashMap<Nip19Coordinate, nostr::Event>, |
| 41 | pub nostr_git_url: Option<NostrUrlDecoded>, | 44 | pub nostr_git_url: Option<NostrUrlDecoded>, |
| 42 | } | 45 | } |
| 43 | 46 | ||
| @@ -119,10 +122,12 @@ impl TryFrom<(nostr::Event, Option<PublicKey>)> for RepoRef { | |||
| 119 | } | 122 | } |
| 120 | r.events = HashMap::new(); | 123 | r.events = HashMap::new(); |
| 121 | r.events.insert( | 124 | r.events.insert( |
| 122 | Coordinate { | 125 | Nip19Coordinate { |
| 123 | kind: event.kind, | 126 | coordinate: Coordinate { |
| 124 | identifier: event.tags.identifier().unwrap().to_string(), | 127 | kind: event.kind, |
| 125 | public_key: event.pubkey, | 128 | identifier: event.tags.identifier().unwrap().to_string(), |
| 129 | public_key: event.pubkey, | ||
| 130 | }, | ||
| 126 | relays: vec![], | 131 | relays: vec![], |
| 127 | }, | 132 | }, |
| 128 | event, | 133 | event, |
| @@ -195,20 +200,24 @@ impl RepoRef { | |||
| 195 | .context("failed to create repository reference event") | 200 | .context("failed to create repository reference event") |
| 196 | } | 201 | } |
| 197 | /// coordinates without relay hints | 202 | /// coordinates without relay hints |
| 198 | pub fn coordinates(&self) -> HashSet<Coordinate> { | 203 | pub fn coordinates(&self) -> HashSet<Nip19Coordinate> { |
| 199 | let mut res = HashSet::new(); | 204 | let mut res = HashSet::new(); |
| 200 | res.insert(Coordinate { | 205 | res.insert(Nip19Coordinate { |
| 201 | kind: Kind::GitRepoAnnouncement, | 206 | coordinate: Coordinate { |
| 202 | public_key: self.trusted_maintainer, | 207 | kind: Kind::GitRepoAnnouncement, |
| 203 | identifier: self.identifier.clone(), | 208 | public_key: self.trusted_maintainer, |
| 209 | identifier: self.identifier.clone(), | ||
| 210 | }, | ||
| 204 | relays: vec![], | 211 | relays: vec![], |
| 205 | }); | 212 | }); |
| 206 | 213 | ||
| 207 | for m in &self.maintainers { | 214 | for m in &self.maintainers { |
| 208 | res.insert(Coordinate { | 215 | res.insert(Nip19Coordinate { |
| 209 | kind: Kind::GitRepoAnnouncement, | 216 | coordinate: Coordinate { |
| 210 | public_key: *m, | 217 | kind: Kind::GitRepoAnnouncement, |
| 211 | identifier: self.identifier.clone(), | 218 | public_key: *m, |
| 219 | identifier: self.identifier.clone(), | ||
| 220 | }, | ||
| 212 | relays: vec![], | 221 | relays: vec![], |
| 213 | }); | 222 | }); |
| 214 | } | 223 | } |
| @@ -216,11 +225,13 @@ impl RepoRef { | |||
| 216 | } | 225 | } |
| 217 | 226 | ||
| 218 | /// coordinates without relay hints | 227 | /// coordinates without relay hints |
| 219 | pub fn coordinate_with_hint(&self) -> Coordinate { | 228 | pub fn coordinate_with_hint(&self) -> Nip19Coordinate { |
| 220 | Coordinate { | 229 | Nip19Coordinate { |
| 221 | kind: Kind::GitRepoAnnouncement, | 230 | coordinate: Coordinate { |
| 222 | public_key: self.trusted_maintainer, | 231 | kind: Kind::GitRepoAnnouncement, |
| 223 | identifier: self.identifier.clone(), | 232 | public_key: self.trusted_maintainer, |
| 233 | identifier: self.identifier.clone(), | ||
| 234 | }, | ||
| 224 | relays: if let Some(relay) = self.relays.first() { | 235 | relays: if let Some(relay) = self.relays.first() { |
| 225 | vec![relay.clone()] | 236 | vec![relay.clone()] |
| 226 | } else { | 237 | } else { |
| @@ -230,11 +241,11 @@ impl RepoRef { | |||
| 230 | } | 241 | } |
| 231 | 242 | ||
| 232 | /// coordinates without relay hints | 243 | /// coordinates without relay hints |
| 233 | pub fn coordinates_with_timestamps(&self) -> Vec<(Coordinate, Option<Timestamp>)> { | 244 | pub fn coordinates_with_timestamps(&self) -> Vec<(Nip19Coordinate, Option<Timestamp>)> { |
| 234 | self.coordinates() | 245 | self.coordinates() |
| 235 | .iter() | 246 | .iter() |
| 236 | .map(|c| (c.clone(), self.events.get(c).map(|e| e.created_at))) | 247 | .map(|c| (c.clone(), self.events.get(c).map(|e| e.created_at))) |
| 237 | .collect::<Vec<(Coordinate, Option<Timestamp>)>>() | 248 | .collect::<Vec<(Nip19Coordinate, Option<Timestamp>)>>() |
| 238 | } | 249 | } |
| 239 | 250 | ||
| 240 | pub fn set_nostr_git_url(&mut self, nostr_git_url: NostrUrlDecoded) { | 251 | pub fn set_nostr_git_url(&mut self, nostr_git_url: NostrUrlDecoded) { |
| @@ -264,7 +275,7 @@ pub async fn get_repo_coordinates_when_remote_unknown( | |||
| 264 | git_repo: &Repo, | 275 | git_repo: &Repo, |
| 265 | #[cfg(test)] client: &crate::client::MockConnect, | 276 | #[cfg(test)] client: &crate::client::MockConnect, |
| 266 | #[cfg(not(test))] client: &Client, | 277 | #[cfg(not(test))] client: &Client, |
| 267 | ) -> Result<Coordinate> { | 278 | ) -> Result<Nip19Coordinate> { |
| 268 | if let Ok(c) = try_and_get_repo_coordinates_when_remote_unknown(git_repo).await { | 279 | if let Ok(c) = try_and_get_repo_coordinates_when_remote_unknown(git_repo).await { |
| 269 | Ok(c) | 280 | Ok(c) |
| 270 | } else { | 281 | } else { |
| @@ -274,7 +285,7 @@ pub async fn get_repo_coordinates_when_remote_unknown( | |||
| 274 | 285 | ||
| 275 | pub async fn try_and_get_repo_coordinates_when_remote_unknown( | 286 | pub async fn try_and_get_repo_coordinates_when_remote_unknown( |
| 276 | git_repo: &Repo, | 287 | git_repo: &Repo, |
| 277 | ) -> Result<Coordinate> { | 288 | ) -> Result<Nip19Coordinate> { |
| 278 | let remote_coordinates = get_repo_coordinates_from_nostr_remotes(git_repo).await?; | 289 | let remote_coordinates = get_repo_coordinates_from_nostr_remotes(git_repo).await?; |
| 279 | if remote_coordinates.is_empty() { | 290 | if remote_coordinates.is_empty() { |
| 280 | if let Ok(c) = get_repo_coordinates_from_git_config(git_repo) { | 291 | if let Ok(c) = get_repo_coordinates_from_git_config(git_repo) { |
| @@ -318,7 +329,7 @@ pub async fn try_and_get_repo_coordinates_when_remote_unknown( | |||
| 318 | 329 | ||
| 319 | async fn get_nostr_git_remote_selection_labels( | 330 | async fn get_nostr_git_remote_selection_labels( |
| 320 | git_repo: &Repo, | 331 | git_repo: &Repo, |
| 321 | remote_coordinates: &HashMap<String, Coordinate>, | 332 | remote_coordinates: &HashMap<String, Nip19Coordinate>, |
| 322 | ) -> Result<Vec<String>> { | 333 | ) -> Result<Vec<String>> { |
| 323 | let mut res = vec![]; | 334 | let mut res = vec![]; |
| 324 | for (remote, c) in remote_coordinates { | 335 | for (remote, c) in remote_coordinates { |
| @@ -334,9 +345,9 @@ async fn get_nostr_git_remote_selection_labels( | |||
| 334 | Ok(res) | 345 | Ok(res) |
| 335 | } | 346 | } |
| 336 | 347 | ||
| 337 | fn get_repo_coordinates_from_git_config(git_repo: &Repo) -> Result<Coordinate> { | 348 | fn get_repo_coordinates_from_git_config(git_repo: &Repo) -> Result<Nip19Coordinate> { |
| 338 | Coordinate::parse( | 349 | Nip19Coordinate::from_bech32( |
| 339 | git_repo | 350 | &git_repo |
| 340 | .get_git_config_item("nostr.repo", Some(false))? | 351 | .get_git_config_item("nostr.repo", Some(false))? |
| 341 | .context("git config item \"nostr.repo\" is not set in local repository")?, | 352 | .context("git config item \"nostr.repo\" is not set in local repository")?, |
| 342 | ) | 353 | ) |
| @@ -345,7 +356,7 @@ fn get_repo_coordinates_from_git_config(git_repo: &Repo) -> Result<Coordinate> { | |||
| 345 | 356 | ||
| 346 | async fn get_repo_coordinates_from_nostr_remotes( | 357 | async fn get_repo_coordinates_from_nostr_remotes( |
| 347 | git_repo: &Repo, | 358 | git_repo: &Repo, |
| 348 | ) -> Result<HashMap<String, Coordinate>> { | 359 | ) -> Result<HashMap<String, Nip19Coordinate>> { |
| 349 | let mut repo_coordinates = HashMap::new(); | 360 | let mut repo_coordinates = HashMap::new(); |
| 350 | for remote_name in git_repo.git_repo.remotes()?.iter().flatten() { | 361 | for remote_name in git_repo.git_repo.remotes()?.iter().flatten() { |
| 351 | if let Some(remote_url) = git_repo.git_repo.find_remote(remote_name)?.url() { | 362 | if let Some(remote_url) = git_repo.git_repo.find_remote(remote_name)?.url() { |
| @@ -359,21 +370,23 @@ async fn get_repo_coordinates_from_nostr_remotes( | |||
| 359 | Ok(repo_coordinates) | 370 | Ok(repo_coordinates) |
| 360 | } | 371 | } |
| 361 | 372 | ||
| 362 | async fn get_repo_coordinates_from_maintainers_yaml(git_repo: &Repo) -> Result<Coordinate> { | 373 | async fn get_repo_coordinates_from_maintainers_yaml(git_repo: &Repo) -> Result<Nip19Coordinate> { |
| 363 | let repo_config = get_repo_config_from_yaml(git_repo)?; | 374 | let repo_config = get_repo_config_from_yaml(git_repo)?; |
| 364 | 375 | ||
| 365 | Ok(Coordinate { | 376 | Ok(Nip19Coordinate { |
| 366 | identifier: repo_config | 377 | coordinate: Coordinate { |
| 367 | .identifier | 378 | identifier: repo_config |
| 368 | .context("maintainers.yaml doesnt list the identifier")?, | 379 | .identifier |
| 369 | kind: Kind::GitRepoAnnouncement, | 380 | .context("maintainers.yaml doesnt list the identifier")?, |
| 370 | public_key: PublicKey::from_bech32( | 381 | kind: Kind::GitRepoAnnouncement, |
| 371 | repo_config | 382 | public_key: PublicKey::from_bech32( |
| 372 | .maintainers | 383 | repo_config |
| 373 | .first() | 384 | .maintainers |
| 374 | .context("maintainers.yaml doesnt list any maintainers")?, | 385 | .first() |
| 375 | ) | 386 | .context("maintainers.yaml doesnt list any maintainers")?, |
| 376 | .context("maintainers.yaml doesn't list the first maintainer using a valid npub")?, | 387 | ) |
| 388 | .context("maintainers.yaml doesn't list the first maintainer using a valid npub")?, | ||
| 389 | }, | ||
| 377 | relays: repo_config | 390 | relays: repo_config |
| 378 | .relays | 391 | .relays |
| 379 | .iter() | 392 | .iter() |
| @@ -386,7 +399,7 @@ async fn get_repo_coordinate_from_user_prompt( | |||
| 386 | git_repo: &Repo, | 399 | git_repo: &Repo, |
| 387 | #[cfg(test)] client: &crate::client::MockConnect, | 400 | #[cfg(test)] client: &crate::client::MockConnect, |
| 388 | #[cfg(not(test))] client: &Client, | 401 | #[cfg(not(test))] client: &Client, |
| 389 | ) -> Result<Coordinate> { | 402 | ) -> Result<Nip19Coordinate> { |
| 390 | // TODO: present list of events filter by root_commit | 403 | // TODO: present list of events filter by root_commit |
| 391 | // TODO: fallback to search based on identifier | 404 | // TODO: fallback to search based on identifier |
| 392 | let dim = Style::new().color256(247); | 405 | let dim = Style::new().color256(247); |
| @@ -401,7 +414,7 @@ async fn get_repo_coordinate_from_user_prompt( | |||
| 401 | loop { | 414 | loop { |
| 402 | let input = Interactor::default() | 415 | let input = Interactor::default() |
| 403 | .input(PromptInputParms::default().with_prompt("nostr repository"))?; | 416 | .input(PromptInputParms::default().with_prompt("nostr repository"))?; |
| 404 | let coordinate = if let Ok(c) = Coordinate::parse(&input) { | 417 | let coordinate = if let Ok(c) = Nip19Coordinate::from_bech32(&input) { |
| 405 | c | 418 | c |
| 406 | } else if let Ok(nostr_url) = | 419 | } else if let Ok(nostr_url) = |
| 407 | NostrUrlDecoded::parse_and_resolve(&input, &Some(git_repo)).await | 420 | NostrUrlDecoded::parse_and_resolve(&input, &Some(git_repo)).await |
| @@ -491,7 +504,7 @@ pub fn extract_pks(pk_strings: Vec<String>) -> Result<Vec<PublicKey>> { | |||
| 491 | let mut pks: Vec<PublicKey> = vec![]; | 504 | let mut pks: Vec<PublicKey> = vec![]; |
| 492 | for s in pk_strings { | 505 | for s in pk_strings { |
| 493 | pks.push( | 506 | pks.push( |
| 494 | nostr_sdk::prelude::PublicKey::from_bech32(s.clone()).context(format!( | 507 | nostr_sdk::prelude::PublicKey::from_bech32(&s).context(format!( |
| 495 | "failed to convert {s} into a valid nostr public key" | 508 | "failed to convert {s} into a valid nostr public key" |
| 496 | ))?, | 509 | ))?, |
| 497 | ); | 510 | ); |
diff --git a/test_utils/Cargo.toml b/test_utils/Cargo.toml index b354ff4..951bd39 100644 --- a/test_utils/Cargo.toml +++ b/test_utils/Cargo.toml | |||
| @@ -10,10 +10,10 @@ dialoguer = "0.10.4" | |||
| 10 | directories = "5.0.1" | 10 | directories = "5.0.1" |
| 11 | futures = "0.3.28" | 11 | futures = "0.3.28" |
| 12 | git2 = "0.19.0" | 12 | git2 = "0.19.0" |
| 13 | nostr = "0.37.0" | 13 | nostr = "0.40.0" |
| 14 | nostr-database = "0.37.0" | 14 | nostr-database = "0.40.0" |
| 15 | nostr-lmdb = "0.37.0" | 15 | nostr-lmdb = "0.40.0" |
| 16 | nostr-sdk = "0.37.0" | 16 | nostr-sdk = "0.40.0" |
| 17 | once_cell = "1.18.0" | 17 | once_cell = "1.18.0" |
| 18 | rand = "0.8" | 18 | rand = "0.8" |
| 19 | rexpect = { git = "https://github.com/rust-cli/rexpect.git", rev = "9eb61dd" } | 19 | rexpect = { git = "https://github.com/rust-cli/rexpect.git", rev = "9eb61dd" } |
diff --git a/test_utils/src/git.rs b/test_utils/src/git.rs index 474fc59..5942a54 100644 --- a/test_utils/src/git.rs +++ b/test_utils/src/git.rs | |||
| @@ -9,7 +9,7 @@ use std::{ | |||
| 9 | 9 | ||
| 10 | use anyhow::{Context, Result}; | 10 | use anyhow::{Context, Result}; |
| 11 | use git2::{Branch, Oid, RepositoryInitOptions, Signature, Time}; | 11 | use git2::{Branch, Oid, RepositoryInitOptions, Signature, Time}; |
| 12 | use nostr::nips::nip01::Coordinate; | 12 | use nostr::nips::{nip01::Coordinate, nip19::Nip19Coordinate}; |
| 13 | use nostr_sdk::{Kind, RelayUrl, ToBech32}; | 13 | use nostr_sdk::{Kind, RelayUrl, ToBech32}; |
| 14 | 14 | ||
| 15 | use crate::generate_repo_ref_event; | 15 | use crate::generate_repo_ref_event; |
| @@ -23,10 +23,12 @@ pub struct GitTestRepo { | |||
| 23 | impl Default for GitTestRepo { | 23 | impl Default for GitTestRepo { |
| 24 | fn default() -> Self { | 24 | fn default() -> Self { |
| 25 | let repo_event = generate_repo_ref_event(); | 25 | let repo_event = generate_repo_ref_event(); |
| 26 | let coordinate = Coordinate { | 26 | let coordinate = Nip19Coordinate { |
| 27 | kind: Kind::GitRepoAnnouncement, | 27 | coordinate: Coordinate { |
| 28 | public_key: repo_event.pubkey, | 28 | kind: Kind::GitRepoAnnouncement, |
| 29 | identifier: repo_event.tags.identifier().unwrap().to_string(), | 29 | public_key: repo_event.pubkey, |
| 30 | identifier: repo_event.tags.identifier().unwrap().to_string(), | ||
| 31 | }, | ||
| 30 | relays: vec![ | 32 | relays: vec![ |
| 31 | RelayUrl::parse("ws://localhost:8055").unwrap(), | 33 | RelayUrl::parse("ws://localhost:8055").unwrap(), |
| 32 | RelayUrl::parse("ws://localhost:8056").unwrap(), | 34 | RelayUrl::parse("ws://localhost:8056").unwrap(), |
diff --git a/test_utils/src/lib.rs b/test_utils/src/lib.rs index 5c8d7a5..66d0df5 100644 --- a/test_utils/src/lib.rs +++ b/test_utils/src/lib.rs | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | use std::{ | 1 | use std::{ |
| 2 | collections::HashSet, | ||
| 2 | ffi::OsStr, | 3 | ffi::OsStr, |
| 3 | path::{Path, PathBuf}, | 4 | path::{Path, PathBuf}, |
| 4 | str::FromStr, | 5 | str::FromStr, |
| @@ -8,13 +9,13 @@ use std::{ | |||
| 8 | 9 | ||
| 9 | use anyhow::{Context, Result, bail, ensure}; | 10 | use anyhow::{Context, Result, bail, ensure}; |
| 10 | use dialoguer::theme::{ColorfulTheme, Theme}; | 11 | use dialoguer::theme::{ColorfulTheme, Theme}; |
| 11 | use futures::executor::block_on; | 12 | use futures::{executor::block_on, future::join_all}; |
| 12 | use git::GitTestRepo; | 13 | use git::GitTestRepo; |
| 13 | use git2::{Signature, Time}; | 14 | use git2::{Signature, Time}; |
| 14 | use nostr::{self, Kind, Tag, nips::nip65::RelayMetadata}; | 15 | use nostr::{self, Kind, Tag, nips::nip65::RelayMetadata}; |
| 15 | use nostr_database::NostrEventsDatabase; | 16 | use nostr_database::NostrEventsDatabase; |
| 16 | use nostr_lmdb::NostrLMDB; | 17 | use nostr_lmdb::NostrLMDB; |
| 17 | use nostr_sdk::{Client, NostrSigner, TagStandard, serde_json}; | 18 | use nostr_sdk::{Client, Event, NostrSigner, TagStandard, serde_json}; |
| 18 | use once_cell::sync::Lazy; | 19 | use once_cell::sync::Lazy; |
| 19 | use rexpect::session::{Options, PtySession}; | 20 | use rexpect::session::{Options, PtySession}; |
| 20 | use strip_ansi_escapes::strip_str; | 21 | use strip_ansi_escapes::strip_str; |
| @@ -139,7 +140,7 @@ pub fn make_event_old_or_change_user( | |||
| 139 | &keys.public_key(), | 140 | &keys.public_key(), |
| 140 | &unsigned.created_at, | 141 | &unsigned.created_at, |
| 141 | &unsigned.kind, | 142 | &unsigned.kind, |
| 142 | &unsigned.tags.clone().to_vec(), | 143 | &unsigned.tags.clone(), |
| 143 | &unsigned.content, | 144 | &unsigned.content, |
| 144 | )); | 145 | )); |
| 145 | 146 | ||
| @@ -1107,14 +1108,24 @@ pub async fn get_events_from_cache( | |||
| 1107 | git_repo_path: &Path, | 1108 | git_repo_path: &Path, |
| 1108 | filters: Vec<nostr::Filter>, | 1109 | filters: Vec<nostr::Filter>, |
| 1109 | ) -> Result<Vec<nostr::Event>> { | 1110 | ) -> Result<Vec<nostr::Event>> { |
| 1110 | Ok(get_local_cache_database(git_repo_path) | 1111 | let db = get_local_cache_database(git_repo_path).await?; |
| 1111 | .await? | 1112 | |
| 1112 | .query(filters.clone()) | 1113 | let query_results = join_all(filters.into_iter().map(|filter| async { |
| 1113 | .await | 1114 | db.query(filter).await.context( |
| 1114 | .context( | ||
| 1115 | "failed to execute query on opened git repo nostr cache database .git/nostr-cache.lmdb", | 1115 | "failed to execute query on opened git repo nostr cache database .git/nostr-cache.lmdb", |
| 1116 | )? | 1116 | ) |
| 1117 | .to_vec()) | 1117 | })) |
| 1118 | .await; | ||
| 1119 | |||
| 1120 | // no Event is being mutated, just new items added to the set | ||
| 1121 | #[allow(clippy::mutable_key_type)] | ||
| 1122 | let mut events: HashSet<Event> = HashSet::new(); | ||
| 1123 | |||
| 1124 | for result in query_results { | ||
| 1125 | events.extend(result?); | ||
| 1126 | } | ||
| 1127 | |||
| 1128 | Ok(events.into_iter().collect()) | ||
| 1118 | } | 1129 | } |
| 1119 | 1130 | ||
| 1120 | pub fn get_proposal_branch_name( | 1131 | pub fn get_proposal_branch_name( |
| @@ -1436,19 +1447,18 @@ fn get_first_proposal_event_id() -> Result<nostr::EventId> { | |||
| 1436 | Handle::current().block_on(client.add_relay("ws://localhost:8055"))?; | 1447 | Handle::current().block_on(client.add_relay("ws://localhost:8055"))?; |
| 1437 | Handle::current().block_on(client.connect_relay("ws://localhost:8055"))?; | 1448 | Handle::current().block_on(client.connect_relay("ws://localhost:8055"))?; |
| 1438 | let proposals = Handle::current() | 1449 | let proposals = Handle::current() |
| 1439 | .block_on(client.fetch_events( | 1450 | .block_on( |
| 1440 | vec![ | 1451 | client.fetch_events( |
| 1441 | nostr::Filter::default() | 1452 | nostr::Filter::default() |
| 1442 | .kind(nostr::Kind::GitPatch) | 1453 | .kind(nostr::Kind::GitPatch) |
| 1443 | .custom_tag( | 1454 | .custom_tags(nostr::SingleLetterTag::lowercase(nostr::Alphabet::T), vec![ |
| 1444 | nostr::SingleLetterTag::lowercase(nostr::Alphabet::T), | 1455 | "root", |
| 1445 | vec!["root"], | 1456 | ]), |
| 1446 | ), | 1457 | Duration::from_millis(500), |
| 1447 | ], | 1458 | ), |
| 1448 | Some(Duration::from_millis(500)), | 1459 | )? |
| 1449 | ))? | ||
| 1450 | .to_vec(); | 1460 | .to_vec(); |
| 1451 | Handle::current().block_on(client.disconnect())?; | 1461 | Handle::current().block_on(client.disconnect()); |
| 1452 | 1462 | ||
| 1453 | let proposal_1_id = proposals | 1463 | let proposal_1_id = proposals |
| 1454 | .iter() | 1464 | .iter() |
diff --git a/test_utils/src/relay.rs b/test_utils/src/relay.rs index 634b2d6..e820651 100644 --- a/test_utils/src/relay.rs +++ b/test_utils/src/relay.rs | |||
| @@ -48,7 +48,7 @@ impl<'a> Relay<'a> { | |||
| 48 | let ok_json = RelayMessage::Ok { | 48 | let ok_json = RelayMessage::Ok { |
| 49 | event_id: event.id, | 49 | event_id: event.id, |
| 50 | status: error.is_none(), | 50 | status: error.is_none(), |
| 51 | message: error.unwrap_or("").to_string(), | 51 | message: error.unwrap_or("").to_string().into(), |
| 52 | } | 52 | } |
| 53 | .as_json(); | 53 | .as_json(); |
| 54 | // bail!(format!("{}", &ok_json)); | 54 | // bail!(format!("{}", &ok_json)); |
| @@ -63,7 +63,7 @@ impl<'a> Relay<'a> { | |||
| 63 | let responder = self.clients.get(&client_id).unwrap(); | 63 | let responder = self.clients.get(&client_id).unwrap(); |
| 64 | 64 | ||
| 65 | Ok(responder.send(simple_websockets::Message::Text( | 65 | Ok(responder.send(simple_websockets::Message::Text( |
| 66 | RelayMessage::EndOfStoredEvents(subscription_id).as_json(), | 66 | RelayMessage::EndOfStoredEvents(std::borrow::Cow::Borrowed(&subscription_id)).as_json(), |
| 67 | ))) | 67 | ))) |
| 68 | } | 68 | } |
| 69 | 69 | ||
| @@ -79,8 +79,8 @@ impl<'a> Relay<'a> { | |||
| 79 | for event in events { | 79 | for event in events { |
| 80 | let res = responder.send(simple_websockets::Message::Text( | 80 | let res = responder.send(simple_websockets::Message::Text( |
| 81 | RelayMessage::Event { | 81 | RelayMessage::Event { |
| 82 | subscription_id: subscription_id.clone(), | 82 | subscription_id: std::borrow::Cow::Borrowed(subscription_id), |
| 83 | event: Box::new(event.clone()), | 83 | event: std::borrow::Cow::Borrowed(event), |
| 84 | } | 84 | } |
| 85 | .as_json(), | 85 | .as_json(), |
| 86 | )); | 86 | )); |
| @@ -156,12 +156,14 @@ impl<'a> Relay<'a> { | |||
| 156 | } | 156 | } |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | if let Ok((subscription_id, filters)) = get_nreq(&message) { | 159 | if let Ok((subscription_id, filter)) = get_nreq(&message) { |
| 160 | self.reqs.push(filters.clone()); | 160 | self.reqs.push(vec![filter.clone()]); |
| 161 | if let Some(listner) = self.req_listener { | 161 | if let Some(listner) = self.req_listener { |
| 162 | listner(self, client_id, subscription_id, filters)?; | 162 | listner(self, client_id, subscription_id, vec![filter.clone()])?; |
| 163 | } else { | 163 | } else { |
| 164 | self.respond_standard_req(client_id, &subscription_id, &filters)?; | 164 | self.respond_standard_req(client_id, &subscription_id, &[ |
| 165 | filter.clone() | ||
| 166 | ])?; | ||
| 165 | // self.respond_eose(client_id, subscription_id)?; | 167 | // self.respond_eose(client_id, subscription_id)?; |
| 166 | } | 168 | } |
| 167 | // respond with events | 169 | // respond with events |
| @@ -198,8 +200,7 @@ fn get_nevent(message: &simple_websockets::Message) -> Result<nostr::Event> { | |||
| 198 | if let simple_websockets::Message::Text(s) = message.clone() { | 200 | if let simple_websockets::Message::Text(s) = message.clone() { |
| 199 | let cm_result = ClientMessage::from_json(s); | 201 | let cm_result = ClientMessage::from_json(s); |
| 200 | if let Ok(ClientMessage::Event(event)) = cm_result { | 202 | if let Ok(ClientMessage::Event(event)) = cm_result { |
| 201 | let e = *event; | 203 | return Ok(event.into_owned()); |
| 202 | return Ok(e.clone()); | ||
| 203 | } | 204 | } |
| 204 | } | 205 | } |
| 205 | bail!("not nostr event") | 206 | bail!("not nostr event") |
| @@ -207,15 +208,15 @@ fn get_nevent(message: &simple_websockets::Message) -> Result<nostr::Event> { | |||
| 207 | 208 | ||
| 208 | fn get_nreq( | 209 | fn get_nreq( |
| 209 | message: &simple_websockets::Message, | 210 | message: &simple_websockets::Message, |
| 210 | ) -> Result<(nostr::SubscriptionId, Vec<nostr::Filter>)> { | 211 | ) -> Result<(nostr::SubscriptionId, nostr::Filter)> { |
| 211 | if let simple_websockets::Message::Text(s) = message.clone() { | 212 | if let simple_websockets::Message::Text(s) = message.clone() { |
| 212 | let cm_result = ClientMessage::from_json(s); | 213 | let cm_result = ClientMessage::from_json(s); |
| 213 | if let Ok(ClientMessage::Req { | 214 | if let Ok(ClientMessage::Req { |
| 214 | subscription_id, | 215 | subscription_id, |
| 215 | filters, | 216 | filter, |
| 216 | }) = cm_result | 217 | }) = cm_result |
| 217 | { | 218 | { |
| 218 | return Ok((subscription_id, filters)); | 219 | return Ok((subscription_id.into_owned(), filter.into_owned())); |
| 219 | } | 220 | } |
| 220 | } | 221 | } |
| 221 | bail!("not nostr event") | 222 | bail!("not nostr event") |
diff --git a/tests/git_remote_nostr/main.rs b/tests/git_remote_nostr/main.rs index 686a5df..6b51825 100644 --- a/tests/git_remote_nostr/main.rs +++ b/tests/git_remote_nostr/main.rs | |||
| @@ -3,7 +3,7 @@ use std::{collections::HashSet, env::current_dir}; | |||
| 3 | use anyhow::{Context, Result}; | 3 | use anyhow::{Context, Result}; |
| 4 | use futures::join; | 4 | use futures::join; |
| 5 | use git2::Oid; | 5 | use git2::Oid; |
| 6 | use nostr::nips::nip01::Coordinate; | 6 | use nostr::nips::{nip01::Coordinate, nip19::Nip19Coordinate}; |
| 7 | use nostr_sdk::{Event, JsonUtil, Kind, RelayUrl, ToBech32, secp256k1::rand}; | 7 | use nostr_sdk::{Event, JsonUtil, Kind, RelayUrl, ToBech32, secp256k1::rand}; |
| 8 | use relay::Relay; | 8 | use relay::Relay; |
| 9 | use serial_test::serial; | 9 | use serial_test::serial; |
| @@ -18,10 +18,12 @@ static STATE_KIND: nostr::Kind = Kind::Custom(30618); | |||
| 18 | 18 | ||
| 19 | fn get_nostr_remote_url() -> Result<String> { | 19 | fn get_nostr_remote_url() -> Result<String> { |
| 20 | let repo_event = generate_repo_ref_event(); | 20 | let repo_event = generate_repo_ref_event(); |
| 21 | let naddr = Coordinate { | 21 | let naddr = Nip19Coordinate { |
| 22 | kind: Kind::GitRepoAnnouncement, | 22 | coordinate: Coordinate { |
| 23 | public_key: repo_event.pubkey, | 23 | kind: Kind::GitRepoAnnouncement, |
| 24 | identifier: repo_event.tags.identifier().unwrap().to_string(), | 24 | public_key: repo_event.pubkey, |
| 25 | identifier: repo_event.tags.identifier().unwrap().to_string(), | ||
| 26 | }, | ||
| 25 | relays: vec![ | 27 | relays: vec![ |
| 26 | RelayUrl::parse("ws://localhost:8055").unwrap(), | 28 | RelayUrl::parse("ws://localhost:8055").unwrap(), |
| 27 | RelayUrl::parse("ws://localhost:8056").unwrap(), | 29 | RelayUrl::parse("ws://localhost:8056").unwrap(), |
diff --git a/tests/ngit_init.rs b/tests/ngit_init.rs index 4b61559..409bd51 100644 --- a/tests/ngit_init.rs +++ b/tests/ngit_init.rs | |||
| @@ -194,7 +194,7 @@ mod when_repo_not_previously_claimed { | |||
| 194 | 194 | ||
| 195 | mod git_config_updated { | 195 | mod git_config_updated { |
| 196 | 196 | ||
| 197 | use nostr::nips::nip01::Coordinate; | 197 | use nostr::nips::{nip01::Coordinate, nip19::Nip19Coordinate}; |
| 198 | use nostr_sdk::ToBech32; | 198 | use nostr_sdk::ToBech32; |
| 199 | 199 | ||
| 200 | use super::*; | 200 | use super::*; |
| @@ -236,10 +236,12 @@ mod when_repo_not_previously_claimed { | |||
| 236 | .get_entry("nostr.repo")? | 236 | .get_entry("nostr.repo")? |
| 237 | .value() | 237 | .value() |
| 238 | .unwrap(), | 238 | .unwrap(), |
| 239 | Coordinate { | 239 | Nip19Coordinate { |
| 240 | kind: nostr_sdk::Kind::GitRepoAnnouncement, | 240 | coordinate: Coordinate { |
| 241 | identifier: "example-identifier".to_string(), | 241 | kind: nostr_sdk::Kind::GitRepoAnnouncement, |
| 242 | public_key: TEST_KEY_1_KEYS.public_key(), | 242 | identifier: "example-identifier".to_string(), |
| 243 | public_key: TEST_KEY_1_KEYS.public_key(), | ||
| 244 | }, | ||
| 243 | relays: vec![], | 245 | relays: vec![], |
| 244 | } | 246 | } |
| 245 | .to_bech32()?, | 247 | .to_bech32()?, |
diff --git a/tests/ngit_list.rs b/tests/ngit_list.rs index 4a3aad5..bb742cf 100644 --- a/tests/ngit_list.rs +++ b/tests/ngit_list.rs | |||
| @@ -49,7 +49,10 @@ async fn prep_proposals_repo_and_repo_with_proposal_pulled_and_checkedout( | |||
| 49 | mod cannot_find_repo_event { | 49 | mod cannot_find_repo_event { |
| 50 | use super::*; | 50 | use super::*; |
| 51 | mod cli_prompts { | 51 | mod cli_prompts { |
| 52 | use nostr::{ToBech32, nips::nip01::Coordinate}; | 52 | use nostr::{ |
| 53 | ToBech32, | ||
| 54 | nips::{nip01::Coordinate, nip19::Nip19Coordinate}, | ||
| 55 | }; | ||
| 53 | use nostr_sdk::RelayUrl; | 56 | use nostr_sdk::RelayUrl; |
| 54 | 57 | ||
| 55 | use super::*; | 58 | use super::*; |
| @@ -87,10 +90,12 @@ mod cannot_find_repo_event { | |||
| 87 | } | 90 | } |
| 88 | if naddr { | 91 | if naddr { |
| 89 | let mut input = p.expect_input("nostr repository")?; | 92 | let mut input = p.expect_input("nostr repository")?; |
| 90 | let coordinate = Coordinate { | 93 | let coordinate = Nip19Coordinate { |
| 91 | kind: nostr::Kind::GitRepoAnnouncement, | 94 | coordinate: Coordinate { |
| 92 | public_key: TEST_KEY_1_KEYS.public_key(), | 95 | kind: nostr::Kind::GitRepoAnnouncement, |
| 93 | identifier: repo_event.tags.identifier().unwrap().to_string(), | 96 | public_key: TEST_KEY_1_KEYS.public_key(), |
| 97 | identifier: repo_event.tags.identifier().unwrap().to_string(), | ||
| 98 | }, | ||
| 94 | relays: vec![RelayUrl::parse("ws://localhost:8056").unwrap()], | 99 | relays: vec![RelayUrl::parse("ws://localhost:8056").unwrap()], |
| 95 | }; | 100 | }; |
| 96 | input.succeeds_with(&coordinate.to_bech32()?)?; | 101 | input.succeeds_with(&coordinate.to_bech32()?)?; |