upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2024-03-28 12:35:37 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2024-03-28 12:35:37 +0000
commit4b06b2bd70d37656d727c8fffc0656c1aa3c7b97 (patch)
tree1d885fdef21a7530c1a91f848788a665d6fc9948
parent91a68de459b7d22a8dfb8a324e43740fca3e0a35 (diff)
parent11dc9fa2d8b82594d3803f12d2c5a49e57026cfb (diff)
Merge upgrade rust-nostr v0.29
refactor to address breaking changes in rust-nostr fix a number of in dependancy which have been upstreamed
-rw-r--r--.github/workflows/build_test.yaml30
-rw-r--r--.github/workflows/check_rustfmt_clippy.yaml26
-rw-r--r--.github/workflows/clippy_rustfmt_test.yaml16
-rw-r--r--Cargo.lock313
-rw-r--r--Cargo.toml4
-rw-r--r--src/client.rs11
-rw-r--r--src/config.rs6
-rw-r--r--src/git.rs2
-rw-r--r--src/key_handling/encryption.rs12
-rw-r--r--src/key_handling/users.rs24
-rw-r--r--src/login.rs8
-rw-r--r--src/repo_ref.rs19
-rw-r--r--src/sub_commands/init.rs10
-rw-r--r--src/sub_commands/list.rs12
-rw-r--r--src/sub_commands/push.rs2
-rw-r--r--src/sub_commands/send.rs30
-rw-r--r--test_utils/Cargo.toml4
-rw-r--r--test_utils/src/lib.rs8
-rw-r--r--tests/list.rs238
-rw-r--r--tests/pull.rs162
20 files changed, 584 insertions, 353 deletions
diff --git a/.github/workflows/build_test.yaml b/.github/workflows/build_test.yaml
deleted file mode 100644
index 5d2555d..0000000
--- a/.github/workflows/build_test.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
1on: push
2
3name: build test
4
5jobs:
6 ci:
7 runs-on: ubuntu-latest
8 timeout-minutes: 8
9 strategy:
10 matrix:
11 rust:
12 - stable
13 - nightly
14
15 steps:
16 - uses: actions/checkout@v2
17
18 - uses: actions-rs/toolchain@v1
19 with:
20 profile: minimal
21 toolchain: ${{ matrix.rust }}
22 override: true
23
24 - uses: actions-rs/cargo@v1
25 with:
26 command: build
27
28 - uses: actions-rs/cargo@v1
29 with:
30 command: test
diff --git a/.github/workflows/check_rustfmt_clippy.yaml b/.github/workflows/check_rustfmt_clippy.yaml
deleted file mode 100644
index eec744e..0000000
--- a/.github/workflows/check_rustfmt_clippy.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
1on: push
2
3name: check rustfmt
4
5jobs:
6 ci:
7 runs-on: ubuntu-latest
8 strategy:
9 matrix:
10 rust:
11 - nightly
12
13 steps:
14 - uses: actions/checkout@v2
15
16 - uses: actions-rs/toolchain@v1
17 with:
18 profile: minimal
19 toolchain: ${{ matrix.rust }}
20 override: true
21 components: rustfmt
22
23 - uses: actions-rs/cargo@v1
24 with:
25 command: fmt
26 args: --all -- --check
diff --git a/.github/workflows/clippy_rustfmt_test.yaml b/.github/workflows/clippy_rustfmt_test.yaml
new file mode 100644
index 0000000..5253814
--- /dev/null
+++ b/.github/workflows/clippy_rustfmt_test.yaml
@@ -0,0 +1,16 @@
1on: push
2
3name: build test
4
5jobs:
6 ci:
7 runs-on: ubuntu-latest
8 timeout-minutes: 8
9 steps:
10 - uses: actions/checkout@v3
11 - uses: cachix/install-nix-action@v22
12 with:
13 nix_path: nixpkgs=channel:nixos-unstable
14 - run: nix develop --command cargo clippy
15 - run: nix develop --command cargo fmt --all -- --check
16 - run: nix develop --command cargo test
diff --git a/Cargo.lock b/Cargo.lock
index 97614fa..a3f3cc1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -51,6 +51,18 @@ dependencies = [
51] 51]
52 52
53[[package]] 53[[package]]
54name = "ahash"
55version = "0.8.11"
56source = "registry+https://github.com/rust-lang/crates.io-index"
57checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
58dependencies = [
59 "cfg-if",
60 "once_cell",
61 "version_check",
62 "zerocopy",
63]
64
65[[package]]
54name = "aho-corasick" 66name = "aho-corasick"
55version = "1.1.3" 67version = "1.1.3"
56source = "registry+https://github.com/rust-lang/crates.io-index" 68source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -60,6 +72,12 @@ dependencies = [
60] 72]
61 73
62[[package]] 74[[package]]
75name = "allocator-api2"
76version = "0.2.16"
77source = "registry+https://github.com/rust-lang/crates.io-index"
78checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
79
80[[package]]
63name = "anstream" 81name = "anstream"
64version = "0.6.13" 82version = "0.6.13"
65source = "registry+https://github.com/rust-lang/crates.io-index" 83source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -301,9 +319,9 @@ dependencies = [
301 319
302[[package]] 320[[package]]
303name = "async-utility" 321name = "async-utility"
304version = "0.1.1" 322version = "0.2.0"
305source = "registry+https://github.com/rust-lang/crates.io-index" 323source = "registry+https://github.com/rust-lang/crates.io-index"
306checksum = "3716c0d3970fe92d79a8f4cda2caf91113574505dff5b18e455e549d4b078e98" 324checksum = "a349201d80b4aa18d17a34a182bdd7f8ddf845e9e57d2ea130a12e10ef1e3a47"
307dependencies = [ 325dependencies = [
308 "futures-util", 326 "futures-util",
309 "gloo-timers", 327 "gloo-timers",
@@ -313,20 +331,20 @@ dependencies = [
313 331
314[[package]] 332[[package]]
315name = "async-wsocket" 333name = "async-wsocket"
316version = "0.1.0" 334version = "0.3.0"
317source = "registry+https://github.com/rust-lang/crates.io-index" 335source = "registry+https://github.com/rust-lang/crates.io-index"
318checksum = "82d55992e9155e571208dc012c2a5c056572d1ab167bc299a63810ebf910226c" 336checksum = "d253e375ea899cb131b92a474587e217634e7ea927c24d8098eecbcad0c5c97a"
319dependencies = [ 337dependencies = [
320 "async-utility", 338 "async-utility",
321 "futures-util", 339 "futures-util",
322 "thiserror", 340 "thiserror",
323 "tokio", 341 "tokio",
324 "tokio-rustls", 342 "tokio-rustls 0.25.0",
325 "tokio-socks", 343 "tokio-socks",
326 "tokio-tungstenite", 344 "tokio-tungstenite 0.21.0",
327 "url-fork", 345 "url",
328 "wasm-ws", 346 "wasm-ws",
329 "webpki-roots", 347 "webpki-roots 0.26.1",
330] 348]
331 349
332[[package]] 350[[package]]
@@ -341,6 +359,15 @@ dependencies = [
341] 359]
342 360
343[[package]] 361[[package]]
362name = "atomic-destructor"
363version = "0.1.1"
364source = "registry+https://github.com/rust-lang/crates.io-index"
365checksum = "4653a42bf04120a1d4e92452e006b4e3af4ab4afff8fb4af0f1bbb98418adf3e"
366dependencies = [
367 "tracing",
368]
369
370[[package]]
344name = "atomic-waker" 371name = "atomic-waker"
345version = "1.1.2" 372version = "1.1.2"
346source = "registry+https://github.com/rust-lang/crates.io-index" 373source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1169,7 +1196,7 @@ dependencies = [
1169 "futures-core", 1196 "futures-core",
1170 "futures-sink", 1197 "futures-sink",
1171 "futures-util", 1198 "futures-util",
1172 "http", 1199 "http 0.2.12",
1173 "indexmap", 1200 "indexmap",
1174 "slab", 1201 "slab",
1175 "tokio", 1202 "tokio",
@@ -1182,6 +1209,10 @@ name = "hashbrown"
1182version = "0.14.3" 1209version = "0.14.3"
1183source = "registry+https://github.com/rust-lang/crates.io-index" 1210source = "registry+https://github.com/rust-lang/crates.io-index"
1184checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 1211checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
1212dependencies = [
1213 "ahash",
1214 "allocator-api2",
1215]
1185 1216
1186[[package]] 1217[[package]]
1187name = "heck" 1218name = "heck"
@@ -1243,13 +1274,24 @@ dependencies = [
1243] 1274]
1244 1275
1245[[package]] 1276[[package]]
1277name = "http"
1278version = "1.1.0"
1279source = "registry+https://github.com/rust-lang/crates.io-index"
1280checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
1281dependencies = [
1282 "bytes",
1283 "fnv",
1284 "itoa",
1285]
1286
1287[[package]]
1246name = "http-body" 1288name = "http-body"
1247version = "0.4.6" 1289version = "0.4.6"
1248source = "registry+https://github.com/rust-lang/crates.io-index" 1290source = "registry+https://github.com/rust-lang/crates.io-index"
1249checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 1291checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
1250dependencies = [ 1292dependencies = [
1251 "bytes", 1293 "bytes",
1252 "http", 1294 "http 0.2.12",
1253 "pin-project-lite", 1295 "pin-project-lite",
1254] 1296]
1255 1297
@@ -1276,7 +1318,7 @@ dependencies = [
1276 "futures-core", 1318 "futures-core",
1277 "futures-util", 1319 "futures-util",
1278 "h2", 1320 "h2",
1279 "http", 1321 "http 0.2.12",
1280 "http-body", 1322 "http-body",
1281 "httparse", 1323 "httparse",
1282 "httpdate", 1324 "httpdate",
@@ -1296,11 +1338,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1296checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" 1338checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
1297dependencies = [ 1339dependencies = [
1298 "futures-util", 1340 "futures-util",
1299 "http", 1341 "http 0.2.12",
1300 "hyper", 1342 "hyper",
1301 "rustls", 1343 "rustls 0.21.10",
1302 "tokio", 1344 "tokio",
1303 "tokio-rustls", 1345 "tokio-rustls 0.24.1",
1304] 1346]
1305 1347
1306[[package]] 1348[[package]]
@@ -1508,6 +1550,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1508checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" 1550checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
1509 1551
1510[[package]] 1552[[package]]
1553name = "lnurl-pay"
1554version = "0.3.0"
1555source = "registry+https://github.com/rust-lang/crates.io-index"
1556checksum = "b628658116d331c9567f6cb22415d726125ff6e328d1fb1b422b1b58afeaec21"
1557dependencies = [
1558 "bech32",
1559 "reqwest",
1560 "serde",
1561 "serde_json",
1562]
1563
1564[[package]]
1511name = "lock_api" 1565name = "lock_api"
1512version = "0.4.11" 1566version = "0.4.11"
1513source = "registry+https://github.com/rust-lang/crates.io-index" 1567source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1524,6 +1578,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1524checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" 1578checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
1525 1579
1526[[package]] 1580[[package]]
1581name = "lru"
1582version = "0.12.3"
1583source = "registry+https://github.com/rust-lang/crates.io-index"
1584checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc"
1585dependencies = [
1586 "hashbrown",
1587]
1588
1589[[package]]
1527name = "memchr" 1590name = "memchr"
1528version = "2.7.1" 1591version = "2.7.1"
1529source = "registry+https://github.com/rust-lang/crates.io-index" 1592source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1702,9 +1765,9 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
1702 1765
1703[[package]] 1766[[package]]
1704name = "nostr" 1767name = "nostr"
1705version = "0.27.0" 1768version = "0.29.0"
1706source = "registry+https://github.com/rust-lang/crates.io-index" 1769source = "registry+https://github.com/rust-lang/crates.io-index"
1707checksum = "3e47228d958fd65ef3e04650a3b1dd80f16f10f0243c80ed969556dead0f48c8" 1770checksum = "255485c2f41cf8f39d4e4a1901199549f54e32def81a71a8afe05f75809f441d"
1708dependencies = [ 1771dependencies = [
1709 "aes 0.8.4", 1772 "aes 0.8.4",
1710 "base64", 1773 "base64",
@@ -1712,16 +1775,19 @@ dependencies = [
1712 "bitcoin", 1775 "bitcoin",
1713 "cbc", 1776 "cbc",
1714 "chacha20", 1777 "chacha20",
1778 "chacha20poly1305",
1715 "getrandom", 1779 "getrandom",
1716 "instant", 1780 "instant",
1717 "js-sys", 1781 "js-sys",
1718 "negentropy", 1782 "negentropy",
1719 "once_cell", 1783 "once_cell",
1720 "reqwest", 1784 "reqwest",
1785 "scrypt",
1721 "serde", 1786 "serde",
1722 "serde_json", 1787 "serde_json",
1723 "tracing", 1788 "tracing",
1724 "url-fork", 1789 "unicode-normalization",
1790 "url",
1725 "wasm-bindgen", 1791 "wasm-bindgen",
1726 "wasm-bindgen-futures", 1792 "wasm-bindgen-futures",
1727 "web-sys", 1793 "web-sys",
@@ -1729,11 +1795,12 @@ dependencies = [
1729 1795
1730[[package]] 1796[[package]]
1731name = "nostr-database" 1797name = "nostr-database"
1732version = "0.27.0" 1798version = "0.29.0"
1733source = "registry+https://github.com/rust-lang/crates.io-index" 1799source = "registry+https://github.com/rust-lang/crates.io-index"
1734checksum = "aa0550256c8d4f0aaf74891ac986bd5ba46b2957c2c7e20f51838fa5819285f8" 1800checksum = "8e15ab55f96ea5e560af0c75f1d942b1064266d443d11b2afbe51ca9ad78a018"
1735dependencies = [ 1801dependencies = [
1736 "async-trait", 1802 "async-trait",
1803 "lru",
1737 "nostr", 1804 "nostr",
1738 "thiserror", 1805 "thiserror",
1739 "tokio", 1806 "tokio",
@@ -1741,22 +1808,65 @@ dependencies = [
1741] 1808]
1742 1809
1743[[package]] 1810[[package]]
1744name = "nostr-sdk" 1811name = "nostr-relay-pool"
1745version = "0.27.0" 1812version = "0.29.2"
1746source = "registry+https://github.com/rust-lang/crates.io-index" 1813source = "registry+https://github.com/rust-lang/crates.io-index"
1747checksum = "3cf190e41230721f0ce64f5ea72ed36cbc431d3b305eb166e24a94f5d7e4a425" 1814checksum = "a1b306bc99d49064950a16a06d35c7c19af94d8b4052fad0dfe02e41e529d5d3"
1748dependencies = [ 1815dependencies = [
1749 "async-utility", 1816 "async-utility",
1750 "async-wsocket", 1817 "async-wsocket",
1818 "atomic-destructor",
1751 "nostr", 1819 "nostr",
1752 "nostr-database", 1820 "nostr-database",
1753 "once_cell",
1754 "thiserror", 1821 "thiserror",
1755 "tokio", 1822 "tokio",
1756 "tracing", 1823 "tracing",
1757] 1824]
1758 1825
1759[[package]] 1826[[package]]
1827name = "nostr-sdk"
1828version = "0.29.0"
1829source = "registry+https://github.com/rust-lang/crates.io-index"
1830checksum = "81ed0ab9cbc3b20d3dba99337f2e0739f052ebe32133d690e212022a06a22044"
1831dependencies = [
1832 "async-utility",
1833 "lnurl-pay",
1834 "nostr",
1835 "nostr-database",
1836 "nostr-relay-pool",
1837 "nostr-signer",
1838 "nostr-zapper",
1839 "nwc",
1840 "thiserror",
1841 "tokio",
1842 "tracing",
1843]
1844
1845[[package]]
1846name = "nostr-signer"
1847version = "0.29.0"
1848source = "registry+https://github.com/rust-lang/crates.io-index"
1849checksum = "307bdc7c26887d7e65632e66872989a19892dfe9f2c6dbd9a1d3f959c5c524d5"
1850dependencies = [
1851 "async-utility",
1852 "nostr",
1853 "nostr-relay-pool",
1854 "thiserror",
1855 "tokio",
1856]
1857
1858[[package]]
1859name = "nostr-zapper"
1860version = "0.29.0"
1861source = "registry+https://github.com/rust-lang/crates.io-index"
1862checksum = "061d5eb00b430747a984ea9e41cd82c849832151b4263d8230c9c220dc2c62f8"
1863dependencies = [
1864 "async-trait",
1865 "nostr",
1866 "thiserror",
1867]
1868
1869[[package]]
1760name = "num" 1870name = "num"
1761version = "0.4.1" 1871version = "0.4.1"
1762source = "registry+https://github.com/rust-lang/crates.io-index" 1872source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1848,6 +1958,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1848checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 1958checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
1849 1959
1850[[package]] 1960[[package]]
1961name = "nwc"
1962version = "0.29.0"
1963source = "registry+https://github.com/rust-lang/crates.io-index"
1964checksum = "d1894ffe54a1e5adf8dbb22b5a290c0748ec4a88aa07fa69c4359010edea49ed"
1965dependencies = [
1966 "async-utility",
1967 "nostr",
1968 "nostr-relay-pool",
1969 "nostr-zapper",
1970 "thiserror",
1971 "tracing",
1972]
1973
1974[[package]]
1851name = "object" 1975name = "object"
1852version = "0.32.2" 1976version = "0.32.2"
1853source = "registry+https://github.com/rust-lang/crates.io-index" 1977source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2300,7 +2424,7 @@ dependencies = [
2300 "futures-core", 2424 "futures-core",
2301 "futures-util", 2425 "futures-util",
2302 "h2", 2426 "h2",
2303 "http", 2427 "http 0.2.12",
2304 "http-body", 2428 "http-body",
2305 "hyper", 2429 "hyper",
2306 "hyper-rustls", 2430 "hyper-rustls",
@@ -2311,7 +2435,7 @@ dependencies = [
2311 "once_cell", 2435 "once_cell",
2312 "percent-encoding", 2436 "percent-encoding",
2313 "pin-project-lite", 2437 "pin-project-lite",
2314 "rustls", 2438 "rustls 0.21.10",
2315 "rustls-pemfile", 2439 "rustls-pemfile",
2316 "serde", 2440 "serde",
2317 "serde_json", 2441 "serde_json",
@@ -2319,14 +2443,14 @@ dependencies = [
2319 "sync_wrapper", 2443 "sync_wrapper",
2320 "system-configuration", 2444 "system-configuration",
2321 "tokio", 2445 "tokio",
2322 "tokio-rustls", 2446 "tokio-rustls 0.24.1",
2323 "tokio-socks", 2447 "tokio-socks",
2324 "tower-service", 2448 "tower-service",
2325 "url", 2449 "url",
2326 "wasm-bindgen", 2450 "wasm-bindgen",
2327 "wasm-bindgen-futures", 2451 "wasm-bindgen-futures",
2328 "web-sys", 2452 "web-sys",
2329 "webpki-roots", 2453 "webpki-roots 0.25.4",
2330 "winreg", 2454 "winreg",
2331] 2455]
2332 2456
@@ -2420,11 +2544,25 @@ checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
2420dependencies = [ 2544dependencies = [
2421 "log", 2545 "log",
2422 "ring", 2546 "ring",
2423 "rustls-webpki", 2547 "rustls-webpki 0.101.7",
2424 "sct", 2548 "sct",
2425] 2549]
2426 2550
2427[[package]] 2551[[package]]
2552name = "rustls"
2553version = "0.22.2"
2554source = "registry+https://github.com/rust-lang/crates.io-index"
2555checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41"
2556dependencies = [
2557 "log",
2558 "ring",
2559 "rustls-pki-types",
2560 "rustls-webpki 0.102.2",
2561 "subtle",
2562 "zeroize",
2563]
2564
2565[[package]]
2428name = "rustls-pemfile" 2566name = "rustls-pemfile"
2429version = "1.0.4" 2567version = "1.0.4"
2430source = "registry+https://github.com/rust-lang/crates.io-index" 2568source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2434,6 +2572,12 @@ dependencies = [
2434] 2572]
2435 2573
2436[[package]] 2574[[package]]
2575name = "rustls-pki-types"
2576version = "1.3.1"
2577source = "registry+https://github.com/rust-lang/crates.io-index"
2578checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8"
2579
2580[[package]]
2437name = "rustls-webpki" 2581name = "rustls-webpki"
2438version = "0.101.7" 2582version = "0.101.7"
2439source = "registry+https://github.com/rust-lang/crates.io-index" 2583source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2444,6 +2588,17 @@ dependencies = [
2444] 2588]
2445 2589
2446[[package]] 2590[[package]]
2591name = "rustls-webpki"
2592version = "0.102.2"
2593source = "registry+https://github.com/rust-lang/crates.io-index"
2594checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610"
2595dependencies = [
2596 "ring",
2597 "rustls-pki-types",
2598 "untrusted",
2599]
2600
2601[[package]]
2447name = "ryu" 2602name = "ryu"
2448version = "1.0.17" 2603version = "1.0.17"
2449source = "registry+https://github.com/rust-lang/crates.io-index" 2604source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2699,7 +2854,7 @@ dependencies = [
2699 "flume", 2854 "flume",
2700 "futures-util", 2855 "futures-util",
2701 "tokio", 2856 "tokio",
2702 "tokio-tungstenite", 2857 "tokio-tungstenite 0.20.1",
2703] 2858]
2704 2859
2705[[package]] 2860[[package]]
@@ -2856,7 +3011,7 @@ dependencies = [
2856 "rexpect 0.5.0 (git+https://github.com/rust-cli/rexpect.git?rev=9eb61dd)", 3011 "rexpect 0.5.0 (git+https://github.com/rust-cli/rexpect.git?rev=9eb61dd)",
2857 "simple-websockets", 3012 "simple-websockets",
2858 "strip-ansi-escapes", 3013 "strip-ansi-escapes",
2859 "tungstenite", 3014 "tungstenite 0.20.1",
2860] 3015]
2861 3016
2862[[package]] 3017[[package]]
@@ -2930,7 +3085,18 @@ version = "0.24.1"
2930source = "registry+https://github.com/rust-lang/crates.io-index" 3085source = "registry+https://github.com/rust-lang/crates.io-index"
2931checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" 3086checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
2932dependencies = [ 3087dependencies = [
2933 "rustls", 3088 "rustls 0.21.10",
3089 "tokio",
3090]
3091
3092[[package]]
3093name = "tokio-rustls"
3094version = "0.25.0"
3095source = "registry+https://github.com/rust-lang/crates.io-index"
3096checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
3097dependencies = [
3098 "rustls 0.22.2",
3099 "rustls-pki-types",
2934 "tokio", 3100 "tokio",
2935] 3101]
2936 3102
@@ -2954,11 +3120,24 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c"
2954dependencies = [ 3120dependencies = [
2955 "futures-util", 3121 "futures-util",
2956 "log", 3122 "log",
2957 "rustls",
2958 "tokio", 3123 "tokio",
2959 "tokio-rustls", 3124 "tungstenite 0.20.1",
2960 "tungstenite", 3125]
2961 "webpki-roots", 3126
3127[[package]]
3128name = "tokio-tungstenite"
3129version = "0.21.0"
3130source = "registry+https://github.com/rust-lang/crates.io-index"
3131checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38"
3132dependencies = [
3133 "futures-util",
3134 "log",
3135 "rustls 0.22.2",
3136 "rustls-pki-types",
3137 "tokio",
3138 "tokio-rustls 0.25.0",
3139 "tungstenite 0.21.0",
3140 "webpki-roots 0.26.1",
2962] 3141]
2963 3142
2964[[package]] 3143[[package]]
@@ -3044,11 +3223,31 @@ dependencies = [
3044 "byteorder", 3223 "byteorder",
3045 "bytes", 3224 "bytes",
3046 "data-encoding", 3225 "data-encoding",
3047 "http", 3226 "http 0.2.12",
3048 "httparse", 3227 "httparse",
3049 "log", 3228 "log",
3050 "rand", 3229 "rand",
3051 "rustls", 3230 "sha1",
3231 "thiserror",
3232 "url",
3233 "utf-8",
3234]
3235
3236[[package]]
3237name = "tungstenite"
3238version = "0.21.0"
3239source = "registry+https://github.com/rust-lang/crates.io-index"
3240checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1"
3241dependencies = [
3242 "byteorder",
3243 "bytes",
3244 "data-encoding",
3245 "http 1.1.0",
3246 "httparse",
3247 "log",
3248 "rand",
3249 "rustls 0.22.2",
3250 "rustls-pki-types",
3052 "sha1", 3251 "sha1",
3053 "thiserror", 3252 "thiserror",
3054 "url", 3253 "url",
@@ -3130,17 +3329,6 @@ dependencies = [
3130 "form_urlencoded", 3329 "form_urlencoded",
3131 "idna", 3330 "idna",
3132 "percent-encoding", 3331 "percent-encoding",
3133]
3134
3135[[package]]
3136name = "url-fork"
3137version = "3.0.1"
3138source = "registry+https://github.com/rust-lang/crates.io-index"
3139checksum = "7fa3323c39b8e786154d3000b70ae9af0e9bd746c9791456da0d4a1f68ad89d6"
3140dependencies = [
3141 "form_urlencoded",
3142 "idna",
3143 "percent-encoding",
3144 "serde", 3332 "serde",
3145] 3333]
3146 3334
@@ -3318,6 +3506,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
3318checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" 3506checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
3319 3507
3320[[package]] 3508[[package]]
3509name = "webpki-roots"
3510version = "0.26.1"
3511source = "registry+https://github.com/rust-lang/crates.io-index"
3512checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009"
3513dependencies = [
3514 "rustls-pki-types",
3515]
3516
3517[[package]]
3321name = "winapi" 3518name = "winapi"
3322version = "0.3.9" 3519version = "0.3.9"
3323source = "registry+https://github.com/rust-lang/crates.io-index" 3520source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3567,6 +3764,26 @@ dependencies = [
3567] 3764]
3568 3765
3569[[package]] 3766[[package]]
3767name = "zerocopy"
3768version = "0.7.32"
3769source = "registry+https://github.com/rust-lang/crates.io-index"
3770checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
3771dependencies = [
3772 "zerocopy-derive",
3773]
3774
3775[[package]]
3776name = "zerocopy-derive"
3777version = "0.7.32"
3778source = "registry+https://github.com/rust-lang/crates.io-index"
3779checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
3780dependencies = [
3781 "proc-macro2",
3782 "quote",
3783 "syn 2.0.53",
3784]
3785
3786[[package]]
3570name = "zeroize" 3787name = "zeroize"
3571version = "1.7.0" 3788version = "1.7.0"
3572source = "registry+https://github.com/rust-lang/crates.io-index" 3789source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 7793a8c..67706a9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -23,8 +23,8 @@ futures = "0.3.28"
23git2 = "0.18.1" 23git2 = "0.18.1"
24indicatif = "0.17.7" 24indicatif = "0.17.7"
25keyring = "2.0.5" 25keyring = "2.0.5"
26nostr = "0.27.0" 26nostr = "0.29"
27nostr-sdk = "0.27.0" 27nostr-sdk = "0.29"
28passwords = "3.1.13" 28passwords = "3.1.13"
29scrypt = "0.11.0" 29scrypt = "0.11.0"
30serde = { version = "1.0.181", features = ["derive"] } 30serde = { version = "1.0.181", features = ["derive"] }
diff --git a/src/client.rs b/src/client.rs
index 539d45a..2dbd238 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -19,7 +19,7 @@ use indicatif::{MultiProgress, ProgressBar, ProgressState, ProgressStyle};
19#[cfg(test)] 19#[cfg(test)]
20use mockall::*; 20use mockall::*;
21use nostr::Event; 21use nostr::Event;
22use nostr_sdk::ClientSigner; 22use nostr_sdk::NostrSigner;
23 23
24#[allow(clippy::struct_field_names)] 24#[allow(clippy::struct_field_names)]
25pub struct Client { 25pub struct Client {
@@ -101,7 +101,7 @@ impl Connect for Client {
101 101
102 async fn set_keys(&mut self, keys: &nostr::Keys) { 102 async fn set_keys(&mut self, keys: &nostr::Keys) {
103 self.client 103 self.client
104 .set_signer(Some(ClientSigner::Keys(keys.clone()))) 104 .set_signer(Some(NostrSigner::Keys(keys.clone())))
105 .await; 105 .await;
106 } 106 }
107 107
@@ -124,8 +124,9 @@ impl Connect for Client {
124 124
125 async fn send_event_to(&self, url: &str, event: Event) -> Result<nostr::EventId> { 125 async fn send_event_to(&self, url: &str, event: Event) -> Result<nostr::EventId> {
126 self.client.add_relay(url).await?; 126 self.client.add_relay(url).await?;
127 #[allow(clippy::large_futures)]
127 self.client.connect_relay(url).await?; 128 self.client.connect_relay(url).await?;
128 Ok(self.client.send_event_to(url, event).await?) 129 Ok(self.client.send_event_to(vec![url], event).await?)
129 } 130 }
130 131
131 async fn get_events( 132 async fn get_events(
@@ -144,7 +145,7 @@ impl Connect for Client {
144 let m = MultiProgress::new(); 145 let m = MultiProgress::new();
145 let pb_style = ProgressStyle::with_template(" {spinner} {prefix} {msg} {timeout_in}")? 146 let pb_style = ProgressStyle::with_template(" {spinner} {prefix} {msg} {timeout_in}")?
146 .with_key("timeout_in", |state: &ProgressState, w: &mut dyn Write| { 147 .with_key("timeout_in", |state: &ProgressState, w: &mut dyn Write| {
147 if state.elapsed().as_secs() > 3 { 148 if state.elapsed().as_secs() > 3 && state.elapsed().as_secs() < GET_EVENTS_TIMEOUT {
148 write!( 149 write!(
149 w, 150 w,
150 "timeout in {:.1}s", 151 "timeout in {:.1}s",
@@ -200,6 +201,7 @@ impl Connect for Client {
200 } else { 201 } else {
201 None 202 None
202 }; 203 };
204 #[allow(clippy::large_futures)]
203 match get_events_of(relay, filters, &pb).await { 205 match get_events_of(relay, filters, &pb).await {
204 Err(error) => { 206 Err(error) => {
205 if let Some(pb) = pb { 207 if let Some(pb) = pb {
@@ -246,6 +248,7 @@ async fn get_events_of(
246 pb: &Option<ProgressBar>, 248 pb: &Option<ProgressBar>,
247) -> Result<Vec<Event>> { 249) -> Result<Vec<Event>> {
248 if !relay.is_connected().await { 250 if !relay.is_connected().await {
251 #[allow(clippy::large_futures)]
249 relay.connect(None).await; 252 relay.connect(None).await;
250 } 253 }
251 254
diff --git a/src/config.rs b/src/config.rs
index 2370e34..7fca446 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -4,7 +4,7 @@ use anyhow::{anyhow, Context, Result};
4use directories::ProjectDirs; 4use directories::ProjectDirs;
5#[cfg(test)] 5#[cfg(test)]
6use mockall::*; 6use mockall::*;
7use nostr::{secp256k1::XOnlyPublicKey, ToBech32}; 7use nostr::{PublicKey, ToBech32};
8use serde::{self, Deserialize, Serialize}; 8use serde::{self, Deserialize, Serialize};
9 9
10#[derive(Default)] 10#[derive(Default)]
@@ -69,7 +69,7 @@ pub struct MyConfig {
69 69
70#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] 70#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
71pub struct UserRef { 71pub struct UserRef {
72 pub public_key: XOnlyPublicKey, 72 pub public_key: PublicKey,
73 pub encrypted_key: String, 73 pub encrypted_key: String,
74 pub metadata: UserMetadata, 74 pub metadata: UserMetadata,
75 pub relays: UserRelays, 75 pub relays: UserRelays,
@@ -77,7 +77,7 @@ pub struct UserRef {
77} 77}
78 78
79impl UserRef { 79impl UserRef {
80 pub fn new(public_key: XOnlyPublicKey, encrypted_key: String) -> Self { 80 pub fn new(public_key: PublicKey, encrypted_key: String) -> Self {
81 Self { 81 Self {
82 public_key, 82 public_key,
83 encrypted_key, 83 encrypted_key,
diff --git a/src/git.rs b/src/git.rs
index 86b59fb..77c1dcb 100644
--- a/src/git.rs
+++ b/src/git.rs
@@ -4,7 +4,7 @@ use std::{env::current_dir, path::Path};
4 4
5use anyhow::{bail, Context, Result}; 5use anyhow::{bail, Context, Result};
6use git2::{DiffOptions, Oid, Revwalk}; 6use git2::{DiffOptions, Oid, Revwalk};
7use nostr::prelude::{sha1::Hash as Sha1Hash, Hash}; 7use nostr_sdk::hashes::{sha1::Hash as Sha1Hash, Hash};
8 8
9use crate::sub_commands::list::{get_commit_id_from_patch, tag_value}; 9use crate::sub_commands::list::{get_commit_id_from_patch, tag_value};
10 10
diff --git a/src/key_handling/encryption.rs b/src/key_handling/encryption.rs
index 0ef7f69..54002fa 100644
--- a/src/key_handling/encryption.rs
+++ b/src/key_handling/encryption.rs
@@ -1,3 +1,5 @@
1use std::str::FromStr;
2
1use anyhow::{anyhow, bail, ensure, Context, Result}; 3use anyhow::{anyhow, bail, ensure, Context, Result};
2use chacha20poly1305::{ 4use chacha20poly1305::{
3 aead::{rand_core::RngCore, Aead, AeadCore, KeyInit, OsRng, Payload}, 5 aead::{rand_core::RngCore, Aead, AeadCore, KeyInit, OsRng, Payload},
@@ -6,6 +8,7 @@ use chacha20poly1305::{
6#[cfg(test)] 8#[cfg(test)]
7use mockall::*; 9use mockall::*;
8use nostr::{prelude::*, Keys}; 10use nostr::{prelude::*, Keys};
11use nostr_sdk::bech32::{self, FromBase32, ToBase32};
9use rand::{distributions::Alphanumeric, thread_rng, Rng}; 12use rand::{distributions::Alphanumeric, thread_rng, Rng};
10use zeroize::Zeroize; 13use zeroize::Zeroize;
11 14
@@ -120,10 +123,11 @@ impl EncryptDecrypt for Encryptor {
120 bail!("invalid encrypted key"); 123 bail!("invalid encrypted key");
121 } 124 }
122 125
123 let key = Keys::from_sk_str( 126 let key =
124 std::str::from_utf8(&inner_secret).context("inner secret is not [u8]")?, 127 Keys::from_str(std::str::from_utf8(&inner_secret).context("inner secret is not [u8]")?)
125 ) 128 .context(
126 .context("incorrect password. Key decrypted with password did not produce a valid nsec.")?; 129 "incorrect password. Key decrypted with password did not produce a valid nsec.",
130 )?;
127 131
128 inner_secret.zeroize(); 132 inner_secret.zeroize();
129 133
diff --git a/src/key_handling/users.rs b/src/key_handling/users.rs
index 2e88fba..1dd75a8 100644
--- a/src/key_handling/users.rs
+++ b/src/key_handling/users.rs
@@ -1,4 +1,4 @@
1use std::time::SystemTime; 1use std::{str::FromStr, time::SystemTime};
2 2
3use anyhow::{Context, Result}; 3use anyhow::{Context, Result};
4use async_trait::async_trait; 4use async_trait::async_trait;
@@ -32,13 +32,13 @@ pub trait UserManagement {
32 &self, 32 &self,
33 #[cfg(test)] client: &MockConnect, 33 #[cfg(test)] client: &MockConnect,
34 #[cfg(not(test))] client: &Client, 34 #[cfg(not(test))] client: &Client,
35 public_key: &XOnlyPublicKey, 35 public_key: &PublicKey,
36 after: u64, 36 after: u64,
37 ) -> Result<UserRef>; 37 ) -> Result<UserRef>;
38 fn get_user_from_cache(&self, public_key: &XOnlyPublicKey) -> Result<UserRef>; 38 fn get_user_from_cache(&self, public_key: &PublicKey) -> Result<UserRef>;
39 fn add_user_to_config( 39 fn add_user_to_config(
40 &self, 40 &self,
41 public_key: XOnlyPublicKey, 41 public_key: PublicKey,
42 encrypted_secret_key: Option<String>, 42 encrypted_secret_key: Option<String>,
43 overwrite: bool, 43 overwrite: bool,
44 ) -> Result<()>; 44 ) -> Result<()>;
@@ -59,7 +59,7 @@ impl UserManagement for UserManager {
59 .input(PromptInputParms::default().with_prompt(prompt)) 59 .input(PromptInputParms::default().with_prompt(prompt))
60 .context("failed to get nsec input from interactor")?, 60 .context("failed to get nsec input from interactor")?,
61 }; 61 };
62 match Keys::from_sk_str(&pk) { 62 match Keys::from_str(&pk) {
63 Ok(key) => { 63 Ok(key) => {
64 break key; 64 break key;
65 } 65 }
@@ -99,7 +99,7 @@ impl UserManagement for UserManager {
99 99
100 fn add_user_to_config( 100 fn add_user_to_config(
101 &self, 101 &self,
102 public_key: XOnlyPublicKey, 102 public_key: PublicKey,
103 encrypted_secret_key: Option<String>, 103 encrypted_secret_key: Option<String>,
104 overwrite: bool, 104 overwrite: bool,
105 ) -> Result<()> { 105 ) -> Result<()> {
@@ -129,7 +129,7 @@ impl UserManagement for UserManager {
129 .context("failed to save application configuration with new user details in") 129 .context("failed to save application configuration with new user details in")
130 } 130 }
131 131
132 fn get_user_from_cache(&self, public_key: &XOnlyPublicKey) -> Result<UserRef> { 132 fn get_user_from_cache(&self, public_key: &PublicKey) -> Result<UserRef> {
133 let cfg = self 133 let cfg = self
134 .config_manager 134 .config_manager
135 .load() 135 .load()
@@ -148,7 +148,7 @@ impl UserManagement for UserManager {
148 &self, 148 &self,
149 #[cfg(test)] client: &MockConnect, 149 #[cfg(test)] client: &MockConnect,
150 #[cfg(not(test))] client: &Client, 150 #[cfg(not(test))] client: &Client,
151 public_key: &XOnlyPublicKey, 151 public_key: &PublicKey,
152 use_cache_unless_checked_more_than_x_secs_ago: u64, 152 use_cache_unless_checked_more_than_x_secs_ago: u64,
153 ) -> Result<UserRef> { 153 ) -> Result<UserRef> {
154 let cfg = self 154 let cfg = self
@@ -249,7 +249,11 @@ impl UserManagement for UserManager {
249 relays: new_relays_event 249 relays: new_relays_event
250 .tags 250 .tags
251 .iter() 251 .iter()
252 .filter(|t| t.kind().eq(&nostr::TagKind::R)) 252 .filter(|t| {
253 t.kind().eq(&nostr::TagKind::SingleLetter(
254 SingleLetterTag::lowercase(Alphabet::R),
255 ))
256 })
253 .map(|t| UserRelayRef { 257 .map(|t| UserRelayRef {
254 url: t.as_vec()[1].clone(), 258 url: t.as_vec()[1].clone(),
255 read: t.as_vec().len() == 2 || t.as_vec()[2].eq("read"), 259 read: t.as_vec().len() == 2 || t.as_vec()[2].eq("read"),
@@ -471,7 +475,7 @@ mod tests {
471 .expect_encrypt_key() 475 .expect_encrypt_key()
472 .once() 476 .once()
473 .withf(|k, p| { 477 .withf(|k, p| {
474 k.eq(&Keys::from_sk_str(TEST_KEY_1_NSEC).unwrap()) && p.eq(TEST_PASSWORD) 478 k.eq(&Keys::from_str(TEST_KEY_1_NSEC).unwrap()) && p.eq(TEST_PASSWORD)
475 }) 479 })
476 .returning(|_, _| Ok(TEST_KEY_1_ENCRYPTED.into())); 480 .returning(|_, _| Ok(TEST_KEY_1_ENCRYPTED.into()));
477 481
diff --git a/src/login.rs b/src/login.rs
index b0fe230..4cdf3c1 100644
--- a/src/login.rs
+++ b/src/login.rs
@@ -1,5 +1,7 @@
1use std::str::FromStr;
2
1use anyhow::{bail, Context, Result}; 3use anyhow::{bail, Context, Result};
2use nostr::{prelude::FromSkStr, secp256k1::XOnlyPublicKey}; 4use nostr::PublicKey;
3use zeroize::Zeroize; 5use zeroize::Zeroize;
4 6
5#[cfg(not(test))] 7#[cfg(not(test))]
@@ -25,7 +27,7 @@ pub async fn launch(
25 // if nsec parameter 27 // if nsec parameter
26 let key = if let Some(nsec_unwrapped) = nsec { 28 let key = if let Some(nsec_unwrapped) = nsec {
27 // get key or fail without prompts 29 // get key or fail without prompts
28 let key = nostr::Keys::from_sk_str(nsec_unwrapped).context("invalid nsec parameter")?; 30 let key = nostr::Keys::from_str(nsec_unwrapped).context("invalid nsec parameter")?;
29 31
30 // if password, add user to enable password login in future 32 // if password, add user to enable password login in future
31 if password.is_some() { 33 if password.is_some() {
@@ -91,7 +93,7 @@ pub async fn launch(
91} 93}
92 94
93async fn get_user_details( 95async fn get_user_details(
94 public_key: &XOnlyPublicKey, 96 public_key: &PublicKey,
95 #[cfg(test)] client: &crate::client::MockConnect, 97 #[cfg(test)] client: &crate::client::MockConnect,
96 #[cfg(not(test))] client: &Client, 98 #[cfg(not(test))] client: &Client,
97) -> Result<UserRef> { 99) -> Result<UserRef> {
diff --git a/src/repo_ref.rs b/src/repo_ref.rs
index c7b42fa..2dab79c 100644
--- a/src/repo_ref.rs
+++ b/src/repo_ref.rs
@@ -1,7 +1,7 @@
1use std::{fs::File, io::BufReader, str::FromStr}; 1use std::{fs::File, io::BufReader, str::FromStr};
2 2
3use anyhow::{bail, Context, Result}; 3use anyhow::{bail, Context, Result};
4use nostr::{nips::nip19::Nip19, secp256k1::XOnlyPublicKey, FromBech32, Tag, ToBech32}; 4use nostr::{nips::nip19::Nip19, FromBech32, PublicKey, Tag, ToBech32};
5use serde::{Deserialize, Serialize}; 5use serde::{Deserialize, Serialize};
6 6
7#[cfg(not(test))] 7#[cfg(not(test))]
@@ -23,7 +23,7 @@ pub struct RepoRef {
23 pub git_server: String, 23 pub git_server: String,
24 pub web: Vec<String>, 24 pub web: Vec<String>,
25 pub relays: Vec<String>, 25 pub relays: Vec<String>,
26 pub maintainers: Vec<XOnlyPublicKey>, 26 pub maintainers: Vec<PublicKey>,
27 // code languages and hashtags 27 // code languages and hashtags
28} 28}
29 29
@@ -78,7 +78,7 @@ impl TryFrom<nostr::Event> for RepoRef {
78 } 78 }
79 for pk in maintainers { 79 for pk in maintainers {
80 r.maintainers.push( 80 r.maintainers.push(
81 nostr_sdk::prelude::XOnlyPublicKey::from_str(&pk) 81 nostr_sdk::prelude::PublicKey::from_str(&pk)
82 .context(format!("cannot convert entry from maintainers tag {pk} into a valid nostr public key. it should be in hex format")) 82 .context(format!("cannot convert entry from maintainers tag {pk} into a valid nostr public key. it should be in hex format"))
83 .context("invalid repository event")?, 83 .context("invalid repository event")?,
84 ); 84 );
@@ -200,8 +200,9 @@ pub async fn fetch(
200 nostr::Filter::default().kind(nostr::Kind::Custom(REPO_REF_KIND)); 200 nostr::Filter::default().kind(nostr::Kind::Custom(REPO_REF_KIND));
201 match nip19 { 201 match nip19 {
202 Nip19::Coordinate(c) => { 202 Nip19::Coordinate(c) => {
203 repo_event_filter = 203 repo_event_filter = repo_event_filter
204 repo_event_filter.identifier(c.identifier).author(c.pubkey); 204 .identifier(c.identifier)
205 .author(c.public_key);
205 for r in c.relays { 206 for r in c.relays {
206 relays.push(r); 207 relays.push(r);
207 } 208 }
@@ -246,11 +247,11 @@ pub fn get_repo_config_from_yaml(git_repo: &Repo) -> Result<RepoConfigYaml> {
246 Ok(repo_config_yaml) 247 Ok(repo_config_yaml)
247} 248}
248 249
249pub fn extract_pks(pk_strings: Vec<String>) -> Result<Vec<XOnlyPublicKey>> { 250pub fn extract_pks(pk_strings: Vec<String>) -> Result<Vec<PublicKey>> {
250 let mut pks: Vec<XOnlyPublicKey> = vec![]; 251 let mut pks: Vec<PublicKey> = vec![];
251 for s in pk_strings { 252 for s in pk_strings {
252 pks.push( 253 pks.push(
253 nostr_sdk::prelude::XOnlyPublicKey::from_bech32(s.clone()) 254 nostr_sdk::prelude::PublicKey::from_bech32(s.clone())
254 .context(format!("cannot convert {s} into a valid nostr public key"))?, 255 .context(format!("cannot convert {s} into a valid nostr public key"))?,
255 ); 256 );
256 } 257 }
@@ -259,7 +260,7 @@ pub fn extract_pks(pk_strings: Vec<String>) -> Result<Vec<XOnlyPublicKey>> {
259 260
260pub fn save_repo_config_to_yaml( 261pub fn save_repo_config_to_yaml(
261 git_repo: &Repo, 262 git_repo: &Repo,
262 maintainers: Vec<XOnlyPublicKey>, 263 maintainers: Vec<PublicKey>,
263 relays: Vec<String>, 264 relays: Vec<String>,
264) -> Result<()> { 265) -> Result<()> {
265 let path = git_repo.get_path()?.join("maintainers.yaml"); 266 let path = git_repo.get_path()?.join("maintainers.yaml");
diff --git a/src/sub_commands/init.rs b/src/sub_commands/init.rs
index 4f098c0..56129a6 100644
--- a/src/sub_commands/init.rs
+++ b/src/sub_commands/init.rs
@@ -1,5 +1,5 @@
1use anyhow::{Context, Result}; 1use anyhow::{Context, Result};
2use nostr::{secp256k1::XOnlyPublicKey, FromBech32, ToBech32}; 2use nostr::{FromBech32, PublicKey, ToBech32};
3 3
4use super::send::send_events; 4use super::send::send_events;
5#[cfg(not(test))] 5#[cfg(not(test))]
@@ -163,7 +163,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {
163 args.web.clone() 163 args.web.clone()
164 }; 164 };
165 165
166 let maintainers: Vec<XOnlyPublicKey> = { 166 let maintainers: Vec<PublicKey> = {
167 let mut dont_ask = !args.other_maintainers.is_empty(); 167 let mut dont_ask = !args.other_maintainers.is_empty();
168 let mut maintainers_string = if !args.other_maintainers.is_empty() { 168 let mut maintainers_string = if !args.other_maintainers.is_empty() {
169 [args.other_maintainers.clone()].concat().join(" ") 169 [args.other_maintainers.clone()].concat().join(" ")
@@ -185,7 +185,7 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {
185 }; 185 };
186 // add current user if not present 186 // add current user if not present
187 if maintainers.iter().any(|m| { 187 if maintainers.iter().any(|m| {
188 if let Ok(m_pubkey) = XOnlyPublicKey::from_bech32(m) { 188 if let Ok(m_pubkey) = PublicKey::from_bech32(m) {
189 user_ref.public_key.eq(&m_pubkey) 189 user_ref.public_key.eq(&m_pubkey)
190 } else { 190 } else {
191 false 191 false
@@ -210,9 +210,9 @@ pub async fn launch(cli_args: &Cli, args: &SubCommandArgs) -> Result<()> {
210 .map(std::string::ToString::to_string) 210 .map(std::string::ToString::to_string)
211 .collect(); 211 .collect();
212 } 212 }
213 let mut maintainers: Vec<XOnlyPublicKey> = vec![]; 213 let mut maintainers: Vec<PublicKey> = vec![];
214 for m in maintainers_string.split(' ') { 214 for m in maintainers_string.split(' ') {
215 if let Ok(m_pubkey) = XOnlyPublicKey::from_bech32(m) { 215 if let Ok(m_pubkey) = PublicKey::from_bech32(m) {
216 maintainers.push(m_pubkey); 216 maintainers.push(m_pubkey);
217 } else { 217 } else {
218 println!("not a valid set of npubs seperated by a space"); 218 println!("not a valid set of npubs seperated by a space");
diff --git a/src/sub_commands/list.rs b/src/sub_commands/list.rs
index 2d81164..1a30b9b 100644
--- a/src/sub_commands/list.rs
+++ b/src/sub_commands/list.rs
@@ -730,9 +730,12 @@ pub async fn find_proposal_events(
730 vec![ 730 vec![
731 nostr::Filter::default() 731 nostr::Filter::default()
732 .kind(nostr::Kind::Custom(PATCH_KIND)) 732 .kind(nostr::Kind::Custom(PATCH_KIND))
733 .custom_tag(nostr::Alphabet::T, vec!["root"])
734 .custom_tag( 733 .custom_tag(
735 nostr::Alphabet::A, 734 nostr::SingleLetterTag::lowercase(nostr::Alphabet::T),
735 vec!["root"],
736 )
737 .custom_tag(
738 nostr::SingleLetterTag::lowercase(nostr::Alphabet::A),
736 repo_ref 739 repo_ref
737 .maintainers 740 .maintainers
738 .iter() 741 .iter()
@@ -742,7 +745,10 @@ pub async fn find_proposal_events(
742 // events 745 // events
743 nostr::Filter::default() 746 nostr::Filter::default()
744 .kind(nostr::Kind::Custom(PATCH_KIND)) 747 .kind(nostr::Kind::Custom(PATCH_KIND))
745 .custom_tag(nostr::Alphabet::T, vec!["root"]) 748 .custom_tag(
749 nostr::SingleLetterTag::lowercase(nostr::Alphabet::T),
750 vec!["root"],
751 )
746 .reference(root_commit), 752 .reference(root_commit),
747 ], 753 ],
748 ) 754 )
diff --git a/src/sub_commands/push.rs b/src/sub_commands/push.rs
index 651b250..bb50ee2 100644
--- a/src/sub_commands/push.rs
+++ b/src/sub_commands/push.rs
@@ -1,5 +1,5 @@
1use anyhow::{bail, Context, Result}; 1use anyhow::{bail, Context, Result};
2use nostr::prelude::sha1::Hash as Sha1Hash; 2use nostr_sdk::hashes::sha1::Hash as Sha1Hash;
3 3
4#[cfg(not(test))] 4#[cfg(not(test))]
5use crate::client::Client; 5use crate::client::Client;
diff --git a/src/sub_commands/send.rs b/src/sub_commands/send.rs
index 35c2c81..d9caf9b 100644
--- a/src/sub_commands/send.rs
+++ b/src/sub_commands/send.rs
@@ -5,9 +5,10 @@ use console::Style;
5use futures::future::join_all; 5use futures::future::join_all;
6use indicatif::{MultiProgress, ProgressBar, ProgressStyle}; 6use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
7use nostr::{ 7use nostr::{
8 nips::nip19::Nip19, prelude::sha1::Hash as Sha1Hash, EventBuilder, FromBech32, Marker, Tag, 8 nips::{nip01::Coordinate, nip19::Nip19},
9 TagKind, UncheckedUrl, 9 EventBuilder, FromBech32, Marker, Tag, TagKind, UncheckedUrl,
10}; 10};
11use nostr_sdk::hashes::sha1::Hash as Sha1Hash;
11 12
12use super::list::tag_value; 13use super::list::tag_value;
13#[cfg(not(test))] 14#[cfg(not(test))]
@@ -541,11 +542,13 @@ pub fn generate_cover_letter_and_patch_events(
541 vec![ 542 vec![
542 // TODO: why not tag all maintainer identifiers? 543 // TODO: why not tag all maintainer identifiers?
543 Tag::A { 544 Tag::A {
544 kind: nostr::Kind::Custom(REPO_REF_KIND), 545 coordinate: Coordinate {
545 public_key: *repo_ref.maintainers.first() 546 kind: nostr::Kind::Custom(REPO_REF_KIND),
546 .context("repo reference should always have at least one maintainer - the issuer of the repo event") 547 public_key: *repo_ref.maintainers.first()
547 ?, 548 .context("repo reference should always have at least one maintainer")?,
548 identifier: repo_ref.identifier.to_string(), 549 identifier: repo_ref.identifier.to_string(),
550 relays: repo_ref.relays.clone(),
551 },
549 relay_url: repo_ref.relays.first().map(nostr::UncheckedUrl::from).clone(), 552 relay_url: repo_ref.relays.first().map(nostr::UncheckedUrl::from).clone(),
550 }, 553 },
551 Tag::Reference(format!("{root_commit}")), 554 Tag::Reference(format!("{root_commit}")),
@@ -797,11 +800,14 @@ pub fn generate_patch_event(
797 [ 800 [
798 vec![ 801 vec![
799 Tag::A { 802 Tag::A {
800 kind: nostr::Kind::Custom(REPO_REF_KIND), 803 coordinate: Coordinate {
801 public_key: *repo_ref.maintainers.first() 804 kind: nostr::Kind::Custom(REPO_REF_KIND),
802 .context("repo reference should always have at least one maintainer - the issuer of the repo event") 805 public_key: *repo_ref.maintainers.first()
803 ?, 806 .context("repo reference should always have at least one maintainer - the issuer of the repo event")
804 identifier: repo_ref.identifier.to_string(), 807 ?,
808 identifier: repo_ref.identifier.to_string(),
809 relays: repo_ref.relays.clone(),
810 },
805 relay_url: relay_hint.clone(), 811 relay_url: relay_hint.clone(),
806 }, 812 },
807 Tag::Reference(format!("{root_commit}")), 813 Tag::Reference(format!("{root_commit}")),
diff --git a/test_utils/Cargo.toml b/test_utils/Cargo.toml
index 8928f67..c4e1b1a 100644
--- a/test_utils/Cargo.toml
+++ b/test_utils/Cargo.toml
@@ -9,8 +9,8 @@ assert_cmd = "2.0.12"
9dialoguer = "0.10.4" 9dialoguer = "0.10.4"
10directories = "5.0.1" 10directories = "5.0.1"
11git2 = "0.18.1" 11git2 = "0.18.1"
12nostr = "0.27.0" 12nostr = "0.29"
13nostr-sdk = { version = "0.27.0", features = ["blocking"] } 13nostr-sdk = "0.29"
14once_cell = "1.18.0" 14once_cell = "1.18.0"
15rand = "0.8" 15rand = "0.8"
16rexpect = { git = "https://github.com/rust-cli/rexpect.git", rev = "9eb61dd" } 16rexpect = { git = "https://github.com/rust-cli/rexpect.git", rev = "9eb61dd" }
diff --git a/test_utils/src/lib.rs b/test_utils/src/lib.rs
index a0c67df..ad187be 100644
--- a/test_utils/src/lib.rs
+++ b/test_utils/src/lib.rs
@@ -1,9 +1,9 @@
1use std::{ffi::OsStr, path::PathBuf}; 1use std::{ffi::OsStr, path::PathBuf, str::FromStr};
2 2
3use anyhow::{bail, ensure, Context, Result}; 3use anyhow::{bail, ensure, Context, Result};
4use dialoguer::theme::{ColorfulTheme, Theme}; 4use dialoguer::theme::{ColorfulTheme, Theme};
5use directories::ProjectDirs; 5use directories::ProjectDirs;
6use nostr::{self, prelude::FromSkStr, Kind, Tag}; 6use nostr::{self, Kind, Tag};
7use once_cell::sync::Lazy; 7use once_cell::sync::Lazy;
8use rexpect::session::{Options, PtySession}; 8use rexpect::session::{Options, PtySession};
9use strip_ansi_escapes::strip_str; 9use strip_ansi_escapes::strip_str;
@@ -26,7 +26,7 @@ pub static TEST_KEY_1_DISPLAY_NAME: &str = "bob";
26pub static TEST_KEY_1_ENCRYPTED: &str = "ncryptsec1qyq607h3cykxc3f2a44u89cdk336fptccn3fm5pf3nmf93d3c86qpunc7r6klwcn6lyszjy72wxwqq9aljg4pm6atvjrds9e248yhv76xfnt464265kgnjsvg8rlg06wg4sp9uljzfpu8zuaztcvfn2j8ggdrg8mldh850cy75efsyqqansert9wqmn4e6khpgvfz7h5le9"; 26pub static TEST_KEY_1_ENCRYPTED: &str = "ncryptsec1qyq607h3cykxc3f2a44u89cdk336fptccn3fm5pf3nmf93d3c86qpunc7r6klwcn6lyszjy72wxwqq9aljg4pm6atvjrds9e248yhv76xfnt464265kgnjsvg8rlg06wg4sp9uljzfpu8zuaztcvfn2j8ggdrg8mldh850cy75efsyqqansert9wqmn4e6khpgvfz7h5le9";
27pub static TEST_KEY_1_ENCRYPTED_WEAK: &str = "ncryptsec1qy8ke0tjqnn8wt3w6lnc86c27ry3qrptxctjfcgruryxy0at238kwyjwsswd7z88thysruzw3awlrsxjvw5uptcd7vt70ft9rtkx00m8cgy3khm4hxa5d2gfnc6athnfruy2eyl6pkas8k34jg85z7xjqqadzfzh9rp0fzxqtw0tvxksac3n8yc98uksvuf93e0lcvqy8j6"; 27pub static TEST_KEY_1_ENCRYPTED_WEAK: &str = "ncryptsec1qy8ke0tjqnn8wt3w6lnc86c27ry3qrptxctjfcgruryxy0at238kwyjwsswd7z88thysruzw3awlrsxjvw5uptcd7vt70ft9rtkx00m8cgy3khm4hxa5d2gfnc6athnfruy2eyl6pkas8k34jg85z7xjqqadzfzh9rp0fzxqtw0tvxksac3n8yc98uksvuf93e0lcvqy8j6";
28pub static TEST_KEY_1_KEYS: Lazy<nostr::Keys> = 28pub static TEST_KEY_1_KEYS: Lazy<nostr::Keys> =
29 Lazy::new(|| nostr::Keys::from_sk_str(TEST_KEY_1_NSEC).unwrap()); 29 Lazy::new(|| nostr::Keys::from_str(TEST_KEY_1_NSEC).unwrap());
30 30
31pub fn generate_test_key_1_metadata_event(name: &str) -> nostr::Event { 31pub fn generate_test_key_1_metadata_event(name: &str) -> nostr::Event {
32 nostr::event::EventBuilder::metadata(&nostr::Metadata::new().name(name)) 32 nostr::event::EventBuilder::metadata(&nostr::Metadata::new().name(name))
@@ -95,7 +95,7 @@ pub static TEST_KEY_2_NPUB: &str =
95pub static TEST_KEY_2_DISPLAY_NAME: &str = "carole"; 95pub static TEST_KEY_2_DISPLAY_NAME: &str = "carole";
96pub static TEST_KEY_2_ENCRYPTED: &str = "...2"; 96pub static TEST_KEY_2_ENCRYPTED: &str = "...2";
97pub static TEST_KEY_2_KEYS: Lazy<nostr::Keys> = 97pub static TEST_KEY_2_KEYS: Lazy<nostr::Keys> =
98 Lazy::new(|| nostr::Keys::from_sk_str(TEST_KEY_2_NSEC).unwrap()); 98 Lazy::new(|| nostr::Keys::from_str(TEST_KEY_2_NSEC).unwrap());
99 99
100pub fn generate_test_key_2_metadata_event(name: &str) -> nostr::Event { 100pub fn generate_test_key_2_metadata_event(name: &str) -> nostr::Event {
101 nostr::event::EventBuilder::metadata(&nostr::Metadata::new().name(name)) 101 nostr::event::EventBuilder::metadata(&nostr::Metadata::new().name(name))
diff --git a/tests/list.rs b/tests/list.rs
index 4f55645..61c2201 100644
--- a/tests/list.rs
+++ b/tests/list.rs
@@ -1,6 +1,6 @@
1use anyhow::Result; 1use anyhow::Result;
2use futures::join; 2use futures::join;
3use nostr_sdk::client::blocking::Client; 3use nostr_sdk::client::Client;
4use serial_test::serial; 4use serial_test::serial;
5use test_utils::{git::GitTestRepo, relay::Relay, *}; 5use test_utils::{git::GitTestRepo, relay::Relay, *};
6 6
@@ -23,6 +23,7 @@ fn cli_tester_create_proposals() -> Result<GitTestRepo> {
23 Some((PROPOSAL_TITLE_1, "proposal a description")), 23 Some((PROPOSAL_TITLE_1, "proposal a description")),
24 None, 24 None,
25 )?; 25 )?;
26 std::thread::sleep(std::time::Duration::from_millis(1000));
26 cli_tester_create_proposal( 27 cli_tester_create_proposal(
27 &git_repo, 28 &git_repo,
28 FEATURE_BRANCH_NAME_2, 29 FEATURE_BRANCH_NAME_2,
@@ -30,6 +31,7 @@ fn cli_tester_create_proposals() -> Result<GitTestRepo> {
30 Some((PROPOSAL_TITLE_2, "proposal b description")), 31 Some((PROPOSAL_TITLE_2, "proposal b description")),
31 None, 32 None,
32 )?; 33 )?;
34 std::thread::sleep(std::time::Duration::from_millis(1000));
33 cli_tester_create_proposal( 35 cli_tester_create_proposal(
34 &git_repo, 36 &git_repo,
35 FEATURE_BRANCH_NAME_3, 37 FEATURE_BRANCH_NAME_3,
@@ -72,7 +74,7 @@ fn cli_tester_create_proposal(
72 in_reply_to: Option<String>, 74 in_reply_to: Option<String>,
73) -> Result<()> { 75) -> Result<()> {
74 create_and_populate_branch(test_repo, branch_name, prefix, false)?; 76 create_and_populate_branch(test_repo, branch_name, prefix, false)?;
75 77 std::thread::sleep(std::time::Duration::from_millis(1000));
76 if let Some(in_reply_to) = in_reply_to { 78 if let Some(in_reply_to) = in_reply_to {
77 let mut p = CliTester::new_from_dir( 79 let mut p = CliTester::new_from_dir(
78 &test_repo.dir, 80 &test_repo.dir,
@@ -190,7 +192,7 @@ mod cannot_find_repo_event {
190 input.succeeds_with( 192 input.succeeds_with(
191 &Coordinate { 193 &Coordinate {
192 kind: nostr::Kind::Custom(REPOSITORY_KIND), 194 kind: nostr::Kind::Custom(REPOSITORY_KIND),
193 pubkey: TEST_KEY_1_KEYS.public_key(), 195 public_key: TEST_KEY_1_KEYS.public_key(),
194 identifier: repo_event.identifier().unwrap().to_string(), 196 identifier: repo_event.identifier().unwrap().to_string(),
195 relays: vec!["ws://localhost:8056".to_string()], 197 relays: vec!["ws://localhost:8056".to_string()],
196 } 198 }
@@ -489,7 +491,7 @@ mod when_main_branch_is_uptodate {
489 "checked out proposal as '{FEATURE_BRANCH_NAME_3}' branch\r\n" 491 "checked out proposal as '{FEATURE_BRANCH_NAME_3}' branch\r\n"
490 ))?; 492 ))?;
491 p.expect_end()?; 493 p.expect_end()?;
492 494 println!("blablagothere");
493 for p in [51, 52, 53, 55, 56] { 495 for p in [51, 52, 53, 55, 56] {
494 relay::shutdown_relay(8000 + p)?; 496 relay::shutdown_relay(8000 + p)?;
495 } 497 }
@@ -726,6 +728,7 @@ mod when_main_branch_is_uptodate {
726 728
727 let cli_tester_handle = std::thread::spawn(move || -> Result<()> { 729 let cli_tester_handle = std::thread::spawn(move || -> Result<()> {
728 let originating_repo = cli_tester_create_proposals()?; 730 let originating_repo = cli_tester_create_proposals()?;
731 std::thread::sleep(std::time::Duration::from_millis(1000));
729 cli_tester_create_proposal( 732 cli_tester_create_proposal(
730 &originating_repo, 733 &originating_repo,
731 FEATURE_BRANCH_NAME_4, 734 FEATURE_BRANCH_NAME_4,
@@ -1589,6 +1592,8 @@ mod when_main_branch_is_uptodate {
1589 mod when_latest_revision_rebases_branch { 1592 mod when_latest_revision_rebases_branch {
1590 use std::time::Duration; 1593 use std::time::Duration;
1591 1594
1595 use tokio::{runtime::Handle, task::JoinHandle};
1596
1592 use super::*; 1597 use super::*;
1593 1598
1594 async fn prep_and_run() -> Result<(GitTestRepo, GitTestRepo)> { 1599 async fn prep_and_run() -> Result<(GitTestRepo, GitTestRepo)> {
@@ -1609,23 +1614,28 @@ mod when_main_branch_is_uptodate {
1609 r55.events.push(generate_test_key_1_metadata_event("fred")); 1614 r55.events.push(generate_test_key_1_metadata_event("fred"));
1610 r55.events.push(generate_test_key_1_relay_list_event()); 1615 r55.events.push(generate_test_key_1_relay_list_event());
1611 1616
1612 let cli_tester_handle = std::thread::spawn( 1617 let cli_tester_handle: JoinHandle<Result<(GitTestRepo, GitTestRepo)>> =
1613 move || -> Result<(GitTestRepo, GitTestRepo)> { 1618 tokio::task::spawn_blocking(move || {
1614 // create 3 proposals 1619 // create 3 proposals
1615 let _ = cli_tester_create_proposals()?; 1620 let _ = cli_tester_create_proposals()?;
1616 // get proposal id of first 1621 // get proposal id of first
1617 let client = Client::new(&nostr::Keys::generate()); 1622 // get proposal id of first
1618 client.add_relay("ws://localhost:8055")?; 1623 let client = Client::default();
1619 client.connect_relay("ws://localhost:8055")?; 1624 Handle::current().block_on(client.add_relay("ws://localhost:8055"))?;
1620 let proposals = client.get_events_of( 1625 Handle::current()
1626 .block_on(client.connect_relay("ws://localhost:8055"))?;
1627 let proposals = Handle::current().block_on(client.get_events_of(
1621 vec![ 1628 vec![
1622 nostr::Filter::default() 1629 nostr::Filter::default()
1623 .kind(nostr::Kind::Custom(PATCH_KIND)) 1630 .kind(nostr::Kind::Custom(PATCH_KIND))
1624 .custom_tag(nostr::Alphabet::T, vec!["root"]), 1631 .custom_tag(
1625 ], 1632 nostr::SingleLetterTag::lowercase(nostr::Alphabet::T),
1633 vec!["root"],
1634 ),
1635 ],
1626 Some(Duration::from_millis(500)), 1636 Some(Duration::from_millis(500)),
1627 )?; 1637 ))?;
1628 client.disconnect()?; 1638 Handle::current().block_on(client.disconnect())?;
1629 1639
1630 let proposal_1_id = proposals 1640 let proposal_1_id = proposals
1631 .iter() 1641 .iter()
@@ -1699,8 +1709,7 @@ mod when_main_branch_is_uptodate {
1699 relay::shutdown_relay(8000 + p)?; 1709 relay::shutdown_relay(8000 + p)?;
1700 } 1710 }
1701 Ok((second_originating_repo, test_repo)) 1711 Ok((second_originating_repo, test_repo))
1702 }, 1712 });
1703 );
1704 1713
1705 // launch relay 1714 // launch relay
1706 let _ = join!( 1715 let _ = join!(
@@ -1710,7 +1719,7 @@ mod when_main_branch_is_uptodate {
1710 r55.listen_until_close(), 1719 r55.listen_until_close(),
1711 r56.listen_until_close(), 1720 r56.listen_until_close(),
1712 ); 1721 );
1713 let res = cli_tester_handle.join().unwrap()?; 1722 let res = cli_tester_handle.await??;
1714 1723
1715 Ok(res) 1724 Ok(res)
1716 } 1725 }
@@ -1737,96 +1746,105 @@ mod when_main_branch_is_uptodate {
1737 r55.events.push(generate_test_key_1_metadata_event("fred")); 1746 r55.events.push(generate_test_key_1_metadata_event("fred"));
1738 r55.events.push(generate_test_key_1_relay_list_event()); 1747 r55.events.push(generate_test_key_1_relay_list_event());
1739 1748
1740 let cli_tester_handle = std::thread::spawn(move || -> Result<()> { 1749 let cli_tester_handle: JoinHandle<Result<()>> = tokio::task::spawn_blocking(
1741 // create 3 proposals 1750 move || {
1742 let _ = cli_tester_create_proposals()?; 1751 // create 3 proposals
1743 // get proposal id of first 1752 let _ = cli_tester_create_proposals()?;
1744 let client = Client::new(&nostr::Keys::generate()); 1753 // get proposal id of first
1745 client.add_relay("ws://localhost:8055")?; 1754 let client = Client::default();
1746 client.connect_relay("ws://localhost:8055")?; 1755 Handle::current()
1747 let proposals = client.get_events_of( 1756 .block_on(client.add_relay("ws://localhost:8055"))?;
1748 vec![ 1757 Handle::current()
1749 nostr::Filter::default() 1758 .block_on(client.connect_relay("ws://localhost:8055"))?;
1750 .kind(nostr::Kind::Custom(PATCH_KIND)) 1759 let proposals =
1751 .custom_tag(nostr::Alphabet::T, vec!["root"]), 1760 Handle::current().block_on(client.get_events_of(
1752 ], 1761 vec![
1753 Some(Duration::from_millis(500)), 1762 nostr::Filter::default()
1754 )?; 1763 .kind(nostr::Kind::Custom(PATCH_KIND))
1755 client.disconnect()?; 1764 .custom_tag(
1756 1765 nostr::SingleLetterTag::lowercase(nostr::Alphabet::T),
1757 let proposal_1_id = proposals 1766 vec!["root"],
1758 .iter() 1767 ),
1759 .find(|e| { 1768 ],
1760 e.tags 1769 Some(Duration::from_millis(500)),
1761 .iter() 1770 ))?;
1762 .any(|t| t.as_vec()[1].eq(&FEATURE_BRANCH_NAME_1)) 1771 Handle::current().block_on(client.disconnect())?;
1763 }) 1772
1764 .unwrap() 1773 let proposal_1_id = proposals
1765 .id; 1774 .iter()
1766 // recreate proposal 1 on top of a another commit (like a rebase on top 1775 .find(|e| {
1767 // of one extra commit) 1776 e.tags
1768 let second_originating_repo = GitTestRepo::default(); 1777 .iter()
1769 second_originating_repo.populate()?; 1778 .any(|t| t.as_vec()[1].eq(&FEATURE_BRANCH_NAME_1))
1770 std::fs::write( 1779 })
1771 second_originating_repo.dir.join("amazing.md"), 1780 .unwrap()
1772 "some content", 1781 .id;
1773 )?; 1782 // recreate proposal 1 on top of a another commit (like a rebase on
1774 second_originating_repo 1783 // top of one extra commit)
1775 .stage_and_commit("commit for rebasing on top of")?; 1784 let second_originating_repo = GitTestRepo::default();
1776 cli_tester_create_proposal( 1785 second_originating_repo.populate()?;
1777 &second_originating_repo, 1786 std::fs::write(
1778 FEATURE_BRANCH_NAME_1, 1787 second_originating_repo.dir.join("amazing.md"),
1779 "a", 1788 "some content",
1780 Some((PROPOSAL_TITLE_1, "proposal a description")), 1789 )?;
1781 Some(proposal_1_id.to_string()), 1790 second_originating_repo
1782 )?; 1791 .stage_and_commit("commit for rebasing on top of")?;
1783 1792 cli_tester_create_proposal(
1784 // pretend we have downloaded the origianl version of the first proposal 1793 &second_originating_repo,
1785 let test_repo = GitTestRepo::default(); 1794 FEATURE_BRANCH_NAME_1,
1786 test_repo.populate()?; 1795 "a",
1787 create_and_populate_branch( 1796 Some((PROPOSAL_TITLE_1, "proposal a description")),
1788 &test_repo, 1797 Some(proposal_1_id.to_string()),
1789 FEATURE_BRANCH_NAME_1, 1798 )?;
1790 "a", 1799
1791 false, 1800 // pretend we have downloaded the origianl version of the first
1792 )?; 1801 // proposal
1793 // pretend we have pulled the updated main branch 1802 let test_repo = GitTestRepo::default();
1794 test_repo.checkout("main")?; 1803 test_repo.populate()?;
1795 std::fs::write(test_repo.dir.join("amazing.md"), "some content")?; 1804 create_and_populate_branch(
1796 test_repo.stage_and_commit("commit for rebasing on top of")?; 1805 &test_repo,
1797 1806 FEATURE_BRANCH_NAME_1,
1798 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]); 1807 "a",
1799 p.expect("finding proposals...\r\n")?; 1808 false,
1800 let mut c = p.expect_choice( 1809 )?;
1801 "all proposals", 1810 // pretend we have pulled the updated main branch
1802 vec![ 1811 test_repo.checkout("main")?;
1803 format!("\"{PROPOSAL_TITLE_3}\""), 1812 std::fs::write(test_repo.dir.join("amazing.md"), "some content")?;
1804 format!("\"{PROPOSAL_TITLE_2}\""), 1813 test_repo.stage_and_commit("commit for rebasing on top of")?;
1805 format!("\"{PROPOSAL_TITLE_1}\""), 1814
1806 ], 1815 let mut p = CliTester::new_from_dir(&test_repo.dir, ["list"]);
1807 )?; 1816 p.expect("finding proposals...\r\n")?;
1808 c.succeeds_with(2, true, None)?; 1817 let mut c = p.expect_choice(
1809 p.expect("finding commits...\r\n")?; 1818 "all proposals",
1810 p.expect("updated proposal available (2 ahead 0 behind 'main'). existing version is 2 ahead 1 behind 'main'\r\n")?; 1819 vec![
1811 let mut c = p.expect_choice( 1820 format!("\"{PROPOSAL_TITLE_3}\""),
1812 "", 1821 format!("\"{PROPOSAL_TITLE_2}\""),
1813 vec![ 1822 format!("\"{PROPOSAL_TITLE_1}\""),
1814 format!("checkout and overwrite existing proposal branch"), 1823 ],
1815 format!("checkout existing outdated proposal branch"), 1824 )?;
1816 format!("apply to current branch with `git am`"), 1825 c.succeeds_with(2, true, None)?;
1817 format!("download to ./patches"), 1826 p.expect("finding commits...\r\n")?;
1818 format!("back"), 1827 p.expect("updated proposal available (2 ahead 0 behind 'main'). existing version is 2 ahead 1 behind 'main'\r\n")?;
1819 ], 1828 let mut c = p.expect_choice(
1820 )?; 1829 "",
1821 c.succeeds_with(0, false, Some(0))?; 1830 vec![
1822 p.expect("checked out new version of proposal (2 ahead 0 behind 'main'), replacing old version (2 ahead 1 behind 'main')\r\n")?; 1831 format!("checkout and overwrite existing proposal branch"),
1823 p.expect_end()?; 1832 format!("checkout existing outdated proposal branch"),
1824 1833 format!("apply to current branch with `git am`"),
1825 for p in [51, 52, 53, 55, 56] { 1834 format!("download to ./patches"),
1826 relay::shutdown_relay(8000 + p)?; 1835 format!("back"),
1827 } 1836 ],
1828 Ok(()) 1837 )?;
1829 }); 1838 c.succeeds_with(0, false, Some(0))?;
1839 p.expect("checked out new version of proposal (2 ahead 0 behind 'main'), replacing old version (2 ahead 1 behind 'main')\r\n")?;
1840 p.expect_end()?;
1841
1842 for p in [51, 52, 53, 55, 56] {
1843 relay::shutdown_relay(8000 + p)?;
1844 }
1845 Ok(())
1846 },
1847 );
1830 1848
1831 // launch relay 1849 // launch relay
1832 let _ = join!( 1850 let _ = join!(
@@ -1836,7 +1854,7 @@ mod when_main_branch_is_uptodate {
1836 r55.listen_until_close(), 1854 r55.listen_until_close(),
1837 r56.listen_until_close(), 1855 r56.listen_until_close(),
1838 ); 1856 );
1839 cli_tester_handle.join().unwrap()?; 1857 cli_tester_handle.await??;
1840 println!("{:?}", r55.events); 1858 println!("{:?}", r55.events);
1841 Ok(()) 1859 Ok(())
1842 } 1860 }
diff --git a/tests/pull.rs b/tests/pull.rs
index 50dddbf..bf132e7 100644
--- a/tests/pull.rs
+++ b/tests/pull.rs
@@ -712,7 +712,8 @@ mod when_branch_is_checked_out {
712 mod when_latest_event_rebases_branch { 712 mod when_latest_event_rebases_branch {
713 use std::time::Duration; 713 use std::time::Duration;
714 714
715 use nostr_sdk::blocking::Client; 715 use nostr_sdk::Client;
716 use tokio::{runtime::Handle, task::JoinHandle};
716 717
717 use super::*; 718 use super::*;
718 719
@@ -734,23 +735,26 @@ mod when_branch_is_checked_out {
734 r55.events.push(generate_test_key_1_metadata_event("fred")); 735 r55.events.push(generate_test_key_1_metadata_event("fred"));
735 r55.events.push(generate_test_key_1_relay_list_event()); 736 r55.events.push(generate_test_key_1_relay_list_event());
736 737
737 let cli_tester_handle = 738 let cli_tester_handle: JoinHandle<Result<(GitTestRepo, GitTestRepo)>> =
738 std::thread::spawn(move || -> Result<(GitTestRepo, GitTestRepo)> { 739 tokio::task::spawn_blocking(move || {
739 // create 3 proposals 740 // create 3 proposals
740 let _ = cli_tester_create_proposals()?; 741 let _ = cli_tester_create_proposals()?;
741 // get proposal id of first 742 // get proposal id of first
742 let client = Client::new(&nostr::Keys::generate()); 743 let client = Client::default();
743 client.add_relay("ws://localhost:8055")?; 744 Handle::current().block_on(client.add_relay("ws://localhost:8055"))?;
744 client.connect_relay("ws://localhost:8055")?; 745 Handle::current().block_on(client.connect_relay("ws://localhost:8055"))?;
745 let proposals = client.get_events_of( 746 let proposals = Handle::current().block_on(client.get_events_of(
746 vec![ 747 vec![
747 nostr::Filter::default() 748 nostr::Filter::default()
748 .kind(nostr::Kind::Custom(PATCH_KIND)) 749 .kind(nostr::Kind::Custom(PATCH_KIND))
749 .custom_tag(nostr::Alphabet::T, vec!["root"]), 750 .custom_tag(
750 ], 751 nostr::SingleLetterTag::lowercase(nostr::Alphabet::T),
752 vec!["root"],
753 ),
754 ],
751 Some(Duration::from_millis(500)), 755 Some(Duration::from_millis(500)),
752 )?; 756 ))?;
753 client.disconnect()?; 757 Handle::current().block_on(client.disconnect())?;
754 758
755 let proposal_1_id = proposals 759 let proposal_1_id = proposals
756 .iter() 760 .iter()
@@ -805,7 +809,7 @@ mod when_branch_is_checked_out {
805 r55.listen_until_close(), 809 r55.listen_until_close(),
806 r56.listen_until_close(), 810 r56.listen_until_close(),
807 ); 811 );
808 let res = cli_tester_handle.join().unwrap()?; 812 let res = cli_tester_handle.await??;
809 813
810 Ok(res) 814 Ok(res)
811 } 815 }
@@ -832,69 +836,75 @@ mod when_branch_is_checked_out {
832 r55.events.push(generate_test_key_1_metadata_event("fred")); 836 r55.events.push(generate_test_key_1_metadata_event("fred"));
833 r55.events.push(generate_test_key_1_relay_list_event()); 837 r55.events.push(generate_test_key_1_relay_list_event());
834 838
835 let cli_tester_handle = std::thread::spawn(move || -> Result<()> { 839 let cli_tester_handle: JoinHandle<Result<()>> = tokio::task::spawn_blocking(
836 // create 3 proposals 840 move || {
837 let _ = cli_tester_create_proposals()?; 841 // create 3 proposals
838 // get proposal id of first 842 let _ = cli_tester_create_proposals()?;
839 let client = Client::new(&nostr::Keys::generate()); 843 // get proposal id of first
840 client.add_relay("ws://localhost:8055")?; 844 let client = Client::default();
841 client.connect_relay("ws://localhost:8055")?; 845 Handle::current().block_on(client.add_relay("ws://localhost:8055"))?;
842 let proposals = client.get_events_of( 846 Handle::current().block_on(client.connect_relay("ws://localhost:8055"))?;
843 vec![ 847 let proposals = Handle::current().block_on(client.get_events_of(
844 nostr::Filter::default() 848 vec![
845 .kind(nostr::Kind::Custom(PATCH_KIND)) 849 nostr::Filter::default()
846 .custom_tag(nostr::Alphabet::T, vec!["root"]), 850 .kind(nostr::Kind::Custom(PATCH_KIND))
847 ], 851 .custom_tag(
848 Some(Duration::from_millis(500)), 852 nostr::SingleLetterTag::lowercase(nostr::Alphabet::T),
849 )?; 853 vec!["root"],
850 client.disconnect()?; 854 ),
851 855 ],
852 let proposal_1_id = proposals 856 Some(Duration::from_millis(500)),
853 .iter() 857 ))?;
854 .find(|e| { 858 Handle::current().block_on(client.disconnect())?;
855 e.tags 859
856 .iter() 860 let proposal_1_id = proposals
857 .any(|t| t.as_vec()[1].eq(&FEATURE_BRANCH_NAME_1)) 861 .iter()
858 }) 862 .find(|e| {
859 .unwrap() 863 e.tags
860 .id; 864 .iter()
861 // recreate proposal 1 on top of a another commit (like a rebase on top 865 .any(|t| t.as_vec()[1].eq(&FEATURE_BRANCH_NAME_1))
862 // of one extra commit) 866 })
863 let second_originating_repo = GitTestRepo::default(); 867 .unwrap()
864 second_originating_repo.populate()?; 868 .id;
865 std::fs::write( 869 // recreate proposal 1 on top of a another commit (like a rebase on top
866 second_originating_repo.dir.join("amazing.md"), 870 // of one extra commit)
867 "some content", 871 let second_originating_repo = GitTestRepo::default();
868 )?; 872 second_originating_repo.populate()?;
869 second_originating_repo.stage_and_commit("commit for rebasing on top of")?; 873 std::fs::write(
870 cli_tester_create_proposal( 874 second_originating_repo.dir.join("amazing.md"),
871 &second_originating_repo, 875 "some content",
872 FEATURE_BRANCH_NAME_1, 876 )?;
873 "a", 877 second_originating_repo
874 Some((PROPOSAL_TITLE_1, "proposal a description")), 878 .stage_and_commit("commit for rebasing on top of")?;
875 Some(proposal_1_id.to_string()), 879 cli_tester_create_proposal(
876 )?; 880 &second_originating_repo,
877 881 FEATURE_BRANCH_NAME_1,
878 // pretend we have downloaded the origianl version of the first proposal 882 "a",
879 let test_repo = GitTestRepo::default(); 883 Some((PROPOSAL_TITLE_1, "proposal a description")),
880 test_repo.populate()?; 884 Some(proposal_1_id.to_string()),
881 create_and_populate_branch(&test_repo, FEATURE_BRANCH_NAME_1, "a", false)?; 885 )?;
882 // pretend we have pulled the updated main branch 886
883 test_repo.checkout("main")?; 887 // pretend we have downloaded the origianl version of the first proposal
884 std::fs::write(test_repo.dir.join("amazing.md"), "some content")?; 888 let test_repo = GitTestRepo::default();
885 test_repo.stage_and_commit("commit for rebasing on top of")?; 889 test_repo.populate()?;
886 test_repo.checkout(FEATURE_BRANCH_NAME_1)?; 890 create_and_populate_branch(&test_repo, FEATURE_BRANCH_NAME_1, "a", false)?;
891 // pretend we have pulled the updated main branch
892 test_repo.checkout("main")?;
893 std::fs::write(test_repo.dir.join("amazing.md"), "some content")?;
894 test_repo.stage_and_commit("commit for rebasing on top of")?;
895 test_repo.checkout(FEATURE_BRANCH_NAME_1)?;
887 896
888 let mut p = CliTester::new_from_dir(&test_repo.dir, ["pull"]); 897 let mut p = CliTester::new_from_dir(&test_repo.dir, ["pull"]);
889 p.expect("finding proposal root event...\r\n")?; 898 p.expect("finding proposal root event...\r\n")?;
890 p.expect("found proposal root event. finding commits...\r\n")?; 899 p.expect("found proposal root event. finding commits...\r\n")?;
891 p.expect_end_with("pulled new version of proposal (2 ahead 0 behind 'main'), replacing old version (2 ahead 1 behind 'main')\r\n")?; 900 p.expect_end_with("pulled new version of proposal (2 ahead 0 behind 'main'), replacing old version (2 ahead 1 behind 'main')\r\n")?;
892 901
893 for p in [51, 52, 53, 55, 56] { 902 for p in [51, 52, 53, 55, 56] {
894 relay::shutdown_relay(8000 + p)?; 903 relay::shutdown_relay(8000 + p)?;
895 } 904 }
896 Ok(()) 905 Ok(())
897 }); 906 },
907 );
898 908
899 // launch relay 909 // launch relay
900 let _ = join!( 910 let _ = join!(
@@ -904,7 +914,7 @@ mod when_branch_is_checked_out {
904 r55.listen_until_close(), 914 r55.listen_until_close(),
905 r56.listen_until_close(), 915 r56.listen_until_close(),
906 ); 916 );
907 cli_tester_handle.join().unwrap()?; 917 cli_tester_handle.await??;
908 println!("{:?}", r55.events); 918 println!("{:?}", r55.events);
909 Ok(()) 919 Ok(())
910 } 920 }