diff --git a/Cargo.lock b/Cargo.lock index 2189280..712dae5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,7 +23,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "generic-array", ] @@ -34,8 +34,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", - "cipher", - "cpufeatures", + "cipher 0.4.4", + "cpufeatures 0.2.17", "zeroize", ] @@ -220,9 +220,9 @@ dependencies = [ [[package]] name = "ashpd" -version = "0.13.10" +version = "0.13.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3118453e020b8e3e0da25ef9a1d0d51d668874358af11aded9d91a8b9c25f323" +checksum = "340e0f6bf7f9ee78549c61454f1460a3ed97c011902ee76b58301bbc6d502a32" dependencies = [ "enumflags2", "futures-channel", @@ -593,18 +593,18 @@ dependencies = [ [[package]] name = "avif-serialize" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375082f007bd67184fb9c0374614b29f9aaa604ec301635f72338bb65386a53d" +checksum = "e7178fe5f7d460b13895ebb9dcb28a3a6216d2df2574a0806cb51b555d297f38" dependencies = [ "arrayvec", ] [[package]] name = "aws-lc-rs" -version = "1.16.3" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" dependencies = [ "aws-lc-sys", "zeroize", @@ -612,9 +612,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.40.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" dependencies = [ "cc", "cmake", @@ -643,12 +643,6 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "base64ct" -version = "1.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" - [[package]] name = "bech32" version = "0.11.1" @@ -763,6 +757,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block-padding" version = "0.3.3" @@ -910,7 +913,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" dependencies = [ - "cipher", + "cipher 0.4.4", ] [[package]] @@ -933,9 +936,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.61" +version = "1.2.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +checksum = "a1dce859f0832a7d088c4f1119888ab94ef4b5d6795d1ce05afb7fe159d79f98" dependencies = [ "find-msvc-tools", "jobserver", @@ -986,8 +989,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", - "cipher", - "cpufeatures", + "cipher 0.4.4", + "cpufeatures 0.2.17", ] [[package]] @@ -998,7 +1001,7 @@ checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead", "chacha20", - "cipher", + "cipher 0.4.4", "poly1305", "zeroize", ] @@ -1074,11 +1077,22 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", - "inout", + "crypto-common 0.1.7", + "inout 0.1.4", "zeroize", ] +[[package]] +name = "cipher" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea" +dependencies = [ + "block-buffer 0.12.0", + "crypto-common 0.2.1", + "inout 0.2.2", +] + [[package]] name = "clang-sys" version = "1.8.1" @@ -1139,6 +1153,12 @@ dependencies = [ "cc", ] +[[package]] +name = "cmov" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" + [[package]] name = "cocoa" version = "0.25.0" @@ -1213,7 +1233,7 @@ dependencies = [ [[package]] name = "collections" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "indexmap", "rustc-hash 2.1.2", @@ -1247,7 +1267,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b60b5124979fccd9addd89d8b97a1d6eebb4950694520c75ddd722535ea443f" dependencies = [ - "nix 0.31.2", + "nix 0.31.3", "thiserror 2.0.18", ] @@ -1594,6 +1614,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -1653,6 +1682,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +dependencies = [ + "hybrid-array", +] + [[package]] name = "ctor" version = "0.4.3" @@ -1669,6 +1707,15 @@ version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2" +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", +] + [[package]] name = "data-encoding" version = "2.11.0" @@ -1713,7 +1760,7 @@ dependencies = [ [[package]] name = "derive_refineable" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "proc-macro2", "quote", @@ -1747,11 +1794,22 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "crypto-common", + "block-buffer 0.10.4", + "crypto-common 0.1.7", "subtle", ] +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.0", + "crypto-common 0.2.1", + "ctutils", +] + [[package]] name = "dirs" version = "5.0.1" @@ -2098,23 +2156,9 @@ dependencies = [ [[package]] name = "fax" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab" -dependencies = [ - "fax_derive", -] - -[[package]] -name = "fax_derive" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] +checksum = "caf1079563223d5d59d83c85886a56e586cfd5c1a26292e971a0fa266531ac5a" [[package]] name = "fdeflate" @@ -2147,13 +2191,12 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.27" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" +checksum = "5c287a33c7f0a620c38e641e7f60827713987b3c0f26e8ddc9462cc69cf75759" dependencies = [ "cfg-if", "libc", - "libredox", ] [[package]] @@ -2704,7 +2747,7 @@ dependencies = [ [[package]] name = "gpui" version = "0.2.2" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "anyhow", "async-channel 2.5.0", @@ -2742,7 +2785,6 @@ dependencies = [ "mach2", "media", "metal", - "naga 29.0.1", "num_cpus", "objc", "parking", @@ -2785,7 +2827,7 @@ dependencies = [ [[package]] name = "gpui_linux" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "anyhow", "as-raw-xcb-connection", @@ -2834,7 +2876,7 @@ dependencies = [ [[package]] name = "gpui_macos" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "anyhow", "async-task", @@ -2877,7 +2919,7 @@ dependencies = [ [[package]] name = "gpui_macros" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -2888,7 +2930,7 @@ dependencies = [ [[package]] name = "gpui_platform" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "console_error_panic_hook", "gpui", @@ -2901,7 +2943,7 @@ dependencies = [ [[package]] name = "gpui_shared_string" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "schemars", "serde", @@ -2911,7 +2953,7 @@ dependencies = [ [[package]] name = "gpui_tokio" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "anyhow", "gpui", @@ -2922,7 +2964,7 @@ dependencies = [ [[package]] name = "gpui_util" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "anyhow", "log", @@ -2931,7 +2973,7 @@ dependencies = [ [[package]] name = "gpui_web" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "anyhow", "console_error_panic_hook", @@ -2955,7 +2997,7 @@ dependencies = [ [[package]] name = "gpui_wgpu" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "anyhow", "bytemuck", @@ -2973,6 +3015,7 @@ dependencies = [ "raw-window-handle", "smallvec", "swash", + "unicode-segmentation", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -2983,7 +3026,7 @@ dependencies = [ [[package]] name = "gpui_windows" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "anyhow", "collections", @@ -3013,9 +3056,9 @@ checksum = "b40ca9252762c466af32d0b1002e91e4e1bc5398f77455e55474deb466355ff5" [[package]] name = "h2" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" dependencies = [ "atomic-waker", "bytes", @@ -3101,9 +3144,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heapless" @@ -3117,9 +3160,9 @@ dependencies = [ [[package]] name = "heapless" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af2455f757db2b292a9b1768c4b70186d443bcb3b316252d6b540aec1cd89ed" +checksum = "25ba4bd83f9415b58b4ed8dc5714c76e626a105be4646c02630ad730ad3b5aa4" dependencies = [ "hash32", "stable_deref_trait", @@ -3204,7 +3247,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "hmac", + "hmac 0.12.1", ] [[package]] @@ -3213,7 +3256,16 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.7", +] + +[[package]] +name = "hmac" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" +dependencies = [ + "digest 0.11.3", ] [[package]] @@ -3261,7 +3313,7 @@ dependencies = [ [[package]] name = "http_client" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "anyhow", "async-compression", @@ -3277,7 +3329,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "sha2", + "sha2 0.10.9", "tempfile", "url", "util", @@ -3286,7 +3338,7 @@ dependencies = [ [[package]] name = "http_client_tls" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "rustls", "rustls-platform-verifier", @@ -3298,6 +3350,15 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "hybrid-array" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +dependencies = [ + "typenum", +] + [[package]] name = "hyper" version = "1.9.0" @@ -3484,9 +3545,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -3534,9 +3595,9 @@ checksum = "edcd27d72f2f071c64249075f42e205ff93c9a4c5f6c6da53e79ed9f9832c285" [[package]] name = "imgref" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8" +checksum = "40fac9d56ed6437b198fddba683305e8e2d651aa42647f00f5ae542e7f5c94a2" [[package]] name = "indexmap" @@ -3545,7 +3606,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", "serde", "serde_core", ] @@ -3569,6 +3630,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "inout" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" +dependencies = [ + "hybrid-array", +] + [[package]] name = "instant" version = "0.1.13" @@ -3616,16 +3686,6 @@ version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" -[[package]] -name = "iri-string" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "is-docker" version = "0.2.0" @@ -3761,9 +3821,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.95" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" +checksum = "67df7112613f8bfd9150013a0314e196f4800d3201ae742489d999db2f979f08" dependencies = [ "cfg-if", "futures-util", @@ -3843,9 +3903,9 @@ checksum = "7a79a3332a6609480d7d0c9eab957bca6b455b91bb84e66d19f5ff66294b85b8" [[package]] name = "libbz2-rs-sys" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3a6a8c165077efc8f3a971534c50ea6a1a18b329ef4a66e897a7e3a1494565f" +checksum = "34b357333733e8260735ba5894eb928c02ecc69c78715f01a8019e7fa7f2db4c" [[package]] name = "libc" @@ -3888,7 +3948,7 @@ dependencies = [ "bitflags 2.11.1", "libc", "plain", - "redox_syscall 0.7.4", + "redox_syscall 0.7.5", ] [[package]] @@ -4029,9 +4089,9 @@ dependencies = [ [[package]] name = "lyon_algorithms" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9815fac08e6fd96733a11dce4f9d15a3f338e96a2e2311ee21e1b738efc2bc0f" +checksum = "8575c0d003ae459399623c4def180c63b77f343b1a7fee64f249b349e7699a31" dependencies = [ "lyon_path", "num-traits", @@ -4119,13 +4179,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ "cfg-if", - "digest", + "digest 0.10.7", ] [[package]] name = "media" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "anyhow", "bindgen", @@ -4263,31 +4323,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "naga" -version = "29.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2630921705b9b01dcdd0b6864b9562ca3c1951eecd0f0c4f5f04f61e412647" -dependencies = [ - "arrayvec", - "bit-set", - "bitflags 2.11.1", - "cfg-if", - "cfg_aliases", - "codespan-reporting", - "half", - "hashbrown 0.16.1", - "hexf-parse", - "indexmap", - "libm", - "log", - "num-traits", - "once_cell", - "rustc-hash 1.1.0", - "thiserror 2.0.18", - "unicode-ident", -] - [[package]] name = "nanorand" version = "0.7.0" @@ -4338,9 +4373,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.31.2" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d6d0705320c1e6ba1d912b5e37cf18071b6c2e9b7fa8215a1e8a7651966f5d3" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ "bitflags 2.11.1", "cfg-if", @@ -4350,9 +4385,9 @@ dependencies = [ [[package]] name = "no_std_io2" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b51ed7824b6e07d354605f4abb3d9d300350701299da96642ee084f5ce631550" +checksum = "418abd1b6d34fbf6cae440dc874771b0525a604428704c76e48b29a5e67b8003" dependencies = [ "memchr", ] @@ -4385,7 +4420,7 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" [[package]] name = "nostr" version = "0.44.1" -source = "git+https://github.com/rust-nostr/nostr#c24f879327b36717913de631be158bd88af8c2d2" +source = "git+https://github.com/rust-nostr/nostr#919b2cdd1a1909b2082911a5fff23cfbff22b8fd" dependencies = [ "aes", "base64", @@ -4409,7 +4444,7 @@ dependencies = [ [[package]] name = "nostr-blossom" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#c24f879327b36717913de631be158bd88af8c2d2" +source = "git+https://github.com/rust-nostr/nostr#919b2cdd1a1909b2082911a5fff23cfbff22b8fd" dependencies = [ "base64", "nostr", @@ -4420,7 +4455,7 @@ dependencies = [ [[package]] name = "nostr-connect" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#c24f879327b36717913de631be158bd88af8c2d2" +source = "git+https://github.com/rust-nostr/nostr#919b2cdd1a1909b2082911a5fff23cfbff22b8fd" dependencies = [ "async-utility", "futures-core", @@ -4433,7 +4468,7 @@ dependencies = [ [[package]] name = "nostr-database" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#c24f879327b36717913de631be158bd88af8c2d2" +source = "git+https://github.com/rust-nostr/nostr#919b2cdd1a1909b2082911a5fff23cfbff22b8fd" dependencies = [ "btreecap", "flatbuffers", @@ -4443,7 +4478,7 @@ dependencies = [ [[package]] name = "nostr-gossip" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#c24f879327b36717913de631be158bd88af8c2d2" +source = "git+https://github.com/rust-nostr/nostr#919b2cdd1a1909b2082911a5fff23cfbff22b8fd" dependencies = [ "nostr", ] @@ -4451,7 +4486,7 @@ dependencies = [ [[package]] name = "nostr-gossip-memory" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#c24f879327b36717913de631be158bd88af8c2d2" +source = "git+https://github.com/rust-nostr/nostr#919b2cdd1a1909b2082911a5fff23cfbff22b8fd" dependencies = [ "indexmap", "lru", @@ -4463,7 +4498,7 @@ dependencies = [ [[package]] name = "nostr-lmdb" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#c24f879327b36717913de631be158bd88af8c2d2" +source = "git+https://github.com/rust-nostr/nostr#919b2cdd1a1909b2082911a5fff23cfbff22b8fd" dependencies = [ "async-utility", "flume 0.12.0", @@ -4477,7 +4512,7 @@ dependencies = [ [[package]] name = "nostr-sdk" version = "0.44.1" -source = "git+https://github.com/rust-nostr/nostr#c24f879327b36717913de631be158bd88af8c2d2" +source = "git+https://github.com/rust-nostr/nostr#919b2cdd1a1909b2082911a5fff23cfbff22b8fd" dependencies = [ "async-utility", "async-wsocket", @@ -4775,21 +4810,21 @@ dependencies = [ "async-lock", "blocking", "cbc", - "cipher", - "digest", + "cipher 0.4.4", + "digest 0.10.7", "endi", "futures-lite 2.6.1", "futures-util", "getrandom 0.4.2", "hkdf", - "hmac", + "hmac 0.12.1", "md-5", "num", "num-bigint-dig", - "pbkdf2", + "pbkdf2 0.12.2", "serde", "serde_bytes", - "sha2", + "sha2 0.10.9", "subtle", "zbus", "zbus_macros", @@ -4805,9 +4840,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "open" -version = "5.3.4" +version = "5.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f3bab717c29a857abf75fcef718d441ec7cb2725f937343c734740a985d37fd" +checksum = "2fbaa89d2ddc8473c78a3adf69eea8cffa28c483b8e02a971ef31527cd0fc92c" dependencies = [ "is-wsl", "libc", @@ -4894,17 +4929,6 @@ dependencies = [ "windows-link 0.2.1", ] -[[package]] -name = "password-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "paste" version = "1.0.15" @@ -4948,8 +4972,18 @@ version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ - "digest", - "hmac", + "digest 0.10.7", + "hmac 0.12.1", +] + +[[package]] +name = "pbkdf2" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112d82ceb8c5bf524d9af484d4e4970c9fd5a0cc15ba14ad93dccd28873b0629" +dependencies = [ + "digest 0.11.3", + "hmac 0.13.0", ] [[package]] @@ -4961,7 +4995,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "perf" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "collections", "serde", @@ -5048,18 +5082,18 @@ checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" [[package]] name = "pin-project" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", @@ -5159,7 +5193,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", "opaque-debug", "universal-hash", ] @@ -5272,18 +5306,18 @@ dependencies = [ [[package]] name = "profiling" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" +checksum = "3d595e54a326bc53c1c197b32d295e14b169e3cfeaa8dc82b529f947fba6bcf5" dependencies = [ "profiling-procmacros", ] [[package]] name = "profiling-procmacros" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" +checksum = "4488a4a36b9a4ba6b9334a32a39971f77c1436ec82c38707bce707699cc3bbcb" dependencies = [ "quote", "syn", @@ -5359,9 +5393,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.39.2" +version = "0.39.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958f21e8e7ceb5a1aa7fa87fab28e7c75976e0bfe7e23ff069e0a260f894067d" +checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e" dependencies = [ "memchr", ] @@ -5632,9 +5666,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" +checksum = "4666a1a60d8412eab19d94f6d13dcc9cea0a5ef4fdf6a5db306537413c661b1b" dependencies = [ "bitflags 2.11.1", ] @@ -5684,7 +5718,7 @@ dependencies = [ [[package]] name = "refineable" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "derive_refineable", ] @@ -5783,7 +5817,7 @@ dependencies = [ [[package]] name = "reqwest_client" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "anyhow", "bytes", @@ -5841,9 +5875,9 @@ dependencies = [ [[package]] name = "rope" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ - "heapless 0.9.2", + "heapless 0.9.3", "log", "rayon", "sum_tree", @@ -5890,7 +5924,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1" dependencies = [ "globset", - "sha2", + "sha2 0.10.9", "walkdir", ] @@ -5959,9 +5993,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.39" +version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2c118cb077cca2822033836dfb1b975355dfb784b5e8da48f7b6c5db74e60e" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ "aws-lc-rs", "log", @@ -6075,11 +6109,12 @@ checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "salsa20" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +checksum = "2f874456e72520ff1375a06c588eaf074b0f01f9e9e1aada45bd9b7954a6e42c" dependencies = [ - "cipher", + "cfg-if", + "cipher 0.5.1", ] [[package]] @@ -6103,7 +6138,7 @@ dependencies = [ [[package]] name = "scheduler" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "async-task", "backtrace", @@ -6178,14 +6213,14 @@ dependencies = [ [[package]] name = "scrypt" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" +checksum = "d87af57419b594aa23fa95f09f0e06d80d84ba01c26148c43844cad6ff4485f0" dependencies = [ - "password-hash", - "pbkdf2", + "cfg-if", + "pbkdf2 0.13.0", "salsa20", - "sha2", + "sha2 0.11.0", ] [[package]] @@ -6404,8 +6439,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", - "digest", + "cpufeatures 0.2.17", + "digest 0.10.7", ] [[package]] @@ -6421,8 +6456,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", - "digest", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] @@ -6492,9 +6538,9 @@ dependencies = [ [[package]] name = "siphasher" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" [[package]] name = "skrifa" @@ -6708,9 +6754,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sum_tree" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ - "heapless 0.9.2", + "heapless 0.9.3", "log", "rayon", "tracing", @@ -6719,15 +6765,15 @@ dependencies = [ [[package]] name = "sval" -version = "2.18.0" +version = "2.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb9318255ebd817902d7e279d8f8e39b35b1b9954decd5eb9ea0e30e5fd2b6a" +checksum = "4a05195a68cb8336336413c3f52ea0467c7666f5f652e01ba807319ffcc090f2" [[package]] name = "sval_buffer" -version = "2.18.0" +version = "2.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12571299185e653fdb0fbfe36cd7f6529d39d4e747a60b15a3f34574b7b97c61" +checksum = "2887fd5e2454319f2f170860427f615451bb057fc9b3fd7f28b7a99ac2ccf0e4" dependencies = [ "sval", "sval_ref", @@ -6735,18 +6781,18 @@ dependencies = [ [[package]] name = "sval_dynamic" -version = "2.18.0" +version = "2.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39526f24e997706c0de7f03fb7371f7f5638b66a504ded508e20ad173d0a3677" +checksum = "12ddf3833aa407554ad40be081aea9cc3ea6d6798832ec83dd35022b45373896" dependencies = [ "sval", ] [[package]] name = "sval_fmt" -version = "2.18.0" +version = "2.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "933dd3bb26965d682280fcc49400ac2a05036f4ee1e6dbd61bf8402d5a5c3a54" +checksum = "94398bdd2ee99eee108e0b7b0df9081700a96cdefac3add5c09ad3e6f2376bcb" dependencies = [ "itoa", "ryu", @@ -6755,9 +6801,9 @@ dependencies = [ [[package]] name = "sval_json" -version = "2.18.0" +version = "2.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0cda08f6d5c9948024a6551077557b1fdcc3880ff2f20ae839667d2ec2d87ed" +checksum = "3f51ae40f37b541fdf81531e51d5071e8edc7c5a191cc23d288b654995b9eaba" dependencies = [ "itoa", "ryu", @@ -6766,9 +6812,9 @@ dependencies = [ [[package]] name = "sval_nested" -version = "2.18.0" +version = "2.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d49d5e6c1f9fd0e53515819b03a97ca4eb1bff5c8ee097c43391c09ecfb19f" +checksum = "3abe05be8455348e3f6edc14a85fd2fcf32f801a14f0126ce025e63851b4f13b" dependencies = [ "sval", "sval_buffer", @@ -6777,18 +6823,18 @@ dependencies = [ [[package]] name = "sval_ref" -version = "2.18.0" +version = "2.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f876c5a78405375b4e19cbb9554407513b59c93dea12dc6a4af4e1d30899ca" +checksum = "a36361fa3c42c9fd129f4c5023a812d5b275742b28a672c758ec70049c61df00" dependencies = [ "sval", ] [[package]] name = "sval_serde" -version = "2.18.0" +version = "2.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f9ccd3b7f7200239a655e517dd3fd48d960b9111ad24bd6a5e055bef17607c7" +checksum = "fb76707179eccecab345902a803aacacab6889f3af675dbe89766bc790b1a6cb" dependencies = [ "serde_core", "sval", @@ -7125,9 +7171,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.52.1" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -7236,7 +7282,7 @@ dependencies = [ "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", "toml_writer", - "winnow 1.0.2", + "winnow 1.0.3", ] [[package]] @@ -7280,7 +7326,7 @@ dependencies = [ "indexmap", "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", - "winnow 1.0.2", + "winnow 1.0.3", ] [[package]] @@ -7289,7 +7335,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.2", + "winnow 1.0.3", ] [[package]] @@ -7321,20 +7367,20 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "68d6fdd9f81c2819c9a8b0e0cd91660e7746a8e6ea2ba7c6b2b057985f6bcb51" dependencies = [ "bitflags 2.11.1", "bytes", "futures-util", "http", "http-body", - "iri-string", "pin-project-lite", "tower", "tower-layer", "tower-service", + "url", ] [[package]] @@ -7589,7 +7635,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "subtle", ] @@ -7672,7 +7718,7 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "util" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "anyhow", "async-fs", @@ -7711,7 +7757,7 @@ dependencies = [ [[package]] name = "util_macros" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "perf", "quote", @@ -7867,9 +7913,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" +checksum = "49ace1d07c165b0864824eee619580c4689389afa9dc9ed3a4c75040d82e6790" dependencies = [ "cfg-if", "once_cell", @@ -7880,9 +7926,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.68" +version = "0.4.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" +checksum = "96492d0d3ffba25305a7dc88720d250b1401d7edca02cc3bcd50633b424673b8" dependencies = [ "js-sys", "wasm-bindgen", @@ -7890,9 +7936,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" +checksum = "8e68e6f4afd367a562002c05637acb8578ff2dea1943df76afb9e83d177c8578" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7900,9 +7946,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" +checksum = "d95a9ec35c64b2a7cb35d3fead40c4238d0940c86d107136999567a4703259f2" dependencies = [ "bumpalo", "proc-macro2", @@ -7913,9 +7959,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.118" +version = "0.2.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" +checksum = "c4e0100b01e9f0d03189a92b96772a1fb998639d981193d7dbab487302513441" dependencies = [ "unicode-ident", ] @@ -8061,7 +8107,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c324a910fd86ebdc364a3e61ec1f11737d3b1d6c273c0239ee8ff4bc0d24b4a" dependencies = [ "proc-macro2", - "quick-xml 0.39.2", + "quick-xml 0.39.4", "quote", ] @@ -8079,9 +8125,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.95" +version = "0.3.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" +checksum = "4b572dff8bcf38bad0fa19729c89bb5748b2b9b1d8be70cf90df697e3a8f32aa" dependencies = [ "js-sys", "wasm-bindgen", @@ -8169,7 +8215,7 @@ dependencies = [ "hashbrown 0.16.1", "js-sys", "log", - "naga 29.0.0", + "naga", "parking_lot", "portable-atomic", "profiling", @@ -8199,7 +8245,7 @@ dependencies = [ "hashbrown 0.16.1", "indexmap", "log", - "naga 29.0.0", + "naga", "once_cell", "parking_lot", "portable-atomic", @@ -8264,7 +8310,7 @@ dependencies = [ "libc", "libloading", "log", - "naga 29.0.0", + "naga", "ndk-sys", "objc2", "objc2-core-foundation", @@ -8297,7 +8343,7 @@ name = "wgpu-naga-bridge" version = "29.0.0" source = "git+https://github.com/zed-industries/wgpu.git?branch=v29#a466bc382ea747f8e1ac810efdb6dcd49a514575" dependencies = [ - "naga 29.0.0", + "naga", "wgpu-types", ] @@ -8972,9 +9018,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] @@ -9231,9 +9277,9 @@ checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5" [[package]] name = "yeslogic-fontconfig-sys" -version = "6.0.0" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "503a066b4c037c440169d995b869046827dbc71263f6e8f3be6d77d4f3229dbd" +checksum = "1d8b8abf912b9a29ff112e1671c97c33636903d13a69712037190e6805af4f76" dependencies = [ "dlib", "once_cell", @@ -9265,9 +9311,9 @@ dependencies = [ [[package]] name = "zbus" -version = "5.14.0" +version = "5.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca82f95dbd3943a40a53cfded6c2d0a2ca26192011846a1810c4256ef92c60bc" +checksum = "c3bcbf15c8708d7fc1be0c993622e0a5cbd5e8b52bfa40afa4c3e0cd8d724ac1" dependencies = [ "async-broadcast", "async-executor", @@ -9292,7 +9338,7 @@ dependencies = [ "uds_windows", "uuid", "windows-sys 0.61.2", - "winnow 0.7.15", + "winnow 1.0.3", "zbus_macros", "zbus_names", "zvariant", @@ -9300,9 +9346,9 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.14.0" +version = "5.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897e79616e84aac4b2c46e9132a4f63b93105d54fe8c0e8f6bffc21fa8d49222" +checksum = "51fa5406ad9175a8c825a931f8cf347116b531b3634fcb0b627c290f1f2516ff" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -9315,12 +9361,12 @@ dependencies = [ [[package]] name = "zbus_names" -version = "4.3.1" +version = "4.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffd8af6d5b78619bab301ff3c560a5bd22426150253db278f164d6cf3b72c50f" +checksum = "7074f3e50b894eac91750142016d30d0a89be8e67dbfd9704fb875825760e52d" dependencies = [ "serde", - "winnow 0.7.15", + "winnow 1.0.3", "zvariant", ] @@ -9459,9 +9505,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] @@ -9534,7 +9580,7 @@ dependencies = [ [[package]] name = "zlog" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "anyhow", "chrono", @@ -9551,7 +9597,7 @@ checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" [[package]] name = "ztracing" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" dependencies = [ "tracing", "tracing-subscriber", @@ -9562,7 +9608,7 @@ dependencies = [ [[package]] name = "ztracing_macro" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#e3d1876c06b0e244230b4b5883e65e83ca1370e2" +source = "git+https://github.com/zed-industries/zed#f7ca86e6eeabd135645c4f25aa1ae83f5cf0231b" [[package]] name = "zune-core" @@ -9605,24 +9651,24 @@ dependencies = [ [[package]] name = "zvariant" -version = "5.10.0" +version = "5.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5708299b21903bbe348e94729f22c49c55d04720a004aa350f1f9c122fd2540b" +checksum = "1c1567a6ec68df868cbbfde844cfc6d81649fe5109a62b116b19fabd53e618ee" dependencies = [ "endi", "enumflags2", "serde", "serde_bytes", - "winnow 0.7.15", + "winnow 1.0.3", "zvariant_derive", "zvariant_utils", ] [[package]] name = "zvariant_derive" -version = "5.10.0" +version = "5.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b59b012ebe9c46656f9cc08d8da8b4c726510aef12559da3e5f1bf72780752c" +checksum = "c7d5b780599bbde114e39d9a0799577fad1ced5105d38515745f7b3099d8ceda" dependencies = [ "proc-macro-crate", "proc-macro2", @@ -9633,13 +9679,13 @@ dependencies = [ [[package]] name = "zvariant_utils" -version = "3.3.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f75c23a64ef8f40f13a6989991e643554d9bef1d682a281160cf0c1bc389c5e9" +checksum = "6d464f5733ffa07a3164d656f18533caace9d0638596721355d73256a410d691" dependencies = [ "proc-macro2", "quote", "serde", "syn", - "winnow 0.7.15", + "winnow 1.0.3", ] diff --git a/Cargo.toml b/Cargo.toml index 0d2c502..06f8bba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ nostr-connect = { git = "https://github.com/rust-nostr/nostr" } nostr-blossom = { git = "https://github.com/rust-nostr/nostr" } nostr-gossip-memory = { git = "https://github.com/rust-nostr/nostr" } nostr-sdk = { git = "https://github.com/rust-nostr/nostr" } -nostr = { git = "https://github.com/rust-nostr/nostr", features = [ "nip96", "nip59", "nip49", "nip44" ] } +nostr = { git = "https://github.com/rust-nostr/nostr", features = [ "nip59", "nip49", "nip44" ] } # Others anyhow = "1.0.44" diff --git a/crates/chat/src/lib.rs b/crates/chat/src/lib.rs index a33dcf0..77a32a4 100644 --- a/crates/chat/src/lib.rs +++ b/crates/chat/src/lib.rs @@ -373,10 +373,7 @@ impl ChatRegistry { } /// Get all messages for the provided signer - fn get_messages(&mut self, signer: T, cx: &mut Context) - where - T: NostrSigner + 'static, - { + fn get_messages(&mut self, signer: Arc, cx: &mut Context) { let task = self.subscribe_gift_wrap_events(signer, cx); self.tasks.push(cx.spawn(async move |this, cx| { @@ -421,7 +418,7 @@ impl ChatRegistry { while let Some((_url, res)) = stream.next().await { if let Ok(event) = res { - let urls: Vec = nip17::extract_owned_relay_list(event).collect(); + let urls: Vec = nip17::extract_relay_list(&event).collect(); return Ok(urls); } } @@ -431,10 +428,11 @@ impl ChatRegistry { } /// Continuously get gift wrap events for the signer - fn subscribe_gift_wrap_events(&self, signer: T, cx: &App) -> Task> - where - T: NostrSigner + 'static, - { + fn subscribe_gift_wrap_events( + &self, + signer: Arc, + cx: &App, + ) -> Task> { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); let urls = self.get_messaging_relays(cx); @@ -579,10 +577,9 @@ impl ChatRegistry { I: Into + 'static, { let nostr = NostrRegistry::global(cx); - let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); cx.spawn(async move |this, cx| { - let signer = client.signer()?; let public_key = signer.get_public_key().await.ok()?; let room: Room = room.into().organize(&public_key); @@ -712,9 +709,9 @@ impl ChatRegistry { fn get_rooms_from_database(&self, cx: &App) -> Task, Error>> { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); cx.background_spawn(async move { - let signer = client.signer().context("Signer not found")?; let public_key = signer.get_public_key().await?; // Get contacts @@ -871,10 +868,10 @@ async fn try_unwrap(signer: &Arc, gift_wrap: &Event) -> Result(gift_wrap: &Event, signer: &T) -> Result -where - T: NostrSigner + 'static, -{ +async fn try_unwrap_with( + gift_wrap: &Event, + signer: &Arc, +) -> Result { // Get the sealed event let seal = signer .nip44_decrypt(&gift_wrap.pubkey, &gift_wrap.content) @@ -906,26 +903,17 @@ async fn set_rumor(client: &Client, id: EventId, rumor: &UnsignedEvent) -> Resul tags.push(Tag::identifier(id)); // Add a reference to the rumor's author - tags.push(Tag::custom( - TagKind::SingleLetter(SingleLetterTag::lowercase(Alphabet::A)), - [author], - )); + tags.push(Tag::custom("a", [author])); // Add a conversation id - tags.push(Tag::custom( - TagKind::SingleLetter(SingleLetterTag::lowercase(Alphabet::C)), - [conversation.to_string()], - )); + tags.push(Tag::custom("c", [conversation.to_string()])); // Add a reference to the rumor's id tags.push(Tag::event(rumor_id)); // Add references to the rumor's participants - for receiver in rumor.tags.public_keys().copied() { - tags.push(Tag::custom( - TagKind::SingleLetter(SingleLetterTag::lowercase(Alphabet::P)), - [receiver], - )); + for receiver in rumor.tags.public_keys() { + tags.push(Tag::public_key(receiver)); } // Convert rumor to json @@ -934,7 +922,7 @@ async fn set_rumor(client: &Client, id: EventId, rumor: &UnsignedEvent) -> Resul // Construct the event let event = EventBuilder::new(Kind::ApplicationSpecificData, content) .tags(tags) - .sign(&Keys::generate()) + .sign_async(&Keys::generate()) .await?; // Save the event to the database @@ -960,7 +948,7 @@ async fn get_rumor(client: &Client, gift_wrap: EventId) -> Result u64 { let mut hasher = DefaultHasher::new(); - let mut pubkeys: Vec = rumor.tags.public_keys().copied().collect(); + let mut pubkeys: Vec = rumor.tags.public_keys().collect(); pubkeys.push(rumor.pubkey); pubkeys.sort(); pubkeys.dedup(); diff --git a/crates/chat/src/message.rs b/crates/chat/src/message.rs index 3234226..10a8ba6 100644 --- a/crates/chat/src/message.rs +++ b/crates/chat/src/message.rs @@ -242,13 +242,13 @@ fn extract_mentions(content: &str) -> Vec { fn extract_reply_ids(inner: &Tags) -> Vec { let mut replies_to = vec![]; - for tag in inner.filter(TagKind::e()) { + for tag in inner.iter().filter(|tag| tag.kind() == "e") { if let Some(id) = tag.content().and_then(|id| EventId::parse(id).ok()) { replies_to.push(id); } } - for tag in inner.filter(TagKind::q()) { + for tag in inner.iter().filter(|tag| tag.kind() == "q") { if let Some(id) = tag.content().and_then(|id| EventId::parse(id).ok()) { replies_to.push(id); } diff --git a/crates/chat/src/room.rs b/crates/chat/src/room.rs index c77a1fb..16e58ca 100644 --- a/crates/chat/src/room.rs +++ b/crates/chat/src/room.rs @@ -1,15 +1,16 @@ use std::cmp::Ordering; use std::hash::{Hash, Hasher}; +use std::sync::Arc; use std::time::Duration; -use anyhow::{Error, anyhow}; +use anyhow::Error; use common::EventExt; use gpui::{App, AppContext, Context, EventEmitter, SharedString, Task}; use itertools::Itertools; use nostr_sdk::prelude::*; use person::{Person, PersonRegistry}; use settings::{RoomConfig, SignerKind}; -use state::{NostrRegistry, TIMEOUT}; +use state::{CoopSigner, NostrRegistry, TIMEOUT}; use crate::NewMessage; @@ -171,7 +172,8 @@ impl From<&UnsignedEvent> for Room { let members = val.extract_public_keys(); let subject = val .tags - .find(TagKind::Subject) + .iter() + .find(|tag| tag.kind() == "subject") .and_then(|tag| tag.content().map(|s| s.to_owned().into())); Room { @@ -440,9 +442,7 @@ impl Room { // Add subject tag if present if let Some(value) = self.subject.as_ref() { - tags.push(Tag::from_standardized_without_cell(TagStandard::Subject( - value.to_string(), - ))); + tags.push(Tag::custom("subject", vec![value.to_string()])); } // Add all reply tags @@ -452,14 +452,13 @@ impl Room { // Add all receiver tags for member in members.into_iter() { - tags.push(Tag::from_standardized_without_cell( - TagStandard::PublicKey { + tags.push( + Nip01Tag::PublicKey { public_key: member.public_key(), - relay_url: member.messaging_relay_hint(), - alias: None, - uppercase: false, - }, - )); + relay_hint: member.messaging_relay_hint(), + } + .to_tag(), + ); } // Construct a direct message rumor event @@ -474,9 +473,9 @@ impl Room { /// Send rumor event to all members's messaging relays pub fn send(&self, rumor: UnsignedEvent, cx: &App) -> Option>> { - let config = self.config.clone(); let persons = PersonRegistry::global(cx); let nostr = NostrRegistry::global(cx); + let client = nostr.read(cx).client(); let signer = nostr.read(cx).signer(); @@ -484,6 +483,8 @@ impl Room { let public_key = nostr.read(cx).signer().public_key()?; let sender = persons.read(cx).get(&public_key, cx); + let config = self.config.clone(); + // Get all members (excluding sender) let members: Vec = self .members @@ -492,12 +493,10 @@ impl Room { .map(|member| persons.read(cx).get(member, cx)) .collect(); - Some(cx.background_spawn(async move { + Some(cx.spawn(async move |_cx| { let signer_kind = config.signer_kind(); let backup = config.backup(); - - let user_signer = signer.get().await; - let encryption_signer = signer.get_encryption_signer().await; + let has_encryption_signer = signer.has_encryption_signer().await; let mut sents = 0; let mut reports = Vec::new(); @@ -516,33 +515,21 @@ impl Room { } // Sender didn't set up a decoupled encryption key - if encryption_signer.is_none() { + if !has_encryption_signer { reports.push(SendReport::new(sender.public_key()).error(USER_NO_DEKEY)); continue; } } // Determine the signer to use - let signer = match signer_kind { - SignerKind::Auto => { - if announcement.is_some() - && let Some(encryption_signer) = encryption_signer.clone() - { - // Safe to unwrap due to earlier checks - encryption_signer - } else { - user_signer.clone() - } - } - SignerKind::Encryption => { - // Safe to unwrap due to earlier checks - encryption_signer.as_ref().unwrap().clone() - } - SignerKind::User => user_signer.clone(), + let use_encryption = match signer_kind { + SignerKind::Auto => announcement.is_some() && has_encryption_signer, + SignerKind::Encryption => true, + SignerKind::User => false, }; // Send the gift wrap event and collect the report - match send_gift_wrap(&client, &signer, &member, &rumor, signer_kind).await { + match send_gift_wrap(&client, &signer, &member, &rumor, use_encryption).await { Ok(report) => { reports.push(report); sents += 1; @@ -559,25 +546,13 @@ impl Room { let public_key = sender.public_key(); // Determine the signer to use - let signer = match signer_kind { - SignerKind::Auto => { - if sender.announcement().is_some() - && let Some(encryption_signer) = encryption_signer.clone() - { - // Safe to unwrap due to earlier checks - encryption_signer - } else { - user_signer.clone() - } - } - SignerKind::Encryption => { - // Safe to unwrap due to earlier checks - encryption_signer.as_ref().unwrap().clone() - } - SignerKind::User => user_signer.clone(), + let use_encryption = match signer_kind { + SignerKind::Auto => sender.announcement().is_some() && has_encryption_signer, + SignerKind::Encryption => true, + SignerKind::User => false, }; - match send_gift_wrap(&client, &signer, &sender, &rumor, signer_kind).await { + match send_gift_wrap(&client, &signer, &sender, &rumor, use_encryption).await { Ok(report) => reports.push(report), Err(error) => { let report = SendReport::new(public_key).error(error.to_string()); @@ -592,22 +567,19 @@ impl Room { } // Helper function to send a gift-wrapped event -async fn send_gift_wrap( +async fn send_gift_wrap( client: &Client, - signer: &T, + signer: &Arc, receiver: &Person, rumor: &UnsignedEvent, - config: &SignerKind, -) -> Result -where - T: NostrSigner + 'static, -{ - let k_tag = Tag::custom(TagKind::k(), vec!["14"]); + encryption: bool, +) -> Result { + let k_tag = Tag::custom("k", vec!["14"]); let mut extra_tags = vec![k_tag]; // Determine the receiver public key based on the config - let receiver = match config { - SignerKind::Auto => { + let receiver = match encryption { + true => { if let Some(announcement) = receiver.announcement().as_ref() { extra_tags.push(Tag::public_key(receiver.public_key())); announcement.public_key() @@ -615,19 +587,20 @@ where receiver.public_key() } } - SignerKind::Encryption => { - if let Some(announcement) = receiver.announcement().as_ref() { - extra_tags.push(Tag::public_key(receiver.public_key())); - announcement.public_key() - } else { - return Err(anyhow!("User has no encryption announcement")); - } - } - SignerKind::User => receiver.public_key(), + false => receiver.public_key(), }; // Construct the gift wrap event - let event = EventBuilder::gift_wrap(signer, &receiver, rumor.clone(), extra_tags).await?; + let event = match encryption { + true => { + let signer = signer.get_encryption_signer().await.unwrap(); + EventBuilder::gift_wrap_async(&signer, &receiver, rumor.clone(), extra_tags).await? + } + false => { + let signer = signer.get().await; + EventBuilder::gift_wrap_async(&signer, &receiver, rumor.clone(), extra_tags).await? + } + }; // Send the gift wrap event and collect the report let report = client diff --git a/crates/common/src/event.rs b/crates/common/src/event.rs index 194cddf..e115775 100644 --- a/crates/common/src/event.rs +++ b/crates/common/src/event.rs @@ -18,7 +18,7 @@ impl EventExt for Event { } fn extract_public_keys(&self) -> Vec { - let mut public_keys: Vec = self.tags.public_keys().copied().collect(); + let mut public_keys: Vec = self.tags.public_keys().collect(); public_keys.push(self.pubkey); public_keys.into_iter().unique().collect() @@ -46,7 +46,7 @@ impl EventExt for UnsignedEvent { } fn extract_public_keys(&self) -> Vec { - let mut public_keys: Vec = self.tags.public_keys().copied().collect(); + let mut public_keys: Vec = self.tags.public_keys().collect(); public_keys.push(self.pubkey); public_keys.into_iter().unique().sorted().collect() } diff --git a/crates/device/src/lib.rs b/crates/device/src/lib.rs index add0642..99c201d 100644 --- a/crates/device/src/lib.rs +++ b/crates/device/src/lib.rs @@ -2,6 +2,7 @@ use std::cell::Cell; use std::collections::HashSet; use std::path::PathBuf; use std::rc::Rc; +use std::sync::Arc; use std::time::Duration; use anyhow::{Context as AnyhowContext, Error, anyhow}; @@ -11,7 +12,7 @@ use gpui::{ }; use nostr_sdk::prelude::*; use person::PersonRegistry; -use state::{Announcement, NostrRegistry, StateEvent, TIMEOUT, app_name}; +use state::{Announcement, CoopSigner, NostrRegistry, StateEvent, TIMEOUT, app_name}; use theme::ActiveTheme; use ui::avatar::Avatar; use ui::button::Button; @@ -110,6 +111,8 @@ impl DeviceRegistry { fn handle_notifications(&mut self, window: &mut Window, cx: &mut Context) { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); + let (tx, rx) = flume::bounded::(100); self.tasks.push(cx.background_spawn(async move { @@ -127,12 +130,12 @@ impl DeviceRegistry { match event.kind { Kind::Custom(4454) => { - if verify_author(&client, event.as_ref()).await { + if verify_author(&signer, event.as_ref()).await { tx.send_async(event.into_owned()).await?; } } Kind::Custom(4455) => { - if verify_author(&client, event.as_ref()).await { + if verify_author(&signer, event.as_ref()).await { tx.send_async(event.into_owned()).await?; } } @@ -181,7 +184,7 @@ impl DeviceRegistry { /// Set the decoupled encryption key for the current user fn set_signer(&mut self, new: S, cx: &mut Context) where - S: NostrSigner + 'static, + S: AsyncNostrSigner, { let nostr = NostrRegistry::global(cx); let signer = nostr.read(cx).signer(); @@ -203,9 +206,10 @@ impl DeviceRegistry { pub fn backup(&self, path: PathBuf, cx: &App) -> Task> { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); cx.background_spawn(async move { - let keys = get_keys(&client).await?; + let keys = get_keys(&client, &signer).await?; let content = keys.secret_key().to_bech32()?; smol::fs::write(path, &content).await?; @@ -218,9 +222,10 @@ impl DeviceRegistry { pub fn get_announcement(&mut self, cx: &mut Context) { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); let task: Task> = cx.background_spawn(async move { - let signer = client.signer().context("Signer not found")?; + let signer = signer.get().await; let public_key = signer.get_public_key().await?; // Construct the filter for the device announcement event @@ -293,19 +298,24 @@ impl DeviceRegistry { fn create_encryption(&self, keys: Keys, cx: &App) -> Task> { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); let secret = keys.secret_key().to_secret_hex(); let n = keys.public_key(); cx.background_spawn(async move { // Construct an announcement event - let builder = EventBuilder::new(Kind::Custom(10044), "").tags(vec![ - Tag::custom(TagKind::custom("n"), vec![n]), - Tag::client(app_name()), - ]); - - // Sign the event with user's signer - let event = client.sign_event_builder(builder).await?; + let event = EventBuilder::new(Kind::Custom(10044), "") + .tags(vec![ + Tag::custom("n", vec![n]), + Nip89Tag::Client { + name: app_name().to_string(), + address: None, + } + .to_tag(), + ]) + .sign_async(&signer.get().await) + .await?; // Publish announcement client @@ -315,7 +325,7 @@ impl DeviceRegistry { .await?; // Save device keys to the database - set_keys(&client, &secret).await?; + set_keys(&client, &signer, &secret).await?; Ok(keys) }) @@ -325,13 +335,14 @@ impl DeviceRegistry { fn set_encryption(&mut self, event: &Event, cx: &mut Context) { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); let announcement = Announcement::from(event); let device_pubkey = announcement.public_key(); // Get encryption key from the database and compare with the announcement let task: Task> = cx.background_spawn(async move { - let keys = get_keys(&client).await?; + let keys = get_keys(&client, &signer).await?; // Compare the public key from the announcement with the one from the database if keys.public_key() != device_pubkey { @@ -403,14 +414,20 @@ impl DeviceRegistry { Some(event) => Ok(Some(event)), // No approval event found, construct a request event None => { - // Construct an event for device key request - let builder = EventBuilder::new(Kind::Custom(4454), "").tags(vec![ - Tag::custom(TagKind::custom("P"), vec![app_pubkey]), - Tag::client(app_name()), - ]); + let signer = signer.get().await; - // Sign the event with user's signer - let event = client.sign_event_builder(builder).await?; + // Construct an event for device key request + let event = EventBuilder::new(Kind::Custom(4454), "") + .tags(vec![ + Tag::custom("P", vec![app_pubkey]), + Nip89Tag::Client { + name: app_name().to_string(), + address: None, + } + .to_tag(), + ]) + .sign_async(&signer) + .await?; // Send the event to write relays client.send_event(&event).to_nip65().await?; @@ -471,17 +488,19 @@ impl DeviceRegistry { fn extract_encryption(&mut self, event: Event, cx: &mut Context) { let nostr = NostrRegistry::global(cx); let app_keys = nostr.read(cx).keys(); + let app_signer: Arc = Arc::new(app_keys); let task: Task> = cx.background_spawn(async move { let master = event .tags - .find(TagKind::custom("P")) + .iter() + .find(|tag| tag.kind() == "P") .and_then(|tag| tag.content()) .and_then(|content| PublicKey::parse(content).ok()) .context("Invalid event's tags")?; let payload = event.content.as_str(); - let decrypted = app_keys.nip44_decrypt(&master, payload).await?; + let decrypted = app_signer.nip44_decrypt(&master, payload).await?; let secret = SecretKey::from_hex(&decrypted)?; let keys = Keys::new(secret); @@ -510,6 +529,7 @@ impl DeviceRegistry { fn approve(&mut self, event: &Event, window: &mut Window, cx: &mut Context) { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); // Get user's write relays let event = event.clone(); @@ -517,31 +537,36 @@ impl DeviceRegistry { let task: Task> = cx.background_spawn(async move { // Get device keys - let keys = get_keys(&client).await?; + let keys = get_keys(&client, &signer).await?; + let public_key = keys.public_key(); let secret = keys.secret_key().to_secret_hex(); + let device_signer: Arc = Arc::new(keys); + + let signer = signer.get().await; // Extract the target public key from the event tags let target = event .tags - .find(TagKind::custom("P")) + .iter() + .find(|tag| tag.kind() == "P") .and_then(|tag| tag.content()) .and_then(|content| PublicKey::parse(content).ok()) .context("Target is not a valid public key")?; // Encrypt the device keys with the user's signer - let payload = keys.nip44_encrypt(&target, &secret).await?; + let payload = device_signer.nip44_encrypt(&target, &secret).await?; // Construct the response event // // P tag: the current device's public key // p tag: the requester's public key - let builder = EventBuilder::new(Kind::Custom(4455), payload).tags(vec![ - Tag::custom(TagKind::custom("P"), vec![keys.public_key().to_hex()]), - Tag::public_key(target), - ]); - - // Sign the builder - let event = client.sign_event_builder(builder).await?; + let event = EventBuilder::new(Kind::Custom(4455), payload) + .tags(vec![ + Tag::custom("P", vec![public_key.to_hex()]), + Tag::public_key(target), + ]) + .sign_async(&signer) + .await?; // Send the response event to the user's relay list client.send_event(&event).to_nip65().await?; @@ -689,18 +714,15 @@ impl DeviceRegistry { struct DeviceNotification; /// Verify the author of an event -async fn verify_author(client: &Client, event: &Event) -> bool { - if let Some(signer) = client.signer() - && let Ok(public_key) = signer.get_public_key().await - { +async fn verify_author(signer: &Arc, event: &Event) -> bool { + if let Ok(public_key) = signer.get_public_key().await { return public_key == event.pubkey; } false } /// Encrypt and store device keys in the local database. -async fn set_keys(client: &Client, secret: &str) -> Result<(), Error> { - let signer = client.signer().context("Signer not found")?; +async fn set_keys(client: &Client, signer: &Arc, secret: &str) -> Result<(), Error> { let public_key = signer.get_public_key().await?; // Encrypt the value @@ -710,7 +732,7 @@ async fn set_keys(client: &Client, secret: &str) -> Result<(), Error> { let event = EventBuilder::new(Kind::ApplicationSpecificData, content) .tag(Tag::identifier(IDENTIFIER)) .build(public_key) - .sign(&Keys::generate()) + .sign_async(&Keys::generate()) .await?; // Save the event to the database @@ -720,8 +742,7 @@ async fn set_keys(client: &Client, secret: &str) -> Result<(), Error> { } /// Get device keys from the local database. -async fn get_keys(client: &Client) -> Result { - let signer = client.signer().context("Signer not found")?; +async fn get_keys(client: &Client, signer: &Arc) -> Result { let public_key = signer.get_public_key().await?; let filter = Filter::new() diff --git a/crates/person/src/lib.rs b/crates/person/src/lib.rs index 3f72f99..b8423f1 100644 --- a/crates/person/src/lib.rs +++ b/crates/person/src/lib.rs @@ -242,7 +242,7 @@ impl PersonRegistry { /// Set messaging relays for a person fn set_messaging_relays(&mut self, event: &Event, cx: &mut App) { - let urls: Vec = nip17::extract_relay_list(event).cloned().collect(); + let urls: Vec = nip17::extract_relay_list(event).collect(); if let Some(person) = self.persons.get(&event.pubkey) { person.update(cx, |person, cx| { diff --git a/crates/relay_auth/src/lib.rs b/crates/relay_auth/src/lib.rs index 4bac09a..bb820e0 100644 --- a/crates/relay_auth/src/lib.rs +++ b/crates/relay_auth/src/lib.rs @@ -193,15 +193,19 @@ impl RelayAuth { fn auth(&self, req: &Arc, cx: &App) -> Task> { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); let req = req.clone(); // Get all pending events for the relay let pending_events = self.get_pending_events(req.url(), cx); cx.background_spawn(async move { + let signer = signer.get().await; + // Construct event - let builder = EventBuilder::auth(req.challenge(), req.url().clone()); - let event = client.sign_event_builder(builder).await?; + let event = EventBuilder::auth(req.challenge(), req.url().clone()) + .sign_async(&signer) + .await?; // Get the event ID let id = event.id; diff --git a/crates/state/src/device.rs b/crates/state/src/device.rs index 4aae264..475795c 100644 --- a/crates/state/src/device.rs +++ b/crates/state/src/device.rs @@ -16,14 +16,15 @@ impl From<&Event> for Announcement { let public_key = val .tags .iter() - .find(|tag| tag.kind().as_str() == "n") + .find(|tag| tag.kind() == "n") .and_then(|tag| tag.content()) .and_then(|c| PublicKey::parse(c).ok()) .unwrap_or(val.pubkey); let client_name = val .tags - .find(TagKind::Client) + .iter() + .find(|tag| tag.kind() == "client") .and_then(|tag| tag.content()) .map(|c| c.to_string()); diff --git a/crates/state/src/lib.rs b/crates/state/src/lib.rs index 9f177eb..4d07f84 100644 --- a/crates/state/src/lib.rs +++ b/crates/state/src/lib.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use std::sync::Arc; use std::time::Duration; -use anyhow::{Context as AnyhowContext, Error, anyhow}; +use anyhow::{Error, anyhow}; use common::config_dir; use gpui::{App, AppContext, Context, Entity, EventEmitter, Global, SharedString, Task, Window}; use nostr_connect::prelude::*; @@ -130,10 +130,8 @@ impl NostrRegistry { // Construct the nostr client let client = ClientBuilder::default() - .signer(signer.clone()) .database(lmdb) .gossip(NostrGossipMemory::unbounded()) - .automatic_authentication(false) .connect_timeout(Duration::from_secs(10)) .sleep_when_idle(SleepWhenIdle::Enabled { timeout: Duration::from_secs(600), @@ -236,10 +234,7 @@ impl NostrRegistry { } // Connect to all added relays - client - .connect() - .and_wait(Duration::from_secs(TIMEOUT)) - .await; + client.connect().await; Ok(()) }); @@ -262,70 +257,73 @@ impl NostrRegistry { })); } - /// Get the secret for a given npub. - pub fn get_secret( - &self, - public_key: PublicKey, - cx: &App, - ) -> Task, Error>> { + /// Switch to a different account by public key + pub fn switch_account(&self, public_key: PublicKey, cx: &App) -> Result<(), Error> { + let client = self.client(); + let signer = self.signer(); + let npub = public_key.to_bech32().unwrap(); let key_path = self.key_dir.join(format!("{}.npub", npub)); let app_keys = self.app_keys.clone(); + let app_signer: Arc = Arc::new(app_keys.clone()); - if let Ok(payload) = std::fs::read_to_string(key_path) { - if !payload.is_empty() { - cx.background_spawn(async move { - let decrypted = app_keys.nip44_decrypt(&public_key, &payload).await?; - let secret = SecretKey::parse(&decrypted)?; - let keys = Keys::new(secret); + if let Ok(payload) = std::fs::read_to_string(key_path) + && !payload.is_empty() + { + let decrypted = app_signer.nip44_decrypt(&public_key, &payload)?; - Ok(keys.into_nostr_signer()) + if let Ok(secret) = SecretKey::parse(&decrypted) { + let keys = Keys::new(secret); + cx.spawn(async move |_cx| { + signer.switch(keys).await; + client.unsubscribe_all().await.ok(); }) - } else { - self.get_secret_keyring(&npub, cx) + .detach(); + + return Ok(()); + } else if let Ok(uri) = NostrConnectUri::parse(decrypted) { + let timeout = Duration::from_secs(NOSTR_CONNECT_TIMEOUT); + let mut nip46 = NostrConnect::new(uri, app_keys, timeout, None)?; + nip46.auth_url_handler(CoopAuthUrlHandler); + + cx.spawn(async move |_cx| { + signer.switch(nip46).await; + client.unsubscribe_all().await.ok(); + }) + .detach(); + + return Ok(()); } - } else { - self.get_secret_keyring(&npub, cx) } + + Err(anyhow!("Secret not found")) } - /// Get the secret for a given npub in the OS credentials store. - #[deprecated = "Use get_secret instead"] - fn get_secret_keyring( - &self, - user: &str, - cx: &App, - ) -> Task, Error>> { - let read = cx.read_credentials(user); + /// Get the secret for a given npub. + pub fn get_secret(&self, public_key: PublicKey) -> Result, Error> { + let npub = public_key.to_bech32().unwrap(); + let key_path = self.key_dir.join(format!("{}.npub", npub)); let app_keys = self.app_keys.clone(); + let app_signer: Arc = Arc::new(self.app_keys.clone()); - cx.background_spawn(async move { - let (_, secret) = read - .await - .map_err(|_| anyhow!("Failed to get signer. Please re-import the secret key"))? - .ok_or_else(|| anyhow!("Failed to get signer. Please re-import the secret key"))?; + if let Ok(payload) = std::fs::read_to_string(key_path) + && !payload.is_empty() + { + let decrypted = app_signer.nip44_decrypt(&public_key, &payload)?; - // Try to parse as a direct secret key first - if let Ok(secret_key) = SecretKey::from_slice(&secret) { - return Ok(Keys::new(secret_key).into_nostr_signer()); + if let Ok(secret) = SecretKey::parse(&decrypted) { + let keys = Keys::new(secret); + return Ok(Arc::new(keys)); + } else if let Ok(uri) = NostrConnectUri::parse(decrypted) { + let timeout = Duration::from_secs(NOSTR_CONNECT_TIMEOUT); + let mut nip46 = NostrConnect::new(uri, app_keys, timeout, None)?; + nip46.auth_url_handler(CoopAuthUrlHandler); + + return Ok(Arc::new(nip46)); } + } - // Convert the secret into string - let sec = String::from_utf8(secret) - .map_err(|_| anyhow!("Failed to parse secret as UTF-8"))?; - - // Try to parse as a NIP-46 URI - let uri = - NostrConnectUri::parse(&sec).map_err(|_| anyhow!("Failed to parse NIP-46 URI"))?; - - let timeout = Duration::from_secs(NOSTR_CONNECT_TIMEOUT); - let mut nip46 = NostrConnect::new(uri, app_keys, timeout, None)?; - - // Set the auth URL handler - nip46.auth_url_handler(CoopAuthUrlHandler); - - Ok(nip46.into_nostr_signer()) - }) + Err(anyhow!("Secret not found")) } /// Add a new npub to the keys directory @@ -337,7 +335,7 @@ impl NostrRegistry { ) -> Task> { let npub = public_key.to_bech32().unwrap(); let key_path = self.key_dir.join(format!("{}.npub", npub)); - let app_keys = self.app_keys.clone(); + let app_keys: Arc = Arc::new(self.app_keys.clone()); cx.background_spawn(async move { // If the secret starts with "bunker://" (nostr connect), use it directly; otherwise, encrypt it @@ -386,11 +384,11 @@ impl NostrRegistry { // Run async tasks in background let task: Task> = cx.background_spawn(async move { - let signer = async_keys.into_nostr_signer(); - // Construct relay list event let relay_list = default_relay_list(); - let event = EventBuilder::relay_list(relay_list).sign(&signer).await?; + let event = EventBuilder::relay_list(relay_list) + .sign_async(&async_keys) + .await?; // Publish relay list client @@ -403,7 +401,9 @@ impl NostrRegistry { let name = petname::petname(2, "-").unwrap_or("Cooper".to_string()); let avatar = Url::parse(&format!("https://avatar.vercel.sh/{name}")).unwrap(); let metadata = Metadata::new().display_name(&name).picture(avatar); - let event = EventBuilder::metadata(&metadata).sign(&signer).await?; + let event = EventBuilder::metadata(&metadata) + .sign_async(&async_keys) + .await?; // Publish metadata event client @@ -414,7 +414,9 @@ impl NostrRegistry { // Construct the default contact list let contacts = vec![Contact::new(PublicKey::parse(COOP_PUBKEY).unwrap())]; - let event = EventBuilder::contact_list(contacts).sign(&signer).await?; + let event = EventBuilder::contact_list(contacts) + .sign_async(&async_keys) + .await?; // Publish contact list event client @@ -425,7 +427,9 @@ impl NostrRegistry { // Construct the default messaging relay list let relays = default_messaging_relays(); - let event = EventBuilder::nip17_relay_list(relays).sign(&signer).await?; + let event = EventBuilder::nip17_relay_list(relays) + .sign_async(&async_keys) + .await?; // Publish messaging relay list event client.send_event(&event).to_nip65().await?; @@ -440,56 +444,7 @@ impl NostrRegistry { match task.await { Ok(_) => { this.update(cx, |this, cx| { - this.set_signer(keys, cx); - })?; - } - Err(e) => { - this.update(cx, |_this, cx| { - cx.emit(StateEvent::error(e.to_string())); - })?; - } - }; - - Ok(()) - })); - } - - /// Set the signer for the nostr client and verify the public key - pub fn set_signer(&mut self, new: T, cx: &mut Context) - where - T: NostrSigner + 'static, - { - let client = self.client(); - let signer = self.signer(); - - // Create a task to update the signer and verify the public key - let task: Task> = cx.background_spawn(async move { - // Update signer and unsubscribe - signer.switch(new).await; - client.unsubscribe_all().await?; - - // Verify and get public key - let signer = client.signer().context("Signer not found")?; - let public_key = signer.get_public_key().await?; - - log::info!("Signer's public key: {}", public_key); - Ok(public_key) - }); - - self.tasks.push(cx.spawn(async move |this, cx| { - match task.await { - Ok(public_key) => { - this.update(cx, |this, cx| { - // Add public key to npubs if not already present - this.npubs.update(cx, |this, cx| { - if !this.contains(&public_key) { - this.push(public_key); - cx.notify(); - } - }); - - // Emit signer changed event - cx.emit(StateEvent::SignerSet); + this.switch_account(keys.public_key(), cx); })?; } Err(e) => { @@ -513,7 +468,7 @@ impl NostrRegistry { match write_secret.await { Ok(_) => { this.update(cx, |this, cx| { - this.set_signer(keys, cx); + this.switch_account(keys.public_key(), cx); })?; } Err(e) => { @@ -552,7 +507,7 @@ impl NostrRegistry { match write_secret.await { Ok(_) => { this.update(cx, |this, cx| { - this.set_signer(nip46, cx); + this.switch_account(public_key, cx); })?; } Err(e) => { @@ -670,14 +625,19 @@ impl NostrRegistry { pub fn wot_search(&self, query: &str, cx: &App) -> Task, Error>> { let client = self.client(); let query = query.to_string(); + let signer = self.signer(); cx.background_spawn(async move { + let signer = signer.get().await; + // Construct a vertex request event - let builder = EventBuilder::new(Kind::Custom(5315), "").tags(vec![ - Tag::custom(TagKind::custom("param"), vec!["search", &query]), - Tag::custom(TagKind::custom("param"), vec!["limit", "10"]), - ]); - let event = client.sign_event_builder(builder).await?; + let event = EventBuilder::new(Kind::Custom(5315), "") + .tags(vec![ + Tag::custom("param", vec!["search", &query]), + Tag::custom("param", vec!["limit", "10"]), + ]) + .sign_async(&signer) + .await?; // Send the event to vertex relays let output = client.send_event(&event).to(WOT_RELAYS).await?; diff --git a/crates/state/src/signer.rs b/crates/state/src/signer.rs index c6e9b20..b0a93cc 100644 --- a/crates/state/src/signer.rs +++ b/crates/state/src/signer.rs @@ -7,38 +7,42 @@ use smol::lock::RwLock; #[derive(Debug)] pub struct CoopSigner { - /// User's signer - signer: RwLock>, + signer: Arc>>, /// User's signer public key - signer_pkey: RwLock>, + signer_pkey: Arc>>, /// Specific signer for encryption purposes - encryption_signer: RwLock>>, + encryption_signer: Arc>>>, } impl CoopSigner { pub fn new(signer: T) -> Self where - T: IntoNostrSigner, + T: AsyncNostrSigner, { Self { - signer: RwLock::new(signer.into_nostr_signer()), - signer_pkey: RwLock::new(None), - encryption_signer: RwLock::new(None), + signer: Arc::new(RwLock::new(Arc::new(signer))), + signer_pkey: Arc::new(RwLock::new(None)), + encryption_signer: Arc::new(RwLock::new(None)), } } /// Get the current signer. - pub async fn get(&self) -> Arc { + pub async fn get(&self) -> Arc { self.signer.read().await.clone() } /// Get the encryption signer. - pub async fn get_encryption_signer(&self) -> Option> { + pub async fn get_encryption_signer(&self) -> Option> { self.encryption_signer.read().await.clone() } + /// Check if the encryption signer is available. + pub async fn has_encryption_signer(&self) -> bool { + self.encryption_signer.read().await.is_some() + } + /// Get public key /// /// Ensure to call this method after the signer has been initialized. @@ -50,19 +54,17 @@ impl CoopSigner { /// Switch the current signer to a new signer. pub async fn switch(&self, new: T) where - T: IntoNostrSigner, + T: AsyncNostrSigner, { - let new_signer = new.into_nostr_signer(); - let public_key = new_signer.get_public_key().await.ok(); let mut signer = self.signer.write().await; let mut signer_pkey = self.signer_pkey.write().await; let mut encryption_signer = self.encryption_signer.write().await; - // Switch to the new signer - *signer = new_signer; - // Update the public key - *signer_pkey = public_key; + *signer_pkey = new.get_public_key().await.ok(); + + // Switch to the new signer + *signer = Arc::new(new); // Reset the encryption signer *encryption_signer = None; @@ -71,35 +73,33 @@ impl CoopSigner { /// Set the encryption signer. pub async fn set_encryption_signer(&self, new: T) where - T: IntoNostrSigner, + T: AsyncNostrSigner, { let mut encryption_signer = self.encryption_signer.write().await; - *encryption_signer = Some(new.into_nostr_signer()); + *encryption_signer = Some(Arc::new(new)); } } -impl NostrSigner for CoopSigner { - #[allow(mismatched_lifetime_syntaxes)] - fn backend(&self) -> SignerBackend { - SignerBackend::Custom(Cow::Borrowed("custom")) - } - - fn get_public_key<'a>(&'a self) -> BoxedFuture<'a, Result> { +impl AsyncGetPublicKey for CoopSigner { + fn get_public_key(&self) -> BoxedFuture<'_, Result> { Box::pin(async move { self.get().await.get_public_key().await }) } +} - fn sign_event<'a>( - &'a self, - unsigned: UnsignedEvent, - ) -> BoxedFuture<'a, Result> { +impl AsyncSignEvent for CoopSigner { + fn sign_event(&self, unsigned: UnsignedEvent) -> BoxedFuture<'_, Result> { Box::pin(async move { self.get().await.sign_event(unsigned).await }) } +} + +impl AsyncNip04 for CoopSigner { + type Error = SignerError; fn nip04_encrypt<'a>( &'a self, public_key: &'a PublicKey, content: &'a str, - ) -> BoxedFuture<'a, Result> { + ) -> BoxedFuture<'a, Result> { Box::pin(async move { self.get().await.nip04_encrypt(public_key, content).await }) } @@ -107,7 +107,7 @@ impl NostrSigner for CoopSigner { &'a self, public_key: &'a PublicKey, encrypted_content: &'a str, - ) -> BoxedFuture<'a, Result> { + ) -> BoxedFuture<'a, Result> { Box::pin(async move { self.get() .await @@ -115,12 +115,16 @@ impl NostrSigner for CoopSigner { .await }) } +} + +impl AsyncNip44 for CoopSigner { + type Error = SignerError; fn nip44_encrypt<'a>( &'a self, public_key: &'a PublicKey, content: &'a str, - ) -> BoxedFuture<'a, Result> { + ) -> BoxedFuture<'a, Result> { Box::pin(async move { self.get().await.nip44_encrypt(public_key, content).await }) } @@ -128,7 +132,13 @@ impl NostrSigner for CoopSigner { &'a self, public_key: &'a PublicKey, payload: &'a str, - ) -> BoxedFuture<'a, Result> { + ) -> BoxedFuture<'a, Result> { Box::pin(async move { self.get().await.nip44_decrypt(public_key, payload).await }) } } + +impl AsyncNostrSigner for CoopSigner { + fn backend(&self) -> SignerBackend<'_> { + SignerBackend::Custom(Cow::Borrowed("custom")) + } +} diff --git a/desktop/src/dialogs/accounts.rs b/desktop/src/dialogs/accounts.rs index c780046..0b3639a 100644 --- a/desktop/src/dialogs/accounts.rs +++ b/desktop/src/dialogs/accounts.rs @@ -91,26 +91,18 @@ impl AccountSelector { fn login(&mut self, public_key: PublicKey, window: &mut Window, cx: &mut Context) { let nostr = NostrRegistry::global(cx); - let task = nostr.read(cx).get_secret(public_key, cx); // Mark the public key as being logged in self.set_logging_in(public_key, cx); - self.tasks.push(cx.spawn_in(window, async move |this, cx| { - match task.await { - Ok(signer) => { - nostr.update(cx, |this, cx| { - this.set_signer(signer, cx); - }); - } - Err(e) => { - this.update(cx, |this, cx| { - this.set_error(e.to_string(), cx); - })?; - } - }; - Ok(()) - })); + match nostr.read(cx).switch_account(public_key, cx) { + Ok(()) => { + // + } + Err(e) => { + self.set_error(e.to_string(), cx); + } + }; } fn remove(&mut self, public_key: PublicKey, cx: &mut Context) { diff --git a/desktop/src/dialogs/screening.rs b/desktop/src/dialogs/screening.rs index 3a13e7a..6d7bca7 100644 --- a/desktop/src/dialogs/screening.rs +++ b/desktop/src/dialogs/screening.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::time::Duration; -use anyhow::{Context as AnyhowContext, Error}; +use anyhow::Error; use common::TimestampExt; use gpui::prelude::FluentBuilder; use gpui::{ @@ -76,10 +76,10 @@ impl Screening { fn check_contact(&mut self, cx: &mut Context) { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); let public_key = self.public_key; let task: Task> = cx.background_spawn(async move { - let signer = client.signer().context("Signer not found")?; let signer_pubkey = signer.get_public_key().await?; // Check if user is in contact list @@ -103,10 +103,10 @@ impl Screening { fn check_wot(&mut self, cx: &mut Context) { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); let public_key = self.public_key; let task: Task, Error>> = cx.background_spawn(async move { - let signer = client.signer().context("Signer not found")?; let signer_pubkey = signer.get_public_key().await?; // Check mutual contacts @@ -222,12 +222,21 @@ impl Screening { fn report(&mut self, window: &mut Window, cx: &mut Context) { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); let public_key = self.public_key; let task: Task> = cx.background_spawn(async move { - let tag = Tag::public_key_report(public_key, Report::Impersonation); - let builder = EventBuilder::report(vec![tag], ""); - let event = client.sign_event_builder(builder).await?; + let signer = signer.get().await; + + let tag = Nip56Tag::PublicKey { + public_key, + report: Report::Impersonation, + } + .to_tag(); + + let event = EventBuilder::report(vec![tag], "") + .sign_async(&signer) + .await?; // Send the report to the public relays client.send_event(&event).to(BOOTSTRAP_RELAYS).await?; diff --git a/desktop/src/panels/contact_list.rs b/desktop/src/panels/contact_list.rs index 628d75d..8548b57 100644 --- a/desktop/src/panels/contact_list.rs +++ b/desktop/src/panels/contact_list.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use std::time::Duration; -use anyhow::{Context as AnyhowContext, Error}; +use anyhow::Error; use gpui::prelude::FluentBuilder; use gpui::{ AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle, Focusable, @@ -81,9 +81,9 @@ impl ContactListPanel { fn load(&mut self, window: &mut Window, cx: &mut Context) { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); let task: Task, Error>> = cx.background_spawn(async move { - let signer = client.signer().context("Signer not found")?; let public_key = signer.get_public_key().await?; let contact_list = client.database().contacts_public_keys(public_key).await?; @@ -156,6 +156,7 @@ impl ContactListPanel { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); // Get contacts let contacts: Vec = self @@ -168,9 +169,12 @@ impl ContactListPanel { self.set_updating(true, cx); let task: Task> = cx.background_spawn(async move { + let signer = signer.get().await; + // Construct contact list event builder - let builder = EventBuilder::contact_list(contacts); - let event = client.sign_event_builder(builder).await?; + let event = EventBuilder::contact_list(contacts) + .sign_async(&signer) + .await?; // Set contact list client.send_event(&event).to_nip65().await?; diff --git a/desktop/src/panels/messaging_relays.rs b/desktop/src/panels/messaging_relays.rs index 66fca40..df04cd0 100644 --- a/desktop/src/panels/messaging_relays.rs +++ b/desktop/src/panels/messaging_relays.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use std::time::Duration; -use anyhow::{Context as AnyhowContext, Error, anyhow}; +use anyhow::{Error, anyhow}; use gpui::prelude::FluentBuilder; use gpui::{ AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle, Focusable, @@ -82,9 +82,9 @@ impl MessagingRelayPanel { fn load(&mut self, window: &mut Window, cx: &mut Context) { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); let task: Task, Error>> = cx.background_spawn(async move { - let signer = client.signer().context("Signer not found")?; let public_key = signer.get_public_key().await?; let filter = Filter::new() @@ -93,7 +93,7 @@ impl MessagingRelayPanel { .limit(1); if let Some(event) = client.database().query(filter).await?.first_owned() { - Ok(nip17::extract_owned_relay_list(event).collect()) + Ok(nip17::extract_relay_list(&event).collect()) } else { Err(anyhow!("Not found.")) } @@ -170,21 +170,26 @@ impl MessagingRelayPanel { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); // Construct event tags let tags: Vec = self .relays .iter() - .map(|relay| Tag::relay(relay.clone())) + .map(|relay| Tag::custom("relay", vec![relay.to_string()])) .collect(); // Set updating state self.set_updating(true, cx); let task: Task> = cx.background_spawn(async move { + let signer = signer.get().await; + // Construct nip17 event builder - let builder = EventBuilder::new(Kind::InboxRelays, "").tags(tags); - let event = client.sign_event_builder(builder).await?; + let event = EventBuilder::new(Kind::InboxRelays, "") + .tags(tags) + .sign_async(&signer) + .await?; // Set messaging relays client.send_event(&event).to_nip65().await?; diff --git a/desktop/src/panels/profile.rs b/desktop/src/panels/profile.rs index b9b26ce..008ead2 100644 --- a/desktop/src/panels/profile.rs +++ b/desktop/src/panels/profile.rs @@ -207,12 +207,16 @@ impl ProfilePanel { fn publish(&self, metadata: &Metadata, cx: &App) -> Task> { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); let metadata = metadata.clone(); cx.background_spawn(async move { + let signer = signer.get().await; + // Build and sign the metadata event - let builder = EventBuilder::metadata(&metadata); - let event = client.sign_event_builder(builder).await?; + let event = EventBuilder::metadata(&metadata) + .sign_async(&signer) + .await?; // Send event to user's relays client.send_event(&event).await?; diff --git a/desktop/src/panels/relay_list.rs b/desktop/src/panels/relay_list.rs index 577eb20..6d6e457 100644 --- a/desktop/src/panels/relay_list.rs +++ b/desktop/src/panels/relay_list.rs @@ -1,7 +1,7 @@ use std::collections::HashSet; use std::time::Duration; -use anyhow::{Context as AnyhowContext, Error, anyhow}; +use anyhow::{Error, anyhow}; use gpui::prelude::FluentBuilder; use gpui::{ Action, AnyElement, App, AppContext, Context, Entity, EventEmitter, FocusHandle, Focusable, @@ -99,10 +99,10 @@ impl RelayListPanel { fn load(&mut self, window: &mut Window, cx: &mut Context) { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); let task: Task)>, Error>> = cx .background_spawn(async move { - let signer = client.signer().context("Signer not found")?; let public_key = signer.get_public_key().await?; let filter = Filter::new() @@ -111,7 +111,7 @@ impl RelayListPanel { .limit(1); if let Some(event) = client.database().query(filter).await?.first_owned() { - Ok(nip65::extract_owned_relay_list(event).collect()) + Ok(nip65::extract_relay_list(&event).collect()) } else { Err(anyhow!("Not found.")) } @@ -206,6 +206,7 @@ impl RelayListPanel { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); // Get all relays let relays = self.relays.clone(); @@ -214,8 +215,8 @@ impl RelayListPanel { self.set_updating(true, cx); let task: Task> = cx.background_spawn(async move { - let builder = EventBuilder::relay_list(relays); - let event = client.sign_event_builder(builder).await?; + let signer = signer.get().await; + let event = EventBuilder::relay_list(relays).sign_async(&signer).await?; // Set relay list for current user client.send_event(&event).await?; diff --git a/desktop/src/sidebar/mod.rs b/desktop/src/sidebar/mod.rs index a9d1b99..1327972 100644 --- a/desktop/src/sidebar/mod.rs +++ b/desktop/src/sidebar/mod.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use std::ops::Range; use std::time::Duration; -use anyhow::{Context as AnyhowContext, Error}; +use anyhow::Error; use chat::{ChatEvent, ChatRegistry, Room, RoomKind}; use common::{DebouncedDelay, TimestampExt, coop_cache}; use entry::RoomEntry; @@ -158,9 +158,9 @@ impl Sidebar { fn get_contact_list(&mut self, window: &mut Window, cx: &mut Context) { let nostr = NostrRegistry::global(cx); let client = nostr.read(cx).client(); + let signer = nostr.read(cx).signer(); let task: Task, Error>> = cx.background_spawn(async move { - let signer = client.signer().context("Signer not found")?; let public_key = signer.get_public_key().await?; let contacts = client.database().contacts_public_keys(public_key).await?;