diff --git a/Cargo.lock b/Cargo.lock index b132544c..b38c38e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -235,12 +235,56 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "anstream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + [[package]] name = "anstyle" version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" +[[package]] +name = "anstyle-parse" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" +dependencies = [ + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.2", +] + [[package]] name = "anyhow" version = "1.0.104" @@ -520,7 +564,7 @@ dependencies = [ "tokio-happy-eyeballs", "tokio-rustls", "tokio-socks", - "tokio-tungstenite", + "tokio-tungstenite 0.28.0", "url", "wasm-bindgen", "wasm-bindgen-futures", @@ -676,6 +720,21 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base58ck" +version = "0.1.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "365c0acd5b2e8dd0111a46c4faea83fb3cfb6e39a49a7c73a06e090db7b2eff0" +dependencies = [ + "bitcoin_hashes 0.14.101", +] + [[package]] name = "base62" version = "2.2.6" @@ -688,6 +747,12 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "base64" version = "0.22.1" @@ -706,6 +771,12 @@ version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" +[[package]] +name = "bech32" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" + [[package]] name = "bech32" version = "0.12.0" @@ -737,6 +808,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90dbd31c98227229239363921e60fcf5e558e43ec69094d46fc4996f08d1d5bc" dependencies = [ "bitcoin_hashes 0.14.101", + "rand 0.8.8", + "rand_core 0.6.4", "serde", "unicode-normalization", ] @@ -762,6 +835,24 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e4b40c7323adcfc0a41c4b88143ed58346ff65a288fc144329c5c45e05d70c6" +[[package]] +name = "bitcoin" +version = "0.32.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0ce8bd5baaa0d303a19915a6d93afed161f528654e42da2a7a97d05c59499a" +dependencies = [ + "base58ck", + "base64 0.21.7", + "bech32 0.11.1", + "bitcoin-io", + "bitcoin-units", + "bitcoin_hashes 0.14.101", + "hex-conservative 0.2.3", + "hex_lit", + "secp256k1 0.29.1", + "serde", +] + [[package]] name = "bitcoin-consensus-encoding" version = "1.3.0" @@ -794,6 +885,27 @@ dependencies = [ "bitcoin-consensus-encoding", ] +[[package]] +name = "bitcoin-payment-instructions" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f5b43b0e8338cd36ce7940bd6b8a007d54f1cbe25314ec3fbba566f870b085" +dependencies = [ + "bitcoin", + "lightning", + "lightning-invoice", +] + +[[package]] +name = "bitcoin-units" +version = "0.1.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cb95693f371d089a4b5b6fc41c6f3ea6e01ee8c15388335dfac8ea685173b51" +dependencies = [ + "bitcoin-consensus-encoding", + "serde", +] + [[package]] name = "bitcoin_hashes" version = "0.14.101" @@ -802,6 +914,7 @@ checksum = "bca4c7abb40c8817d77403c880988cfd484f23ab2365726afb2f798363e2c4a2" dependencies = [ "bitcoin-io", "hex-conservative 0.2.3", + "serde", ] [[package]] @@ -831,6 +944,22 @@ dependencies = [ "serde_core", ] +[[package]] +name = "bitreq" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2118ef89c7d94696800407a4b0e555da52d36a791f522c3b98d7cceff9b45f51" +dependencies = [ + "base64 0.22.1", + "rustls", + "rustls-webpki", + "serde", + "serde_json", + "tokio", + "tokio-rustls", + "webpki-roots 1.0.11", +] + [[package]] name = "bitstream-io" version = "4.10.0" @@ -1019,6 +1148,30 @@ dependencies = [ "wayland-client", ] +[[package]] +name = "cashu" +version = "0.18.0" +source = "git+https://github.com/cashubtc/cdk#578e719fbf683871a8480961627700f01f3ee7ee" +dependencies = [ + "bitcoin", + "cbor-diag", + "ciborium", + "lightning", + "lightning-invoice", + "serde", + "serde_bytes", + "serde_json", + "serde_with", + "thiserror 2.0.21", + "tracing", + "unicode-normalization", + "ur", + "url", + "uuid", + "web-time", + "zeroize", +] + [[package]] name = "castaway" version = "0.2.4" @@ -1055,6 +1208,25 @@ dependencies = [ "toml 0.8.23", ] +[[package]] +name = "cbor-diag" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc245b6ecd09b23901a4fbad1ad975701fd5061ceaef6afa93a2d70605a64429" +dependencies = [ + "bs58", + "chrono", + "data-encoding", + "half", + "nom 7.1.3", + "num-bigint", + "num-rational", + "num-traits", + "separator", + "url", + "uuid", +] + [[package]] name = "cc" version = "1.10.0" @@ -1067,6 +1239,146 @@ dependencies = [ "shlex 2.0.1", ] +[[package]] +name = "cdk" +version = "0.18.0" +source = "git+https://github.com/cashubtc/cdk#578e719fbf683871a8480961627700f01f3ee7ee" +dependencies = [ + "anyhow", + "arc-swap", + "async-trait", + "bitcoin", + "bitcoin-payment-instructions", + "cdk-common", + "cdk-http-client", + "cdk-signatory", + "futures", + "getrandom 0.4.3", + "gloo-timers", + "lightning", + "lightning-invoice", + "ring", + "rustls", + "serde", + "serde_json", + "thiserror 2.0.21", + "tokio", + "tokio-util", + "tracing", + "url", + "uuid", + "web-time", + "zeroize", +] + +[[package]] +name = "cdk-common" +version = "0.18.0" +source = "git+https://github.com/cashubtc/cdk#578e719fbf683871a8480961627700f01f3ee7ee" +dependencies = [ + "anyhow", + "async-trait", + "bitcoin", + "cashu", + "cdk-http-client", + "futures", + "getrandom 0.4.3", + "gloo-timers", + "jsonwebtoken", + "lightning", + "lightning-invoice", + "parking_lot", + "paste", + "serde", + "serde_json", + "thiserror 2.0.21", + "tokio", + "tonic", + "tracing", + "url", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-time", +] + +[[package]] +name = "cdk-http-client" +version = "0.18.0" +source = "git+https://github.com/cashubtc/cdk#578e719fbf683871a8480961627700f01f3ee7ee" +dependencies = [ + "async-trait", + "bitreq", + "cashu", + "futures", + "futures-channel", + "getrandom 0.4.3", + "js-sys", + "regex", + "rustls", + "serde", + "serde_json", + "serde_urlencoded", + "thiserror 2.0.21", + "tokio-tungstenite 0.26.2", + "tracing", + "url", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "cdk-nostr" +version = "0.18.0" +source = "git+https://github.com/cashubtc/cdk#578e719fbf683871a8480961627700f01f3ee7ee" +dependencies = [ + "nostr", + "nostr-sdk", + "thiserror 2.0.21", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "cdk-redb" +version = "0.18.0" +source = "git+https://github.com/cashubtc/cdk#578e719fbf683871a8480961627700f01f3ee7ee" +dependencies = [ + "async-trait", + "cdk-common", + "redb", + "serde", + "serde_json", + "thiserror 2.0.21", + "tracing", + "uuid", +] + +[[package]] +name = "cdk-signatory" +version = "0.18.0" +source = "git+https://github.com/cashubtc/cdk#578e719fbf683871a8480961627700f01f3ee7ee" +dependencies = [ + "anyhow", + "arc-swap", + "async-trait", + "bip39", + "bitcoin", + "cdk-common", + "clap", + "getrandom 0.4.3", + "home", + "rustls", + "thiserror 2.0.21", + "tokio", + "tokio-stream", + "tracing", + "tracing-subscriber", +] + [[package]] name = "cesu8" version = "1.1.0" @@ -1188,6 +1500,33 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + [[package]] name = "cipher" version = "0.4.4" @@ -1221,6 +1560,46 @@ dependencies = [ "libloading", ] +[[package]] +name = "clap" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa8876b300ab35ba921adea3dfd70157a46249b33f95c9084ae5709785478946" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0797fb7aeb1406c84efac526901f7ec3ead2124f946b494e72879d4b54704d" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9c751b79415d4e559e3d1fcf128e09e720eb673a06d26cf6f392d37d75b66e0" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 3.0.9", +] + +[[package]] +name = "clap_lex" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c133bc6a41be0d194c306b5506d15e6feeea7b1d6604bd3f8310dfb2ca96486" + [[package]] name = "cmake" version = "0.1.58" @@ -1283,6 +1662,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "colorchoice" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" + [[package]] name = "combine" version = "4.6.9" @@ -1360,6 +1745,12 @@ dependencies = [ "web-sys", ] +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "const-oid" version = "0.10.2" @@ -1445,6 +1836,7 @@ dependencies = [ "native-theme-gpui", "nip29", "nip4e", + "nip60", "nostr-sdk", "person", "settings", @@ -1685,6 +2077,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eb8a2a1cd12ab0d987a5d5e825195d372001a4094a0376319d5a0ad71c1ba0d" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "217698eaf96b4a3f0bc4f3662aaa55bdf913cd54d7204591faa790070c6d0853" + [[package]] name = "crc32fast" version = "1.5.3" @@ -1734,6 +2141,18 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.7" @@ -1782,6 +2201,33 @@ dependencies = [ "cmov", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "daachorse" version = "3.0.3" @@ -1938,13 +2384,24 @@ dependencies = [ "syn 3.0.9", ] +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid 0.9.6", + "pem-rfc7468 0.7.0", + "zeroize", +] + [[package]] name = "der" version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a996a108feb8b427a6e12fcf6af4aa83409b79d72c15337d7741368131ee004" dependencies = [ - "pem-rfc7468", + "pem-rfc7468 1.0.0", "zeroize", ] @@ -2018,6 +2475,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", + "const-oid 0.9.6", "crypto-common 0.1.7", "subtle", ] @@ -2029,7 +2487,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer 0.12.1", - "const-oid", + "const-oid 0.10.2", "crypto-common 0.2.2", "ctutils", ] @@ -2113,6 +2571,15 @@ dependencies = [ "libloading", ] +[[package]] +name = "dnssec-prover" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9468f1a08c50bd1e5ad91b151e11ce8e806f8fa1c1eb9b07f66c7011de45a2e" +dependencies = [ + "bitcoin_hashes 0.14.101", +] + [[package]] name = "document-features" version = "0.2.12" @@ -2182,18 +2649,77 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.10", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + [[package]] name = "ed25519-compact" version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1454db4f2edb7f0e8fe0c5b375b0c978fc63244cc9f010d160e417eb10139aa8" +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2 0.10.9", + "subtle", + "zeroize", +] + [[package]] name = "either" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e9c71c2167ca323c882b99918929403426e2373ea17242ff5653e0d5e1058be" +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468 0.7.0", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "embed-resource" version = "3.0.12" @@ -2458,6 +2984,22 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "filedescriptor" version = "0.8.3" @@ -2795,6 +3337,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -3683,6 +4226,17 @@ dependencies = [ "smallvec", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "h2" version = "0.4.20" @@ -3742,6 +4296,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" + [[package]] name = "hashbrown" version = "0.14.5" @@ -3864,6 +4424,12 @@ dependencies = [ "arrayvec", ] +[[package]] +name = "hex_lit" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3011d1213f159867b13cfd6ac92d2cd5f1345762c63be3554e84092d85a50bbd" + [[package]] name = "hkdf" version = "0.12.4" @@ -3897,6 +4463,15 @@ version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad320b3b96fb2a455a0726d16efe0a5afdbd34b71dea5bc53b05ea057714d4e" +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "hound" version = "3.5.1" @@ -4398,6 +4973,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "is_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + [[package]] name = "itertools" version = "0.11.0" @@ -4580,6 +5161,30 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "jsonwebtoken" +version = "10.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eba32bfb4ffdeaca3e34431072faf01745c9b26d25504aa7a6cf5684334fc4fc" +dependencies = [ + "base64 0.22.1", + "ed25519-dalek", + "getrandom 0.2.17", + "hmac 0.12.1", + "js-sys", + "p256", + "p384", + "pem", + "rand 0.8.8", + "rsa", + "serde", + "serde_json", + "sha2 0.10.9", + "signature", + "simple_asn1", + "zeroize", +] + [[package]] name = "khronos-egl" version = "6.0.0" @@ -4645,6 +5250,9 @@ name = "lazy_static" version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20870f649af7073d53e38067b2a84312175d56ea15217e1b15bc83506ec50afb" +dependencies = [ + "spin 0.9.9", +] [[package]] name = "lebe" @@ -4704,6 +5312,55 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "lightning" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982ffb82e8362ea95e03a5de8a6004bceb7a577fc1f07d5b02cfc3fc7c930a90" +dependencies = [ + "bech32 0.11.1", + "bitcoin", + "dnssec-prover", + "hashbrown 0.13.2", + "libm", + "lightning-invoice", + "lightning-macros", + "lightning-types", + "possiblyrandom", +] + +[[package]] +name = "lightning-invoice" +version = "0.34.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d83bd798e04ab9eecc8bbef1fa17d3808859bcdc0406bd16c55d51c8834444" +dependencies = [ + "bech32 0.11.1", + "bitcoin", + "lightning-types", + "serde", +] + +[[package]] +name = "lightning-macros" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c717494cdc2c8bb85bee7113031248f5f6c64f8802b33c1c9e2d98e594aa71" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "lightning-types" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77c676d4a34cceb2ae3756916e446b4d17f9430a24107e099981f0f9aec77e6" +dependencies = [ + "bitcoin", +] + [[package]] name = "linebender_resource_handle" version = "0.1.1" @@ -5053,6 +5710,15 @@ dependencies = [ "xml5ever", ] +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + [[package]] name = "matrixmultiply" version = "0.3.11" @@ -5138,6 +5804,12 @@ dependencies = [ "unicase", ] +[[package]] +name = "minicbor" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7244eafd1e09e7c4e33043881997aa6ab6dffff3ed2cee3395a278980481d6e" + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -5455,6 +6127,18 @@ dependencies = [ "ui", ] +[[package]] +name = "nip60" +version = "2.0.0-alpha3" +dependencies = [ + "cdk", + "cdk-nostr", + "cdk-redb", + "gpui-pre", + "nostr", + "nostr-sdk", +] + [[package]] name = "no_std_io2" version = "0.9.4" @@ -5511,7 +6195,7 @@ source = "git+https://github.com/rust-nostr/nostr#37f139dfbb0a5c5f879cb052df7376 dependencies = [ "aes", "base64 0.22.1", - "bech32", + "bech32 0.12.0", "bip39", "bitcoin_hashes 1.2.0", "cbc", @@ -5521,7 +6205,7 @@ dependencies = [ "opaquerr 0.2.0", "rand 0.10.3", "scrypt", - "secp256k1", + "secp256k1 0.30.0", "serde", "serde_json", "unicode-normalization", @@ -5744,6 +6428,22 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint-dig" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +dependencies = [ + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.8", + "smallvec", + "zeroize", +] + [[package]] name = "num-bigint-dig" version = "0.9.1" @@ -6282,6 +6982,12 @@ version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + [[package]] name = "onig" version = "6.5.3" @@ -6327,7 +7033,7 @@ dependencies = [ "hmac 0.12.1", "md-5", "num", - "num-bigint-dig", + "num-bigint-dig 0.9.1", "pbkdf2 0.12.2", "serde", "serde_bytes", @@ -6468,6 +7174,30 @@ dependencies = [ "serde", ] +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2 0.10.9", +] + +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2 0.10.9", +] + [[package]] name = "page_size" version = "0.6.0" @@ -6580,6 +7310,25 @@ dependencies = [ "hmac 0.13.0", ] +[[package]] +name = "pem" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" +dependencies = [ + "base64 0.22.1", + "serde_core", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "pem-rfc7468" version = "1.0.0" @@ -6749,6 +7498,27 @@ dependencies = [ "futures-io", ] +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der 0.7.10", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.10", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.34" @@ -6854,6 +7624,15 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "possiblyrandom" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c564dbf654befd49035528299f1208a40508f6e07efb11c163444e304e4484f" +dependencies = [ + "getrandom 0.2.17", +] + [[package]] name = "potential_utf" version = "0.1.6" @@ -6899,6 +7678,15 @@ dependencies = [ "num-integer", ] +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro-crate" version = "3.5.0" @@ -7151,6 +7939,15 @@ dependencies = [ "rand_core 0.10.1", ] +[[package]] +name = "rand_xoshiro" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "662effc7698e08ea324d3acccf8d9d7f7bf79b9785e270a174ea36e56900c91d" +dependencies = [ + "rand_core 0.10.1", +] + [[package]] name = "range-alloc" version = "0.1.5" @@ -7314,6 +8111,15 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03251193000f4bd3b042892be858ee50e8b3719f2b08e5833ac4353724632430" +[[package]] +name = "redb" +version = "3.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ba239c1c1693315d3cc0e601db3b3965543afbf48c41730fdca2f069f510f4a" +dependencies = [ + "libc", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -7474,6 +8280,16 @@ dependencies = [ "zune-jpeg 0.5.15", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle", +] + [[package]] name = "rgb" version = "0.8.53" @@ -7521,6 +8337,26 @@ dependencies = [ "memchr", ] +[[package]] +name = "rsa" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" +dependencies = [ + "const-oid 0.9.6", + "digest 0.10.7", + "num-bigint-dig 0.8.6", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + [[package]] name = "rsqlite-vfs" version = "0.1.1" @@ -7941,6 +8777,32 @@ dependencies = [ "syn 3.0.9", ] +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der 0.7.10", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" +dependencies = [ + "bitcoin_hashes 0.14.101", + "rand 0.8.8", + "secp256k1-sys", + "serde", +] + [[package]] name = "secp256k1" version = "0.30.0" @@ -8000,6 +8862,12 @@ dependencies = [ "serde_core", ] +[[package]] +name = "separator" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f97841a747eef040fcd2e7b3b9a220a7205926e60488e673d9e4926d27772ce5" + [[package]] name = "serde" version = "1.0.229" @@ -8253,6 +9121,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + [[package]] name = "simd-adler32" version = "0.3.10" @@ -8294,6 +9172,18 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "simple_asn1" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d585997b0ac10be3c5ee635f1bab02d512760d14b7c468801ac8a01d9ae5f1d" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror 2.0.21", + "time", +] + [[package]] name = "simplecss" version = "0.2.2" @@ -8436,6 +9326,16 @@ dependencies = [ "bitflags 2.13.2", ] +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.10", +] + [[package]] name = "spm_precompiled" version = "0.1.4" @@ -9005,7 +9905,9 @@ dependencies = [ "bytes", "libc", "mio", + "parking_lot", "pin-project-lite", + "signal-hook-registry", "socket2", "tokio-macros", "windows-sys 0.61.2", @@ -9065,6 +9967,22 @@ dependencies = [ "tokio-util", ] +[[package]] +name = "tokio-tungstenite" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" +dependencies = [ + "futures-util", + "log", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tungstenite 0.26.2", +] + [[package]] name = "tokio-tungstenite" version = "0.28.0" @@ -9077,7 +9995,7 @@ dependencies = [ "rustls-pki-types", "tokio", "tokio-rustls", - "tungstenite", + "tungstenite 0.28.0", "webpki-roots 0.26.11", ] @@ -9187,6 +10105,27 @@ version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06bdbd8cfc056b8d2e2e85f29b56a3bdbecb527cef81eb39e3e7b98af4652770" +[[package]] +name = "tonic" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2cdfc673aabd30fe8fee92e65837b644c37c5d47f0f97ae6d5e0f1237d15e1b" +dependencies = [ + "base64 0.22.1", + "bytes", + "http", + "http-body", + "http-body-util", + "percent-encoding", + "pin-project", + "sync_wrapper", + "tokio-stream", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower" version = "0.5.3" @@ -9282,10 +10221,14 @@ version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ + "matchers", "nu-ansi-term", + "once_cell", + "regex-automata", "sharded-slab", "smallvec", "thread_local", + "tracing", "tracing-core", "tracing-log", ] @@ -9364,6 +10307,25 @@ dependencies = [ "zbus", ] +[[package]] +name = "tungstenite" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" +dependencies = [ + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "rand 0.9.5", + "rustls", + "rustls-pki-types", + "sha1", + "thiserror 2.0.21", + "utf-8", +] + [[package]] name = "tungstenite" version = "0.28.0" @@ -9545,6 +10507,18 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "ur" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28bccbac381852c37efd0217ce8c96742e5cf22f6dbb2a4f0f51418c7f3ab980" +dependencies = [ + "bitcoin_hashes 1.2.0", + "crc", + "minicbor", + "rand_xoshiro", +] + [[package]] name = "ureq" version = "3.5.0" @@ -9553,7 +10527,7 @@ checksum = "cde93ff05758a36a851a398a772b0b79a82fbe3c186a46f2696baaeaf84c966b" dependencies = [ "base64 0.23.1", "cookie_store", - "der", + "der 0.8.3", "log", "native-tls", "percent-encoding", @@ -9665,6 +10639,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.29.0" diff --git a/Cargo.toml b/Cargo.toml index 48581112..b1bf19bd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ nostr-connect = { git = "https://github.com/rust-nostr/nostr" } nostr-browser-signer = { git = "https://github.com/rust-nostr/nostr" } nostr-sdk = { git = "https://github.com/rust-nostr/nostr" } nostr-sqlite = { git = "https://github.com/rust-nostr/nostr" } -nostr = { git = "https://github.com/rust-nostr/nostr", features = [ "nip59", "nip49", "nip44", "nip98" ] } +nostr = { git = "https://github.com/rust-nostr/nostr", features = [ "nip59", "nip49", "nip44", "nip60", "nip98" ] } # Crypto (NIP-17 encrypted file messages) aes-gcm = "0.10" @@ -48,6 +48,14 @@ hmac = "0.12" # Pinned to the instance `nostr-sdk` already builds, so NIP-44 nonces share it rand = { version = "0.10", default-features = false, features = [ "std", "sys_rng", "thread_rng" ] } +# Cashu (NIP-60). From git: the published 0.18.x line targets nostr 0.44 and +# cannot unify with the git rust-nostr used here, while main targets 0.45.x +# (redirected to this repo by the [patch.crates-io] section below). redb +# storage: pure Rust, avoids the libsqlite3-sys links clash with nostr-sqlite. +cdk = { git = "https://github.com/cashubtc/cdk", default-features = false, features = [ "wallet" ] } +cdk-redb = { git = "https://github.com/cashubtc/cdk", default-features = false, features = [ "wallet" ] } +cdk-nostr = { git = "https://github.com/cashubtc/cdk", default-features = false } + # Others anyhow = "1.0.44" tts = { git = "https://github.com/ndarilek/tts-rs" } @@ -66,6 +74,12 @@ webbrowser = "1.0.4" tracing-subscriber = { version = "0.3.18", features = ["fmt"] } instant = "0.1" +# cdk's registry nostr/nostr-sdk requirements are redirected onto the same +# git repo coop already uses, keeping a single copy of each in the graph. +[patch.crates-io] +nostr = { git = "https://github.com/rust-nostr/nostr" } +nostr-sdk = { git = "https://github.com/rust-nostr/nostr" } + [profile.release] strip = true opt-level = "z" diff --git a/crates/nip60/Cargo.toml b/crates/nip60/Cargo.toml new file mode 100644 index 00000000..13002034 --- /dev/null +++ b/crates/nip60/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "nip60" +version.workspace = true +edition.workspace = true +publish.workspace = true + +[dependencies] +gpui.workspace = true +nostr.workspace = true +nostr-sdk.workspace = true + +cdk.workspace = true +cdk-redb.workspace = true +cdk-nostr.workspace = true diff --git a/crates/nip60/src/lib.rs b/crates/nip60/src/lib.rs new file mode 100644 index 00000000..8c0aad9e --- /dev/null +++ b/crates/nip60/src/lib.rs @@ -0,0 +1,49 @@ +#![cfg(not(target_arch = "wasm32"))] + +use gpui::App; +use nostr::prelude::*; + +/// Initialize the wallet registry. +pub fn init(_cx: &mut App) {} + +/// Compile-only phase 0 spike: proves the `nostr::nips::nip60` types, kinds, +/// and the cdk crates resolve against the workspace's git nostr. Replaced by +/// the real implementation. +#[allow(dead_code)] +fn spike() { + let _kinds = ( + Kind::CashuWallet, + Kind::CashuWalletUnspentProof, + Kind::CashuWalletSpendingHistory, + Kind::CashuWalletQuote, + ); + + let _history = + nostr::nips::nip60::SpendingHistory::new(nostr::nips::nip60::TransactionDirection::In, 1); + let _builder = cdk::wallet::WalletBuilder::new(); + let _store: Option = None; + let _inbox: Option = None; + + if let Ok(mint) = nostr::types::Url::parse("https://mint.example.com") { + let proof = nostr::nips::nip60::CashuProof { + id: String::new(), + amount: 1, + secret: String::new(), + c: String::new(), + }; + let _wallet_event = nostr::nips::nip60::WalletEvent::new("privkey", vec![mint.clone()]); + let _token_event = + nostr::nips::nip60::TokenEvent::new(mint, vec![proof]).destroyed("id".to_string()); + } +} + +/// Only compiles when `nostr` and `cdk_nostr` resolve to the same crate. +#[allow(dead_code)] +fn spike_unified(key: nostr::key::SecretKey) -> cdk_nostr::nostr::key::SecretKey { + key +} + +#[allow(dead_code)] +fn spike_sdk_unified(client: nostr_sdk::client::Client) -> cdk_nostr::nostr_sdk::client::Client { + client +} diff --git a/desktop/Cargo.toml b/desktop/Cargo.toml index e2bd9ebf..6c710c20 100644 --- a/desktop/Cargo.toml +++ b/desktop/Cargo.toml @@ -37,6 +37,7 @@ workspace = { path = "../crates/workspace" } ui = { path = "../crates/ui" } state = { path = "../crates/state" } nip4e = { path = "../crates/nip4e" } +nip60 = { path = "../crates/nip60" } chat = { path = "../crates/chat" } chat_ui = { path = "../crates/chat_ui" } nip29 = { path = "../crates/nip29" } diff --git a/desktop/src/main.rs b/desktop/src/main.rs index f1e34dcd..5a2e3665 100644 --- a/desktop/src/main.rs +++ b/desktop/src/main.rs @@ -91,6 +91,11 @@ fn main() { // NIP-4e: https://github.com/nostr-protocol/nips/blob/per-device-keys/4e.md nip4e::init(cx); + // Initialize cashu wallet registry + // + // NIP-60: https://github.com/nostr-protocol/nips/blob/master/60.md + nip60::init(cx); + // Initialize app registry chat::init(cx); diff --git a/docs/nip60.md b/docs/nip60.md index a6808eab..b4cdcbf0 100644 --- a/docs/nip60.md +++ b/docs/nip60.md @@ -1,7 +1,7 @@ # NIP-60: cashu wallet — implementation plan Spec: https://github.com/nostr-protocol/nips/blob/master/60.md -CDK: https://github.com/cashubtc/cdk (crates `cdk`, `cdk-sqlite`, `cdk-nostr` 0.18.x) +CDK: https://github.com/cashubtc/cdk (crates `cdk`, `cdk-redb`, `cdk-nostr`, from git main) NIP-60 stores a user's cashu wallet state on relays: the wallet config (kind `17375`), its unspent proofs (kind `7375`), and an optional spending @@ -50,7 +50,8 @@ Follows the existing crate patterns exactly; no new architecture. (runtime is already initialized by `state::init`). The `cdk-nostr` inbox listener also runs on that runtime. - Signer-agnostic encryption: the signer may be a bunker/extension, so we - never use `nostr::nip60::*::prepare` (they need an owned `SecretKey`). + never use `nostr::nips::nip60` prepare helpers (they need an owned + `SecretKey`). We build payloads as plain JSON, encrypt with `signer.nip44_encrypt(self_pubkey, json)` and sign with `EventBuilder::new(kind, content).finalize_async(signer)` — the same @@ -72,31 +73,41 @@ Follows the existing crate patterns exactly; no new architecture. ## Dependencies -Workspace `Cargo.toml`: +Workspace `Cargo.toml` (final state after the phase 0 spike): ```toml nostr = { git = "https://github.com/rust-nostr/nostr", features = [ "nip59", "nip49", "nip44", "nip60", "nip98" ] } +# Cashu (NIP-60). From git: the published 0.18.x line targets nostr 0.44 and +# cannot unify with the git rust-nostr used here, while main targets 0.45.x +cdk = { git = "https://github.com/cashubtc/cdk", default-features = false, features = [ "wallet" ] } +cdk-redb = { git = "https://github.com/cashubtc/cdk", default-features = false, features = [ "wallet" ] } +cdk-nostr = { git = "https://github.com/cashubtc/cdk", default-features = false } + [patch.crates-io] -# cdk publishes against crates.io nostr 0.45.x; coop uses the git source. -# The patch unifies both on one copy of the crate so types cross crate -# boundaries (cdk-nostr inbox events, keys) without conversion. nostr = { git = "https://github.com/rust-nostr/nostr" } nostr-sdk = { git = "https://github.com/rust-nostr/nostr" } ``` -`crates/nip60/Cargo.toml` (all under `cfg(not(wasm32))`): +Spike findings (all resolved and verified with `cargo check`): -```toml -cdk = { version = "0.18", default-features = false, features = ["wallet"] } -cdk-sqlite = { version = "0.18", default-features = false, features = ["wallet"] } -cdk-nostr = { version = "0.18", default-features = false } # inbox, for NIP-61 -``` - -Version-unification is the one risky step; Phase 0 is a spike that proves -`cdk 0.18.x` + git rust-nostr build together. Fallback if the patch fights -back: convert only at the cdk-nostr inbox boundary (hex/serde) and skip the -patch for `nostr-sdk`. +- The cdk family hard-pins `cdk-common` with `=` per release, so all crates + must come from one release train. crates.io 0.18.3 pins nostr 0.44 and + cannot coexist with coop's git nostr 0.45.x; the git main line pins + nostr ^0.45.3, which the `[patch.crates-io]` block redirects onto the + same git rust-nostr checkout. The lockfile ends with exactly one `nostr` + and one `nostr-sdk`, proven by compile-time type-identity checks between + `nostr` and `cdk_nostr::nostr`. +- Storage is `cdk-redb` (`WalletRedbDatabase::new(&Path)`, pure Rust), not + `cdk-sqlite`: published cdk-sqlite pins rusqlite ^0.31, whose + `libsqlite3-sys` clashes at the `links` level with the `nostr-sqlite` + wasm dependency of the `state` crate. +- rust-nostr 0.45.x has no root re-exports: the module is + `nostr::nips::nip60`, and cdk-nostr re-exports the SDK as + `cdk_nostr::nostr` / `cdk_nostr::nostr_sdk`. +- The `nip60` crate exists (`crates/nip60`) with a compile-only spike in + `lib.rs` and a no-op `init(cx)` wired into `desktop/src/main.rs`; both + are replaced in phase 1. ## Design @@ -116,7 +127,7 @@ patch for `nostr-sdk`. ### Local state -- cdk sqlite store at `config_dir().join("cashu")` (one `WalletDatabase` +- cdk redb store at `config_dir().join("cashu")` (one `WalletDatabase` shared by all mint wallets). - `WalletRegistry` holds: parsed `17375` (`WalletEvent` + event id), the active `7375` events per mint (event id + `TokenEvent`), cdk `Wallet` @@ -173,13 +184,14 @@ the UI crate when Phase 3 lands). ## Phases -### Phase 0 — dependency spike (small, throwaway) +### Phase 0 — dependency spike (done) -1. Enable `nip60` on the `nostr` workspace dep; confirm - `nostr::nip60` types and the four kinds compile. -2. Add the `[patch.crates-io]` block and a scratch dependency on - `cdk`/`cdk-sqlite`/`cdk-nostr`; `cargo check` desktop. Resolve the - nostr unification here before writing any code. +Outcome recorded in the Dependencies section: cdk family on git main, +`[patch.crates-io]` unification, cdk-redb storage, `nip60` crate skeleton +wired into desktop. `cargo check -p nip60` and the full desktop check pass. + +The remaining spike code in `crates/nip60/src/lib.rs` is deleted in +phase 1. ### Phase 1 — bootstrap + load + balance @@ -228,9 +240,13 @@ the UI crate when Phase 3 lands). - Concurrent spends from two devices double-spend; recovery is the spec's Appendix-1 validation (check proofs at the mint, roll over survivors) — implemented as reconciliation on sync, not real-time locking. -- Web target gets no wallet in v1: `cdk-sqlite` (rusqlite bundled) does - not build on wasm32; the crate compiles to nothing there (auto_update - pattern). A wasm store would need a cdk `WalletDatabase` over - IndexedDB — explicitly out of scope. +- Tracking cdk via git main is a moving target; the lockfile pins a rev + and must be bumped deliberately (same policy as the rust-nostr git dep). + Watch for the next cdk release line built against nostr 0.45.x — moving + back to crates.io then removes the moving-target concern. +- Web target gets no wallet in v1: cdk store backends (redb, sqlite) need + a real filesystem and do not build on wasm32; the crate compiles to + nothing there (auto_update pattern). A wasm store would need a cdk + `WalletDatabase` over IndexedDB — explicitly out of scope. - `7374` quote events are skipped (local cdk state per the spec); pending quotes are not visible to other devices until claimed.