From 3f8cfbbf6fcda929de2e5d6ea783f34d97f56989 Mon Sep 17 00:00:00 2001 From: "kody.low" Date: Tue, 19 Mar 2024 17:27:03 -0700 Subject: [PATCH] feat: fedimint 0.3 --- Cargo.lock | 728 +++++++++++------- fedimint-clientd/Cargo.toml | 22 +- fedimint-clientd/src/main.rs | 9 +- .../src/router/handlers/cashu/melt/method.rs | 6 +- .../src/router/handlers/cashu/mint/method.rs | 6 +- .../router/handlers/fedimint/admin/backup.rs | 4 +- .../fedimint/admin/discover_version.rs | 28 +- .../router/handlers/fedimint/admin/join.rs | 5 +- .../fedimint/admin/list_operations.rs | 4 +- .../src/router/handlers/fedimint/admin/mod.rs | 4 +- .../router/handlers/fedimint/admin/module.rs | 4 +- .../router/handlers/fedimint/admin/restore.rs | 4 +- .../handlers/fedimint/ln/await_invoice.rs | 4 +- .../router/handlers/fedimint/ln/await_pay.rs | 7 +- .../router/handlers/fedimint/ln/invoice.rs | 37 +- .../handlers/fedimint/ln/list_gateways.rs | 15 +- .../src/router/handlers/fedimint/ln/mod.rs | 9 +- .../src/router/handlers/fedimint/ln/pay.rs | 26 +- .../handlers/fedimint/ln/switch_gateway.rs | 51 -- .../router/handlers/fedimint/mint/reissue.rs | 7 +- .../router/handlers/fedimint/mint/spend.rs | 52 +- .../router/handlers/fedimint/mint/validate.rs | 7 +- .../handlers/fedimint/wallet/await_deposit.rs | 4 +- .../fedimint/wallet/deposit_address.rs | 4 +- .../handlers/fedimint/wallet/withdraw.rs | 9 +- fedimint-clientd/src/router/ws.rs | 6 +- fedimint-clientd/src/state.rs | 11 +- multimint/Cargo.toml | 12 +- multimint/src/client.rs | 69 +- multimint/src/lib.rs | 126 +-- multimint/src/types.rs | 3 +- 31 files changed, 763 insertions(+), 520 deletions(-) delete mode 100644 fedimint-clientd/src/router/handlers/fedimint/ln/switch_gateway.rs diff --git a/Cargo.lock b/Cargo.lock index dd8ddb0..ee54b89 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -34,6 +34,18 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217" +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.2" @@ -43,6 +55,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -108,29 +126,29 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" [[package]] name = "aquamarine" -version = "0.3.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df752953c49ce90719c7bf1fc587bc8227aed04732ea0c0f85e5397d7fdbd1a1" +checksum = "21cc1548309245035eb18aa7f0967da6bc65587005170c56e6ef2788a4cf3f4e" dependencies = [ "include_dir", "itertools 0.10.5", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.53", ] [[package]] name = "argon2" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ba4cac0a46bc1d2912652a751c47f2a9f3a7fe89bcae2275d418f5270402f9" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" dependencies = [ "base64ct", "blake2", @@ -146,11 +164,13 @@ checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "async-lock" -version = "2.8.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" dependencies = [ "event-listener", + "event-listener-strategy", + "pin-project-lite", ] [[package]] @@ -161,7 +181,7 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.53", ] [[package]] @@ -183,18 +203,18 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.53", ] [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.53", ] [[package]] @@ -204,7 +224,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a349201d80b4aa18d17a34a182bdd7f8ddf845e9e57d2ea130a12e10ef1e3a47" dependencies = [ "futures-util", - "gloo-timers", + "gloo-timers 0.2.6", "tokio", "wasm-bindgen-futures", ] @@ -280,7 +300,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.53", ] [[package]] @@ -325,15 +345,15 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.20.0" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "base64" -version = "0.21.5" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" [[package]] name = "base64-compat" @@ -376,23 +396,22 @@ dependencies = [ [[package]] name = "bindgen" -version = "0.65.1" +version = "0.69.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.1", "cexpr", "clang-sys", + "itertools 0.12.1", "lazy_static", "lazycell", - "peeking_take_while", - "prettyplease", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", - "syn 2.0.39", + "syn 2.0.53", ] [[package]] @@ -423,6 +442,12 @@ dependencies = [ "serde", ] +[[package]] +name = "bitcoin-internals" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" + [[package]] name = "bitcoin-private" version = "0.1.0" @@ -449,6 +474,16 @@ dependencies = [ "serde", ] +[[package]] +name = "bitcoin_hashes" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" +dependencies = [ + "bitcoin-internals", + "hex-conservative", +] + [[package]] name = "bitcoincore-rpc" version = "0.16.0" @@ -485,6 +520,12 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +[[package]] +name = "bitmaps" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d084b0137aaa901caf9f1e8b21daa6aa24d41cd806e111335541eff9683bd6" + [[package]] name = "bitvec" version = "1.0.1" @@ -682,7 +723,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.53", ] [[package]] @@ -697,6 +738,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "concurrent-queue" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -724,9 +774,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -762,6 +812,41 @@ dependencies = [ "typenum", ] +[[package]] +name = "darling" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.53", +] + +[[package]] +name = "darling_macro" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.53", +] + [[package]] name = "data-encoding" version = "2.5.0" @@ -835,9 +920,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "erased-serde" -version = "0.3.31" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c138974f9d5e7fe373eb04df7cae98833802ae4b11c24ac7039a21d5af4b26c" +checksum = "2b73807008a3c7f171cc40312f37d95ef0396e048b5848d775f54b1a4dd4a0d3" dependencies = [ "serde", ] @@ -866,9 +951,24 @@ dependencies = [ [[package]] name = "event-listener" -version = "2.5.3" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener", + "pin-project-lite", +] [[package]] name = "fastrand" @@ -884,22 +984,20 @@ checksum = "8d79878f18e518d77cfb3126939d0e63a62cad845d51a3266f4ac866f2efe57f" [[package]] name = "fedimint-aead" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6258d6dbd7b7f5dc1d62f26e64d47692c495d24c17c7b113b01e0a40ef5d6235" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "anyhow", "argon2", "hex", "rand", - "ring 0.17.6", + "ring 0.17.8", ] [[package]] name = "fedimint-bitcoind" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a746535346df82a3c6e8646364dec07112fe64bb7c2491bd5c3b0830c082e16" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "anyhow", "async-trait", @@ -912,24 +1010,23 @@ dependencies = [ "lazy_static", "rand", "serde", + "serde_json", "tracing", "url", ] [[package]] name = "fedimint-build" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48daee360af91937bf9f6c35e6da164d8574eb934d14b47f92668223b74cf995" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "serde_json", ] [[package]] name = "fedimint-client" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0e9c9046e3de54424108deefbd3501a92a48d2bc22f1af3d05242f29f5b7c31" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "anyhow", "aquamarine", @@ -943,9 +1040,9 @@ dependencies = [ "fedimint-derive-secret", "fedimint-logging", "futures", - "itertools 0.10.5", + "itertools 0.12.1", "rand", - "ring 0.17.6", + "ring 0.17.8", "secp256k1-zkp", "serde", "serde_json", @@ -953,6 +1050,7 @@ dependencies = [ "strum_macros", "thiserror", "tokio", + "tokio-stream", "tracing", ] @@ -966,7 +1064,7 @@ dependencies = [ "axum-macros", "axum-otel-metrics", "bitcoin 0.29.2", - "bitcoin_hashes 0.11.0", + "bitcoin_hashes 0.13.0", "chrono", "clap", "dotenv", @@ -978,11 +1076,11 @@ dependencies = [ "fedimint-rocksdb", "fedimint-wallet-client", "futures-util", - "itertools 0.12.0", + "itertools 0.12.1", "lazy_static", "lightning-invoice", "lnurl-rs", - "multimint 0.1.11", + "multimint", "reqwest", "serde", "serde_json", @@ -996,9 +1094,8 @@ dependencies = [ [[package]] name = "fedimint-core" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1397d89ac6951d49920001fd14b280b33a78de380e0d0db442021b00ca366e6" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "anyhow", "async-lock", @@ -1018,9 +1115,10 @@ dependencies = [ "fedimint-threshold-crypto", "futures", "getrandom", - "gloo-timers", + "gloo-timers 0.3.0", "hex", - "itertools 0.10.5", + "imbl", + "itertools 0.12.1", "js-sys", "jsonrpsee-core", "jsonrpsee-types", @@ -1028,8 +1126,9 @@ dependencies = [ "jsonrpsee-ws-client", "lightning", "lightning-invoice", + "lru", "macro_rules_attribute", - "miniscript", + "miniscript 10.0.0", "parity-scale-codec", "rand", "secp256k1-zkp", @@ -1048,44 +1147,40 @@ dependencies = [ [[package]] name = "fedimint-derive" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7490ad865cb9d8a3b5d24e0d38578df143fbe167f6cc80669a3bc7d5bc5b36d0" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ - "itertools 0.11.0", + "itertools 0.12.1", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.53", ] [[package]] name = "fedimint-derive-secret" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faacc99cbacf014e999865150f82d43808c26ac6dd07725a1d22406dce4f7b3a" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "anyhow", "fedimint-core", "fedimint-hkdf", "fedimint-tbs", - "ring 0.17.6", + "ring 0.17.8", "secp256k1-zkp", ] [[package]] name = "fedimint-hkdf" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da421d229333ce5c80bf6403165a1afe831556145a3983ac3eecbce4f1a79132" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "bitcoin_hashes 0.11.0", ] [[package]] name = "fedimint-ln-client" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f00f779dbc9b27274e166d4b0f790bf44bb9d3483db72f5c629e596d8218e2c9" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "anyhow", "aquamarine", @@ -1100,7 +1195,7 @@ dependencies = [ "fedimint-ln-common", "fedimint-threshold-crypto", "futures", - "itertools 0.10.5", + "itertools 0.12.1", "lightning-invoice", "rand", "reqwest", @@ -1118,9 +1213,8 @@ dependencies = [ [[package]] name = "fedimint-ln-common" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b56e00695812c1b300d9a97ea58edb2a8fde1f9f4b9771085de8f2eead30e3d4" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "anyhow", "aquamarine", @@ -1132,7 +1226,7 @@ dependencies = [ "fedimint-core", "fedimint-threshold-crypto", "futures", - "itertools 0.10.5", + "itertools 0.12.1", "lightning", "lightning-invoice", "rand", @@ -1149,9 +1243,8 @@ dependencies = [ [[package]] name = "fedimint-logging" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14549cd81f904053dd43eeedc2c021c1f660f6d46257f8286b9d5d8c425bdb5e" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "anyhow", "tracing-subscriber", @@ -1159,15 +1252,14 @@ dependencies = [ [[package]] name = "fedimint-mint-client" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee3945f8d4d9c807672ee10b8db4998e0718bcf9dfaa277755f8d03cc9cfc561" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "anyhow", "aquamarine", "async-stream", "async-trait", - "base64 0.20.0", + "base64 0.22.0", "bincode", "bitcoin_hashes 0.11.0", "erased-serde", @@ -1179,7 +1271,7 @@ dependencies = [ "fedimint-tbs", "fedimint-threshold-crypto", "futures", - "itertools 0.10.5", + "itertools 0.12.1", "rand", "secp256k1 0.24.3", "secp256k1-zkp", @@ -1195,9 +1287,8 @@ dependencies = [ [[package]] name = "fedimint-mint-common" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d21c16ea6bec68e01fd8fa7a1d3526121c9679bc8fc83fd9d29b977cc447af4" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "anyhow", "async-trait", @@ -1207,7 +1298,7 @@ dependencies = [ "fedimint-tbs", "fedimint-threshold-crypto", "futures", - "itertools 0.10.5", + "itertools 0.12.1", "rand", "secp256k1 0.24.3", "secp256k1-zkp", @@ -1220,9 +1311,8 @@ dependencies = [ [[package]] name = "fedimint-rocksdb" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e13f4613c2eba7cc6a371d37ab0d869d6e2ba6496882f8502cb00c3c3d57627" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "anyhow", "async-trait", @@ -1235,9 +1325,8 @@ dependencies = [ [[package]] name = "fedimint-tbs" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9cfde5114fb8ccb2abc1b0a4807e5af9fa03027a54d75209cb301edd77c29cd" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "bitcoin_hashes 0.11.0", "bls12_381", @@ -1273,9 +1362,8 @@ dependencies = [ [[package]] name = "fedimint-wallet-client" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69a4bafd7b495455f3c2fb4324fe4f7c15cf43ec01f9ce319805dc0af2708dac" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "anyhow", "aquamarine", @@ -1289,7 +1377,7 @@ dependencies = [ "fedimint-wallet-common", "futures", "impl-tools", - "miniscript", + "miniscript 10.0.0", "rand", "secp256k1 0.24.3", "serde", @@ -1305,9 +1393,8 @@ dependencies = [ [[package]] name = "fedimint-wallet-common" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27dc03be27d18fdb4e444b4801267cc219b5eccd5e0ef3521faa42a508b0f341" +version = "0.3.0-rc.0" +source = "git+https://github.com/fedimint/fedimint?tag=v0.3.0-rc.0#45c945d6307f440fd18d1fde3331fc681e0b5d1c" dependencies = [ "anyhow", "async-trait", @@ -1316,7 +1403,8 @@ dependencies = [ "fedimint-core", "futures", "impl-tools", - "miniscript", + "miniscript 10.0.0", + "miniscript 9.0.2", "rand", "secp256k1 0.24.3", "serde", @@ -1431,7 +1519,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.53", ] [[package]] @@ -1452,7 +1540,7 @@ version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" dependencies = [ - "gloo-timers", + "gloo-timers 0.2.6", "send_wrapper", ] @@ -1486,9 +1574,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if", "js-sys", @@ -1511,9 +1599,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "gloo-net" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ac9e8288ae2c632fa9f8657ac70bfe38a1530f345282d7ba66a1f70b72b7dc4" +checksum = "43aaa242d1239a8822c15c645f02166398da4f8b5c4bae795c1f5b44e9eee173" dependencies = [ "futures-channel", "futures-core", @@ -1542,6 +1630,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "gloo-utils" version = "0.2.0" @@ -1610,7 +1710,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25" dependencies = [ - "ahash", + "ahash 0.3.8", "autocfg", ] @@ -1619,6 +1719,10 @@ name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash 0.8.11", + "allocator-api2", +] [[package]] name = "heck" @@ -1641,6 +1745,12 @@ dependencies = [ "serde", ] +[[package]] +name = "hex-conservative" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ed443af458ccb6d81c1e7e661545f94d3176752fb1df2f543b902a1e0f51e2" + [[package]] name = "hex_fmt" version = "0.3.0" @@ -1835,14 +1945,10 @@ dependencies = [ ] [[package]] -name = "idna" -version = "0.4.0" +name = "ident_case" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" @@ -1855,33 +1961,49 @@ dependencies = [ ] [[package]] -name = "if_chain" -version = "1.0.2" +name = "imbl" +version = "2.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" +checksum = "978d142c8028edf52095703af2fad11d6f611af1246685725d6b850634647085" +dependencies = [ + "bitmaps", + "imbl-sized-chunks", + "rand_core", + "rand_xoshiro", + "version_check", +] + +[[package]] +name = "imbl-sized-chunks" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "144006fb58ed787dcae3f54575ff4349755b00ccc99f4b4873860b654be1ed63" +dependencies = [ + "bitmaps", +] [[package]] name = "impl-tools" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bde75c0fa563af28932bd7317eaa58186d4d29043858f5f3a8c199076c06da7" +checksum = "d82c305b1081f1a99fda262883c788e50ab57d36c00830bdd7e0a82894ad965c" dependencies = [ "autocfg", "impl-tools-lib", "proc-macro-error", - "syn 1.0.109", + "syn 2.0.53", ] [[package]] name = "impl-tools-lib" -version = "0.8.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ffdf3b0bdfaa18798f4df71bc965704f63fba521b24d425cd61fb2bc771a77b" +checksum = "85d3946d886eaab0702fa0c6585adcced581513223fa9df7ccfabbd9fa331a88" dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.53", ] [[package]] @@ -1951,18 +2073,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "itertools" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] @@ -1984,9 +2097,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" dependencies = [ "wasm-bindgen", ] @@ -2005,9 +2118,9 @@ dependencies = [ [[package]] name = "jsonrpsee-client-transport" -version = "0.20.3" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b005c793122d03217da09af68ba9383363caa950b90d3436106df8cabce935" +checksum = "455fc882e56f58228df2aee36b88a1340eafd707c76af2fa68cf94b37d461131" dependencies = [ "futures-channel", "futures-util", @@ -2015,21 +2128,22 @@ dependencies = [ "http 0.2.11", "jsonrpsee-core", "pin-project", + "rustls-pki-types", "soketto", "thiserror", "tokio", - "tokio-rustls 0.24.1", + "tokio-rustls 0.25.0", "tokio-util", "tracing", "url", - "webpki-roots", + "webpki-roots 0.26.1", ] [[package]] name = "jsonrpsee-core" -version = "0.20.3" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2327ba8df2fdbd5e897e2b5ed25ce7f299d345b9736b6828814c3dbd1fd47b" +checksum = "b75568f4f9696e3a47426e1985b548e1a9fcb13372a5e320372acaf04aca30d1" dependencies = [ "anyhow", "async-lock", @@ -2038,34 +2152,35 @@ dependencies = [ "futures-timer", "futures-util", "jsonrpsee-types", + "pin-project", "rustc-hash", "serde", "serde_json", "thiserror", "tokio", + "tokio-stream", "tracing", "wasm-bindgen-futures", ] [[package]] name = "jsonrpsee-types" -version = "0.20.3" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be0be325642e850ed0bdff426674d2e66b2b7117c9be23a7caef68a2902b7d9" +checksum = "3467fd35feeee179f71ab294516bdf3a81139e7aeebdd860e46897c12e1a3368" dependencies = [ "anyhow", "beef", "serde", "serde_json", "thiserror", - "tracing", ] [[package]] name = "jsonrpsee-wasm-client" -version = "0.20.3" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c7cbb3447cf14fd4d2f407c3cc96e6c9634d5440aa1fbed868a31f3c02b27f0" +checksum = "ee61985930ef5b67bfcd0f21a881bae25e15fc982dfc943d73de39381d5e46bf" dependencies = [ "jsonrpsee-client-transport", "jsonrpsee-core", @@ -2074,9 +2189,9 @@ dependencies = [ [[package]] name = "jsonrpsee-ws-client" -version = "0.20.3" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca9cb3933ccae417eb6b08c3448eb1cb46e39834e5b503e395e5e5bd08546c0" +checksum = "68ca71e74983f624c0cb67828e480a981586074da8ad3a2f214c6a3f884edab9" dependencies = [ "http 0.2.11", "jsonrpsee-client-transport", @@ -2124,9 +2239,9 @@ dependencies = [ [[package]] name = "librocksdb-sys" -version = "0.11.0+8.1.1" +version = "0.16.0+8.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3386f101bcb4bd252d8e9d2fb41ec3b0862a15a62b478c355b2982efa469e3e" +checksum = "ce3d60bc059831dc1c83903fb45c103f75db65c5a7bf22272764d9cc683e348c" dependencies = [ "bindgen", "bzip2-sys", @@ -2183,9 +2298,9 @@ checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "lnurl-rs" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce3b5abaabb22f7e6d68e58e269c0cd5d144760872a5a436c308de6a90f422f" +checksum = "29742339d2d88bd3ea1f4305e11b22d3efada9f86010ccbd7b6646837cc57e85" dependencies = [ "aes", "anyhow", @@ -2216,6 +2331,15 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "lru" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +dependencies = [ + "hashbrown 0.14.3", +] + [[package]] name = "lz4-sys" version = "1.9.4" @@ -2228,9 +2352,9 @@ dependencies = [ [[package]] name = "macro_rules_attribute" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf0c9b980bf4f3a37fd7b1c066941dd1b1d0152ce6ee6e8fe8c49b9f6810d862" +checksum = "8a82271f7bc033d84bbca59a3ce3e4159938cb08a9c3aebbe54d215131518a13" dependencies = [ "macro_rules_attribute-proc_macro", "paste", @@ -2238,9 +2362,9 @@ dependencies = [ [[package]] name = "macro_rules_attribute-proc_macro" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58093314a45e00c77d5c508f76e77c3396afbbc0d01506e7fae47b018bac2b1d" +checksum = "b8dd856d451cc0da70e2ef2ce95a18e39a93b7558bedf10201ad28503f918568" [[package]] name = "matchers" @@ -2282,6 +2406,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5b106477a0709e2da253e5559ba4ab20a272f8577f1eefff72f3a905b5d35f5" dependencies = [ "bitcoin 0.29.2", +] + +[[package]] +name = "miniscript" +version = "10.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1eb102b66b2127a872dbcc73095b7b47aeb9d92f7b03c2b2298253ffc82c7594" +dependencies = [ + "bitcoin 0.30.2", + "bitcoin-private", "serde", ] @@ -2305,28 +2439,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "multimint" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5f474cce3a20276cd772ee895f0283ad950aa7ba984393d8b49014b14f5cc25" -dependencies = [ - "anyhow", - "fedimint-client", - "fedimint-core", - "fedimint-ln-client", - "fedimint-mint-client", - "fedimint-rocksdb", - "fedimint-wallet-client", - "futures-util", - "hex", - "rand", - "serde", - "serde_json", - "tokio", - "tracing", -] - [[package]] name = "multimint" version = "0.1.12" @@ -2448,7 +2560,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.53", ] [[package]] @@ -2579,6 +2691,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + [[package]] name = "parking_lot" version = "0.12.1" @@ -2619,12 +2737,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - [[package]] name = "percent-encoding" version = "2.3.1" @@ -2648,7 +2760,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.53", ] [[package]] @@ -2681,16 +2793,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "prettyplease" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" -dependencies = [ - "proc-macro2", - "syn 2.0.39", -] - [[package]] name = "proc-macro-crate" version = "2.0.0" @@ -2726,9 +2828,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -2756,9 +2858,9 @@ checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -2799,6 +2901,15 @@ dependencies = [ "getrandom", ] +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -2854,9 +2965,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.5", "bytes", @@ -2882,6 +2993,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-native-tls", @@ -2892,7 +3004,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", + "webpki-roots 0.25.3", "winreg", ] @@ -2913,23 +3025,24 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.6" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684d5e6e18f669ccebf64a92236bb7db9a34f07be010e3627368182027180866" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rocksdb" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6f170a4041d50a0ce04b0d2e14916d6ca863ea2e422689a5b694395d299ffe" +checksum = "6bd13e55d6d7b8cd0ea569161127567cd587676c99f4472f779a0279aa60a7a7" dependencies = [ "libc", "librocksdb-sys", @@ -2979,11 +3092,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9" dependencies = [ "log", - "ring 0.17.6", - "rustls-webpki", + "ring 0.17.8", + "rustls-webpki 0.101.7", "sct", ] +[[package]] +name = "rustls" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41" +dependencies = [ + "log", + "ring 0.17.8", + "rustls-pki-types", + "rustls-webpki 0.102.2", + "subtle", + "zeroize", +] + [[package]] name = "rustls-pemfile" version = "1.0.4" @@ -2993,13 +3120,30 @@ dependencies = [ "base64 0.21.5", ] +[[package]] +name = "rustls-pki-types" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8" + [[package]] name = "rustls-webpki" version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.17.6", + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610" +dependencies = [ + "ring 0.17.8", + "rustls-pki-types", "untrusted 0.9.0", ] @@ -3036,7 +3180,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.6", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -3135,9 +3279,9 @@ checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -3153,20 +3297,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.53", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa", "ryu", @@ -3323,21 +3467,21 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "strum" -version = "0.24.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" [[package]] name = "strum_macros" -version = "0.24.3" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" dependencies = [ "heck", "proc-macro2", "quote", "rustversion", - "syn 1.0.109", + "syn 2.0.53", ] [[package]] @@ -3359,9 +3503,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" dependencies = [ "proc-macro2", "quote", @@ -3416,22 +3560,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.53", ] [[package]] @@ -3499,9 +3643,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.34.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -3525,7 +3669,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.53", ] [[package]] @@ -3559,6 +3703,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls 0.22.2", + "rustls-pki-types", + "tokio", +] + [[package]] name = "tokio-socks" version = "0.5.1" @@ -3580,6 +3735,7 @@ dependencies = [ "futures-core", "pin-project-lite", "tokio", + "tokio-util", ] [[package]] @@ -3644,14 +3800,13 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09e12e6351354851911bdf8c2b8f2ab15050c567d70a8b9a37ae7b8301a4080d" +checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" dependencies = [ "base64 0.21.5", "bitflags 2.4.1", "bytes", - "futures-util", "http 1.0.0", "http-body 1.0.0", "http-body-util", @@ -3694,7 +3849,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.53", ] [[package]] @@ -3807,7 +3962,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", - "idna 0.5.0", + "idna", "percent-encoding", "serde", ] @@ -3832,12 +3987,12 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "validator" -version = "0.16.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b92f40481c04ff1f4f61f304d61793c7b56ff76ac1469f1beb199b1445b253bd" +checksum = "da339118f018cc70ebf01fafc103360528aad53717e4bf311db929cb01cb9345" dependencies = [ - "idna 0.4.0", - "lazy_static", + "idna", + "once_cell", "regex", "serde", "serde_derive", @@ -3848,28 +4003,16 @@ dependencies = [ [[package]] name = "validator_derive" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc44ca3088bb3ba384d9aecf40c6a23a676ce23e09bdaca2073d99c207f864af" +checksum = "76e88ea23b8f5e59230bff8a2f03c0ee0054a61d5b8343a38946bcd406fe624c" dependencies = [ - "if_chain", - "lazy_static", + "darling", "proc-macro-error", "proc-macro2", "quote", "regex", - "syn 1.0.109", - "validator_types", -] - -[[package]] -name = "validator_types" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "111abfe30072511849c5910134e8baf8dc05de4c0e5903d681cbd5c9c4d611e3" -dependencies = [ - "proc-macro2", - "syn 1.0.109", + "syn 2.0.53", ] [[package]] @@ -3907,9 +4050,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -3917,24 +4060,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.53", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" dependencies = [ "cfg-if", "js-sys", @@ -3944,9 +4087,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3954,22 +4097,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.53", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" [[package]] name = "web-sys" @@ -3987,7 +4130,7 @@ version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring 0.17.6", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -3997,6 +4140,15 @@ version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +[[package]] +name = "webpki-roots" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi" version = "0.3.9" @@ -4188,6 +4340,26 @@ dependencies = [ "tap", ] +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", +] + [[package]] name = "zeroize" version = "1.7.0" diff --git a/fedimint-clientd/Cargo.toml b/fedimint-clientd/Cargo.toml index 410a018..2be3dbf 100644 --- a/fedimint-clientd/Cargo.toml +++ b/fedimint-clientd/Cargo.toml @@ -20,27 +20,27 @@ serde_json = "1.0.108" tokio = { version = "1.34.0", features = ["full"] } tracing = "0.1.40" tracing-subscriber = "0.3.18" -fedimint-client = "0.2.2" -fedimint-core = "0.2.2" -fedimint-wallet-client = "0.2.2" -fedimint-mint-client = "0.2.2" -fedimint-ln-client = "0.2.2" -fedimint-rocksdb = "0.2.2" +fedimint-client = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0-rc.0" } +fedimint-core = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0-rc.0" } +fedimint-wallet-client = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0-rc.0" } +fedimint-mint-client = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0-rc.0" } +fedimint-ln-client = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0-rc.0" } +fedimint-rocksdb = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0-rc.0" } url = "2.5.0" lazy_static = "1.4.0" async-utility = "0.2.0" -tower-http = { version = "0.5.0", features = ["cors", "auth", "trace"] } +tower-http = { version = "0.5.2", features = ["cors", "auth", "trace"] } bitcoin = "0.29.2" itertools = "0.12.0" -lnurl-rs = { version = "0.4.0", features = ["async"], default-features = false } -reqwest = "0.11.23" +lnurl-rs = { version = "0.4.1", features = ["async"], default-features = false } +reqwest = "0.11.27" lightning-invoice = { version = "0.26.0", features = ["serde"] } -bitcoin_hashes = "0.11.0" +bitcoin_hashes = "0.13.0" time = { version = "0.3.25", features = ["formatting"] } chrono = "0.4.31" futures-util = "0.3.30" clap = { version = "4.4.13", features = ["derive", "env"] } -multimint = "0.1.7" +multimint = { version = "0.1.12", path = "../multimint" } axum-otel-metrics = "0.8.0" [patch.crates-io] diff --git a/fedimint-clientd/src/main.rs b/fedimint-clientd/src/main.rs index 379f9dd..1449fa3 100644 --- a/fedimint-clientd/src/main.rs +++ b/fedimint-clientd/src/main.rs @@ -86,7 +86,10 @@ async fn main() -> Result<()> { match InviteCode::from_str(&cli.invite_code) { Ok(invite_code) => { - let federation_id = state.multimint.register_new(invite_code, manual_secret).await?; + let federation_id = state + .multimint + .register_new(invite_code, manual_secret) + .await?; info!("Created client for federation id: {:?}", federation_id); if cli.mode == Mode::Cashu { state.cashu_mint = Some(federation_id); @@ -210,10 +213,6 @@ fn fedimint_v2_rest() -> Router { .route( "/list-gateways", post(fedimint::ln::list_gateways::handle_rest), - ) - .route( - "/switch-gateway", - post(fedimint::ln::switch_gateway::handle_rest), ); let wallet_router = Router::new() diff --git a/fedimint-clientd/src/router/handlers/cashu/melt/method.rs b/fedimint-clientd/src/router/handlers/cashu/melt/method.rs index 4ac5b00..f8e7894 100644 --- a/fedimint-clientd/src/router/handlers/cashu/melt/method.rs +++ b/fedimint-clientd/src/router/handlers/cashu/melt/method.rs @@ -4,7 +4,7 @@ use anyhow::anyhow; use axum::extract::{Path, State}; use axum::http::StatusCode; use axum::Json; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::FederationId; use fedimint_core::Amount; use fedimint_ln_client::{LightningClientModule, OutgoingLightningPayment}; @@ -64,7 +64,7 @@ pub async fn handle_method( } pub async fn melt_bolt11( - client: ClientArc, + client: ClientHandleArc, request: String, amount_msat: Amount, ) -> Result { @@ -108,7 +108,7 @@ pub async fn melt_bolt11( } async fn melt_onchain( - client: ClientArc, + client: ClientHandleArc, request: String, amount_sat: bitcoin::Amount, ) -> Result { diff --git a/fedimint-clientd/src/router/handlers/cashu/mint/method.rs b/fedimint-clientd/src/router/handlers/cashu/mint/method.rs index eec2baf..4bdf801 100644 --- a/fedimint-clientd/src/router/handlers/cashu/mint/method.rs +++ b/fedimint-clientd/src/router/handlers/cashu/mint/method.rs @@ -4,7 +4,7 @@ use anyhow::anyhow; use axum::extract::{Path, State}; use axum::http::StatusCode; use axum::Json; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::FederationId; use fedimint_core::time::now; use fedimint_core::Amount; @@ -60,7 +60,7 @@ const DEFAULT_MINT_EXPIRY_OFFSET: u64 = 3600; const DEFAULT_MINT_DESCRIPTION: &str = "Cashu mint operation"; pub async fn mint_bolt11( - client: ClientArc, + client: ClientHandleArc, amount_msat: Amount, ) -> Result { let lightning_module = client.get_first_module::(); @@ -87,7 +87,7 @@ pub async fn mint_bolt11( } async fn mint_onchain( - client: ClientArc, + client: ClientHandleArc, _amount_sat: Amount, ) -> Result { let wallet_client = client.get_first_module::(); diff --git a/fedimint-clientd/src/router/handlers/fedimint/admin/backup.rs b/fedimint-clientd/src/router/handlers/fedimint/admin/backup.rs index 97d3a10..3c4bf2d 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/admin/backup.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/admin/backup.rs @@ -5,7 +5,7 @@ use axum::extract::State; use axum::http::StatusCode; use axum::Json; use fedimint_client::backup::Metadata; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::FederationId; use serde::Deserialize; use serde_json::{json, Value}; @@ -20,7 +20,7 @@ pub struct BackupRequest { pub federation_id: FederationId, } -async fn _backup(client: ClientArc, req: BackupRequest) -> Result<(), AppError> { +async fn _backup(client: ClientHandleArc, req: BackupRequest) -> Result<(), AppError> { client .backup_to_federation(Metadata::from_json_serialized(req.metadata)) .await diff --git a/fedimint-clientd/src/router/handlers/fedimint/admin/discover_version.rs b/fedimint-clientd/src/router/handlers/fedimint/admin/discover_version.rs index ae64f09..29d2777 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/admin/discover_version.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/admin/discover_version.rs @@ -1,32 +1,48 @@ use std::collections::HashMap; use axum::extract::State; +use axum::http::StatusCode; use axum::Json; use multimint::MultiMint; +use serde::Deserialize; use serde_json::{json, Value}; use crate::error::AppError; use crate::state::AppState; -async fn _discover_version(multimint: MultiMint) -> Result { +#[derive(Debug, Clone, Deserialize)] +pub struct DiscoverVersionRequest { + threshold: Option, +} + +async fn _discover_version(multimint: MultiMint, threshold: Option) -> Result { let mut api_versions = HashMap::new(); for (id, client) in multimint.clients.lock().await.iter() { api_versions.insert( *id, - json!({"version" : client.discover_common_api_version().await?}), + json!({"version" : client.discover_common_api_version(threshold).await?}), ); } Ok(json!(api_versions)) } -pub async fn handle_ws(state: AppState) -> Result { - let version = _discover_version(state.multimint).await?; +pub async fn handle_ws(state: AppState, v: Value) -> Result { + let v = serde_json::from_value::(v).map_err(|e| { + AppError::new( + StatusCode::BAD_REQUEST, + anyhow::anyhow!("Invalid request: {}", e), + ) + })?; + let version = _discover_version(state.multimint, v.threshold).await?; let version_json = json!(version); Ok(version_json) } #[axum_macros::debug_handler] -pub async fn handle_rest(State(state): State) -> Result, AppError> { - let version = _discover_version(state.multimint).await?; +pub async fn handle_rest( + State(state): State, + Json(req): Json, +) -> Result, AppError> { + let version = _discover_version(state.multimint, req.threshold).await?; Ok(Json(version)) } diff --git a/fedimint-clientd/src/router/handlers/fedimint/admin/join.rs b/fedimint-clientd/src/router/handlers/fedimint/admin/join.rs index 29df831..5d248dd 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/admin/join.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/admin/join.rs @@ -31,14 +31,15 @@ async fn _join(mut multimint: MultiMint, req: JoinRequest) -> Result Some(secret), Err(_) => { - return Err(anyhow!("FEDIMINT_CLIENTD_MANUAL_SECRET must be set to join with manual secret")) + return Err(anyhow!( + "FEDIMINT_CLIENTD_MANUAL_SECRET must be set to join with manual secret" + )) } } } else { None }; - let _ = multimint .register_new(req.invite_code.clone(), manual_secret) .await?; diff --git a/fedimint-clientd/src/router/handlers/fedimint/admin/list_operations.rs b/fedimint-clientd/src/router/handlers/fedimint/admin/list_operations.rs index 53d0183..2776a94 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/admin/list_operations.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/admin/list_operations.rs @@ -3,7 +3,7 @@ use std::time::UNIX_EPOCH; use axum::extract::State; use axum::http::StatusCode; use axum::Json; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::FederationId; use fedimint_core::core::OperationId; use serde::{Deserialize, Serialize}; @@ -33,7 +33,7 @@ pub struct OperationOutput { } async fn _list_operations( - client: ClientArc, + client: ClientHandleArc, req: ListOperationsRequest, ) -> Result { const ISO8601_CONFIG: iso8601::EncodedConfig = iso8601::Config::DEFAULT diff --git a/fedimint-clientd/src/router/handlers/fedimint/admin/mod.rs b/fedimint-clientd/src/router/handlers/fedimint/admin/mod.rs index 838c00c..c10c96d 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/admin/mod.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/admin/mod.rs @@ -8,12 +8,12 @@ pub mod list_operations; pub mod module; pub mod restore; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_mint_client::MintClientModule; use fedimint_wallet_client::WalletClientModule; use info::InfoResponse; -pub async fn get_note_summary(client: &ClientArc) -> anyhow::Result { +pub async fn get_note_summary(client: &ClientHandleArc) -> anyhow::Result { let mint_client = client.get_first_module::(); let wallet_client = client.get_first_module::(); let summary = mint_client diff --git a/fedimint-clientd/src/router/handlers/fedimint/admin/module.rs b/fedimint-clientd/src/router/handlers/fedimint/admin/module.rs index 01e45fe..e915749 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/admin/module.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/admin/module.rs @@ -2,7 +2,7 @@ use anyhow::anyhow; use axum::extract::State; use axum::http::StatusCode; use axum::Json; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::FederationId; use fedimint_core::core::{ModuleInstanceId, ModuleKind}; use serde::Deserialize; @@ -25,7 +25,7 @@ pub struct ModuleRequest { pub federation_id: FederationId, } -async fn _module(_client: ClientArc, _req: ModuleRequest) -> Result<(), AppError> { +async fn _module(_client: ClientHandleArc, _req: ModuleRequest) -> Result<(), AppError> { // TODO: Figure out how to impl this Err(AppError::new( StatusCode::INTERNAL_SERVER_ERROR, diff --git a/fedimint-clientd/src/router/handlers/fedimint/admin/restore.rs b/fedimint-clientd/src/router/handlers/fedimint/admin/restore.rs index 4878a86..f47fb47 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/admin/restore.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/admin/restore.rs @@ -2,13 +2,13 @@ use anyhow::anyhow; use axum::extract::State; use axum::http::StatusCode; use axum::Json; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use serde_json::{json, Value}; use crate::error::AppError; use crate::state::AppState; -async fn _restore(_client: ClientArc, _v: Value) -> Result<(), AppError> { +async fn _restore(_client: ClientHandleArc, _v: Value) -> Result<(), AppError> { // TODO: unimplemented in cli Err(AppError::new( StatusCode::INTERNAL_SERVER_ERROR, diff --git a/fedimint-clientd/src/router/handlers/fedimint/ln/await_invoice.rs b/fedimint-clientd/src/router/handlers/fedimint/ln/await_invoice.rs index cfaf0d0..e284209 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/ln/await_invoice.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/ln/await_invoice.rs @@ -2,7 +2,7 @@ use anyhow::anyhow; use axum::extract::State; use axum::http::StatusCode; use axum::Json; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::FederationId; use fedimint_core::core::OperationId; use fedimint_ln_client::{LightningClientModule, LnReceiveState}; @@ -24,7 +24,7 @@ pub struct AwaitInvoiceRequest { } async fn _await_invoice( - client: ClientArc, + client: ClientHandleArc, req: AwaitInvoiceRequest, ) -> Result { let lightning_module = &client.get_first_module::(); diff --git a/fedimint-clientd/src/router/handlers/fedimint/ln/await_pay.rs b/fedimint-clientd/src/router/handlers/fedimint/ln/await_pay.rs index a4ee3ec..8324412 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/ln/await_pay.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/ln/await_pay.rs @@ -2,7 +2,7 @@ use anyhow::{anyhow, Context}; use axum::extract::State; use axum::http::StatusCode; use axum::Json; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::FederationId; use fedimint_core::core::OperationId; use fedimint_ln_client::{LightningClientModule, PayType}; @@ -21,7 +21,10 @@ pub struct AwaitLnPayRequest { pub federation_id: FederationId, } -async fn _await_pay(client: ClientArc, req: AwaitLnPayRequest) -> Result { +async fn _await_pay( + client: ClientHandleArc, + req: AwaitLnPayRequest, +) -> Result { let lightning_module = client.get_first_module::(); let ln_pay_details = lightning_module .get_ln_pay_details_for(req.operation_id) diff --git a/fedimint-clientd/src/router/handlers/fedimint/ln/invoice.rs b/fedimint-clientd/src/router/handlers/fedimint/ln/invoice.rs index 9e46357..0764adf 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/ln/invoice.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/ln/invoice.rs @@ -2,13 +2,15 @@ use anyhow::anyhow; use axum::extract::State; use axum::http::StatusCode; use axum::Json; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::FederationId; use fedimint_core::core::OperationId; use fedimint_core::Amount; use fedimint_ln_client::LightningClientModule; +use lightning_invoice::{Bolt11InvoiceDescription, Description}; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; +use tracing::error; use crate::error::AppError; use crate::state::AppState; @@ -29,12 +31,37 @@ pub struct LnInvoiceResponse { pub invoice: String, } -async fn _invoice(client: ClientArc, req: LnInvoiceRequest) -> Result { +async fn _invoice( + client: ClientHandleArc, + req: LnInvoiceRequest, +) -> Result { let lightning_module = client.get_first_module::(); - lightning_module.select_active_gateway().await?; + let gateway_id = match lightning_module.list_gateways().await.first() { + Some(gateway_announcement) => gateway_announcement.info.gateway_id, + None => { + error!("No gateways available"); + return Err(AppError::new( + StatusCode::INTERNAL_SERVER_ERROR, + anyhow!("No gateways available"), + )) + } + }; + let gateway = lightning_module.select_gateway(&gateway_id).await.ok_or_else(|| { + error!("Failed to select gateway"); + AppError::new( + StatusCode::INTERNAL_SERVER_ERROR, + anyhow!("Failed to select gateway"), + ) + })?; - let (operation_id, invoice) = lightning_module - .create_bolt11_invoice(req.amount_msat, req.description, req.expiry_time, ()) + let (operation_id, invoice, _) = lightning_module + .create_bolt11_invoice( + req.amount_msat, + Bolt11InvoiceDescription::Direct(&Description::new(req.description)?), + req.expiry_time, + (), + Some(gateway), + ) .await?; Ok(LnInvoiceResponse { operation_id, diff --git a/fedimint-clientd/src/router/handlers/fedimint/ln/list_gateways.rs b/fedimint-clientd/src/router/handlers/fedimint/ln/list_gateways.rs index 28ce7d1..2c08e6e 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/ln/list_gateways.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/ln/list_gateways.rs @@ -2,7 +2,7 @@ use anyhow::anyhow; use axum::extract::State; use axum::http::StatusCode; use axum::Json; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::FederationId; use fedimint_ln_client::LightningClientModule; use serde::Deserialize; @@ -17,26 +17,21 @@ pub struct ListGatewaysRequest { pub federation_id: FederationId, } -async fn _list_gateways(client: ClientArc) -> Result { +async fn _list_gateways(client: ClientHandleArc) -> Result { let lightning_module = client.get_first_module::(); - let gateways = lightning_module.fetch_registered_gateways().await?; + let gateways = lightning_module.list_gateways().await; if gateways.is_empty() { return Ok(serde_json::to_value(Vec::::new()).unwrap()); } let mut gateways_json = json!(&gateways); - let active_gateway = lightning_module.select_active_gateway().await?; - gateways_json .as_array_mut() .expect("gateways_json is not an array") .iter_mut() .for_each(|gateway| { - if gateway["node_pub_key"] == json!(active_gateway.node_pub_key) { - gateway["active"] = json!(true); - } else { - gateway["active"] = json!(false); - } + let gateway = gateway.as_object_mut().expect("gateway is not an object"); + gateway.insert("federation_id".to_string(), json!(client.federation_id())); }); Ok(serde_json::to_value(gateways_json).unwrap()) } diff --git a/fedimint-clientd/src/router/handlers/fedimint/ln/mod.rs b/fedimint-clientd/src/router/handlers/fedimint/ln/mod.rs index 0eb1d6a..bfe8355 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/ln/mod.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/ln/mod.rs @@ -1,12 +1,12 @@ use std::str::FromStr; use anyhow::{bail, Context}; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::Amount; use fedimint_ln_client::{InternalPayState, LightningClientModule, LnPayState, PayType}; -use futures_util::StreamExt; use lightning_invoice::Bolt11Invoice; use tracing::{debug, info}; +use futures_util::StreamExt; use self::pay::{LnPayRequest, LnPayResponse}; @@ -15,7 +15,6 @@ pub mod await_pay; pub mod invoice; pub mod list_gateways; pub mod pay; -pub mod switch_gateway; pub async fn get_invoice(req: &LnPayRequest) -> anyhow::Result { let info = req.payment_info.trim(); @@ -65,14 +64,12 @@ pub async fn get_invoice(req: &LnPayRequest) -> anyhow::Result { } pub async fn wait_for_ln_payment( - client: &ClientArc, + client: &ClientHandleArc, payment_type: PayType, contract_id: String, return_on_funding: bool, ) -> anyhow::Result> { let lightning_module = client.get_first_module::(); - lightning_module.select_active_gateway().await?; - match payment_type { PayType::Internal(operation_id) => { let mut updates = lightning_module diff --git a/fedimint-clientd/src/router/handlers/fedimint/ln/pay.rs b/fedimint-clientd/src/router/handlers/fedimint/ln/pay.rs index 556e30f..b3fa4bc 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/ln/pay.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/ln/pay.rs @@ -2,14 +2,14 @@ use anyhow::{anyhow, Context}; use axum::extract::State; use axum::http::StatusCode; use axum::Json; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::FederationId; use fedimint_core::core::OperationId; use fedimint_core::Amount; use fedimint_ln_client::{LightningClientModule, OutgoingLightningPayment, PayType}; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; -use tracing::info; +use tracing::{error, info}; use crate::error::AppError; use crate::router::handlers::fedimint::ln::{get_invoice, wait_for_ln_payment}; @@ -34,17 +34,33 @@ pub struct LnPayResponse { pub fee: Amount, } -async fn _pay(client: ClientArc, req: LnPayRequest) -> Result { +async fn _pay(client: ClientHandleArc, req: LnPayRequest) -> Result { let bolt11 = get_invoice(&req).await?; info!("Paying invoice: {bolt11}"); let lightning_module = client.get_first_module::(); - lightning_module.select_active_gateway().await?; + let gateway_id = match lightning_module.list_gateways().await.first() { + Some(gateway_announcement) => gateway_announcement.info.gateway_id, + None => { + error!("No gateways available"); + return Err(AppError::new( + StatusCode::INTERNAL_SERVER_ERROR, + anyhow!("No gateways available"), + )) + } + }; + let gateway = lightning_module.select_gateway(&gateway_id).await.ok_or_else(|| { + error!("Failed to select gateway"); + AppError::new( + StatusCode::INTERNAL_SERVER_ERROR, + anyhow!("Failed to select gateway"), + ) + })?; let OutgoingLightningPayment { payment_type, contract_id, fee, - } = lightning_module.pay_bolt11_invoice(bolt11, ()).await?; + } = lightning_module.pay_bolt11_invoice(Some(gateway), bolt11, ()).await?; let operation_id = payment_type.operation_id(); info!("Gateway fee: {fee}, payment operation id: {operation_id}"); if req.finish_in_background { diff --git a/fedimint-clientd/src/router/handlers/fedimint/ln/switch_gateway.rs b/fedimint-clientd/src/router/handlers/fedimint/ln/switch_gateway.rs deleted file mode 100644 index 2509f09..0000000 --- a/fedimint-clientd/src/router/handlers/fedimint/ln/switch_gateway.rs +++ /dev/null @@ -1,51 +0,0 @@ -use std::str::FromStr; - -use anyhow::anyhow; -use axum::extract::State; -use axum::http::StatusCode; -use axum::Json; -use bitcoin::secp256k1::PublicKey; -use fedimint_client::ClientArc; -use fedimint_core::config::FederationId; -use fedimint_ln_client::LightningClientModule; -use serde::Deserialize; -use serde_json::{json, Value}; - -use crate::error::AppError; -use crate::state::AppState; - -#[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct SwitchGatewayRequest { - pub gateway_id: String, - pub federation_id: FederationId, -} - -async fn _switch_gateway(client: ClientArc, req: SwitchGatewayRequest) -> Result { - let public_key = PublicKey::from_str(&req.gateway_id)?; - let lightning_module = client.get_first_module::(); - lightning_module.set_active_gateway(&public_key).await?; - let gateway = lightning_module.select_active_gateway().await?; - let mut gateway_json = json!(&gateway); - gateway_json["active"] = json!(true); - Ok(serde_json::to_value(gateway_json).unwrap()) -} - -pub async fn handle_ws(state: AppState, v: Value) -> Result { - let v = serde_json::from_value::(v) - .map_err(|e| AppError::new(StatusCode::BAD_REQUEST, anyhow!("Invalid request: {}", e)))?; - let client = state.get_client(v.federation_id).await?; - let gateway = _switch_gateway(client, v).await?; - let gateway_json = json!(gateway); - Ok(gateway_json) -} - -#[axum_macros::debug_handler] -pub async fn handle_rest( - State(state): State, - Json(req): Json, -) -> Result, AppError> { - let client = state.get_client(req.federation_id).await?; - let gateway = _switch_gateway(client, req).await?; - Ok(Json(gateway)) -} diff --git a/fedimint-clientd/src/router/handlers/fedimint/mint/reissue.rs b/fedimint-clientd/src/router/handlers/fedimint/mint/reissue.rs index b815afb..f9f624c 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/mint/reissue.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/mint/reissue.rs @@ -2,7 +2,7 @@ use anyhow::anyhow; use axum::extract::State; use axum::http::StatusCode; use axum::Json; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::Amount; use fedimint_mint_client::{MintClientModule, OOBNotes}; use futures_util::StreamExt; @@ -25,7 +25,10 @@ pub struct ReissueResponse { pub amount_msat: Amount, } -async fn _reissue(client: ClientArc, req: ReissueRequest) -> Result { +async fn _reissue( + client: ClientHandleArc, + req: ReissueRequest, +) -> Result { let amount_msat = req.notes.total_amount(); let mint = client.get_first_module::(); diff --git a/fedimint-clientd/src/router/handlers/fedimint/mint/spend.rs b/fedimint-clientd/src/router/handlers/fedimint/mint/spend.rs index 6219f6d..6120620 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/mint/spend.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/mint/spend.rs @@ -4,11 +4,11 @@ use anyhow::anyhow; use axum::extract::State; use axum::http::StatusCode; use axum::Json; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::FederationId; use fedimint_core::core::OperationId; use fedimint_core::Amount; -use fedimint_mint_client::{MintClientModule, OOBNotes, SelectNotesWithAtleastAmount}; +use fedimint_mint_client::{MintClientModule, OOBNotes, SelectNotesWithAtleastAmount, SelectNotesWithExactAmount}; use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; use tracing::{info, warn}; @@ -22,6 +22,7 @@ pub struct SpendRequest { pub amount_msat: Amount, pub allow_overpay: bool, pub timeout: u64, + pub include_invite: bool, pub federation_id: FederationId, } @@ -32,23 +33,42 @@ pub struct SpendResponse { pub notes: OOBNotes, } -async fn _spend(client: ClientArc, req: SpendRequest) -> Result { +async fn _spend(client: ClientHandleArc, req: SpendRequest) -> Result { warn!("The client will try to double-spend these notes after the duration specified by the --timeout option to recover any unclaimed e-cash."); - let mint_module = client.get_first_module::(); - let timeout = Duration::from_secs(req.timeout); - let (operation, notes) = mint_module - .spend_notes_with_selector(&SelectNotesWithAtleastAmount, req.amount_msat, timeout, ()) - .await?; + let timeout = Duration::from_secs(req.timeout); + let (operation, notes) = if req.allow_overpay { + let (operation, notes) = mint_module + .spend_notes_with_selector( + &SelectNotesWithAtleastAmount, + req.amount_msat, + timeout, + req.include_invite, + (), + ) + .await?; + + let overspend_amount = notes.total_amount() - req.amount_msat; + if overspend_amount != Amount::ZERO { + warn!( + "Selected notes {} worth more than requested", + overspend_amount + ); + } - let overspend_amount = notes.total_amount() - req.amount_msat; - if overspend_amount != Amount::ZERO { - warn!( - "Selected notes {} worth more than requested", - overspend_amount - ); - } - info!("Spend e-cash operation: {operation}"); + (operation, notes) + } else { + mint_module + .spend_notes_with_selector( + &SelectNotesWithExactAmount, + req.amount_msat, + timeout, + req.include_invite, + (), + ) + .await? + }; + info!("Spend e-cash operation: {operation}"); Ok(SpendResponse { operation, notes }) } diff --git a/fedimint-clientd/src/router/handlers/fedimint/mint/validate.rs b/fedimint-clientd/src/router/handlers/fedimint/mint/validate.rs index aad95eb..73460e5 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/mint/validate.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/mint/validate.rs @@ -2,7 +2,7 @@ use anyhow::anyhow; use axum::extract::State; use axum::http::StatusCode; use axum::Json; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::Amount; use fedimint_mint_client::{MintClientModule, OOBNotes}; use serde::{Deserialize, Serialize}; @@ -23,7 +23,10 @@ pub struct ValidateResponse { pub amount_msat: Amount, } -async fn _validate(client: ClientArc, req: ValidateRequest) -> Result { +async fn _validate( + client: ClientHandleArc, + req: ValidateRequest, +) -> Result { let amount_msat = client .get_first_module::() .validate_notes(req.notes) diff --git a/fedimint-clientd/src/router/handlers/fedimint/wallet/await_deposit.rs b/fedimint-clientd/src/router/handlers/fedimint/wallet/await_deposit.rs index b14719a..2f945d4 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/wallet/await_deposit.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/wallet/await_deposit.rs @@ -2,7 +2,7 @@ use anyhow::anyhow; use axum::extract::State; use axum::http::StatusCode; use axum::Json; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::FederationId; use fedimint_core::core::OperationId; use fedimint_wallet_client::{DepositState, WalletClientModule}; @@ -27,7 +27,7 @@ pub struct AwaitDepositResponse { } async fn _await_deposit( - client: ClientArc, + client: ClientHandleArc, req: AwaitDepositRequest, ) -> Result { let mut updates = client diff --git a/fedimint-clientd/src/router/handlers/fedimint/wallet/deposit_address.rs b/fedimint-clientd/src/router/handlers/fedimint/wallet/deposit_address.rs index 4967a44..e502c73 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/wallet/deposit_address.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/wallet/deposit_address.rs @@ -5,7 +5,7 @@ use axum::extract::State; use axum::http::StatusCode; use axum::Json; use bitcoin::Address; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::FederationId; use fedimint_core::core::OperationId; use fedimint_core::time::now; @@ -31,7 +31,7 @@ pub struct DepositAddressResponse { } async fn _deposit_address( - client: ClientArc, + client: ClientHandleArc, req: DepositAddressRequest, ) -> Result { let wallet_module = client.get_first_module::(); diff --git a/fedimint-clientd/src/router/handlers/fedimint/wallet/withdraw.rs b/fedimint-clientd/src/router/handlers/fedimint/wallet/withdraw.rs index 3700aea..e478ea7 100644 --- a/fedimint-clientd/src/router/handlers/fedimint/wallet/withdraw.rs +++ b/fedimint-clientd/src/router/handlers/fedimint/wallet/withdraw.rs @@ -2,9 +2,9 @@ use anyhow::anyhow; use axum::extract::State; use axum::http::StatusCode; use axum::Json; +use bitcoin::hashes::hex::ToHex; use bitcoin::Address; -use bitcoin_hashes::hex::ToHex; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::FederationId; use fedimint_core::BitcoinAmountOrAll; use fedimint_wallet_client::{WalletClientModule, WithdrawState}; @@ -31,7 +31,10 @@ pub struct WithdrawResponse { pub fees_sat: u64, } -async fn _withdraw(client: ClientArc, req: WithdrawRequest) -> Result { +async fn _withdraw( + client: ClientHandleArc, + req: WithdrawRequest, +) -> Result { let wallet_module = client.get_first_module::(); let (amount, fees) = match req.amount_sat { // If the amount is "all", then we need to subtract the fees from diff --git a/fedimint-clientd/src/router/ws.rs b/fedimint-clientd/src/router/ws.rs index 097f17a..de5f01c 100644 --- a/fedimint-clientd/src/router/ws.rs +++ b/fedimint-clientd/src/router/ws.rs @@ -64,7 +64,6 @@ pub enum JsonRpcMethod { LnPay, LnAwaitPay, LnListGateways, - LnSwitchGateway, WalletDepositAddress, WalletAwaitDeposit, WalletWithdraw, @@ -148,7 +147,7 @@ async fn match_method(req: JsonRpcRequest, state: AppState) -> Result { - handlers::fedimint::admin::discover_version::handle_ws(state.clone()).await + handlers::fedimint::admin::discover_version::handle_ws(state.clone(), req.params).await } JsonRpcMethod::AdminFederationIds => { handlers::fedimint::admin::federation_ids::handle_ws(state.clone(), req.params).await @@ -196,9 +195,6 @@ async fn match_method(req: JsonRpcRequest, state: AppState) -> Result { handlers::fedimint::ln::list_gateways::handle_ws(state.clone(), req.params).await } - JsonRpcMethod::LnSwitchGateway => { - handlers::fedimint::ln::switch_gateway::handle_ws(state.clone(), req.params).await - } JsonRpcMethod::WalletDepositAddress => { handlers::fedimint::wallet::deposit_address::handle_ws(state.clone(), req.params).await } diff --git a/fedimint-clientd/src/state.rs b/fedimint-clientd/src/state.rs index b9bed93..31a24aa 100644 --- a/fedimint-clientd/src/state.rs +++ b/fedimint-clientd/src/state.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; use anyhow::{anyhow, Result}; use axum::http::StatusCode; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::config::{FederationId, FederationIdPrefix}; use multimint::MultiMint; @@ -23,7 +23,10 @@ impl AppState { } // Helper function to get a specific client from the state or default - pub async fn get_client(&self, federation_id: FederationId) -> Result { + pub async fn get_client( + &self, + federation_id: FederationId, + ) -> Result { match self.multimint.get(&federation_id).await { Some(client) => Ok(client), None => Err(AppError::new( @@ -33,7 +36,7 @@ impl AppState { } } - pub async fn get_cashu_client(&self) -> Result { + pub async fn get_cashu_client(&self) -> Result { match self.cashu_mint { Some(client) => match self.multimint.get(&client).await { Some(client) => Ok(client), @@ -52,7 +55,7 @@ impl AppState { pub async fn get_client_by_prefix( &self, federation_id_prefix: &FederationIdPrefix, - ) -> Result { + ) -> Result { let client = self.multimint.get_by_prefix(federation_id_prefix).await; match client { diff --git a/multimint/Cargo.toml b/multimint/Cargo.toml index 73f78f7..52e5e32 100644 --- a/multimint/Cargo.toml +++ b/multimint/Cargo.toml @@ -13,12 +13,12 @@ anyhow = "1.0.75" serde = "1.0.193" serde_json = "1.0.108" tokio = { version = "1.34.0", features = ["full"] } -fedimint-client = "0.2.2" -fedimint-core = "0.2.2" -fedimint-wallet-client = "0.2.2" -fedimint-mint-client = "0.2.2" -fedimint-ln-client = "0.2.2" -fedimint-rocksdb = "0.2.2" +fedimint-client = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0-rc.0" } +fedimint-core = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0-rc.0" } +fedimint-wallet-client = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0-rc.0" } +fedimint-mint-client = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0-rc.0" } +fedimint-ln-client = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0-rc.0" } +fedimint-rocksdb = { git = "https://github.com/fedimint/fedimint", tag = "v0.3.0-rc.0" } futures-util = "0.3.30" rand = "0.8.5" tracing = "0.1.40" diff --git a/multimint/src/client.rs b/multimint/src/client.rs index 7eb281f..ce56e14 100644 --- a/multimint/src/client.rs +++ b/multimint/src/client.rs @@ -1,12 +1,15 @@ -//! LocalClientBuilder is a builder pattern for adding Fedimint Clients to the multimint +//! LocalClientBuilder is a builder pattern for adding Fedimint Clients to the +//! multimint -use anyhow::Result; use std::collections::BTreeMap; use std::fmt::Debug; use std::path::PathBuf; +use std::sync::Arc; +use anyhow::Result; use fedimint_client::secret::{PlainRootSecretStrategy, RootSecretStrategy}; -use fedimint_client::{get_config_from_db, Client, FederationInfo}; +use fedimint_client::Client; +use fedimint_core::config::ClientConfig; use fedimint_core::db::{ Committable, Database, DatabaseTransaction, IDatabaseTransactionOpsCoreTyped, }; @@ -33,7 +36,11 @@ impl LocalClientBuilder { impl LocalClientBuilder { /// Build a new client with the given config and optional manual secret #[allow(clippy::too_many_arguments)] - pub async fn build(&self, config: FederationConfig, manual_secret: Option<[u8; 64]>) -> Result { + pub async fn build( + &self, + config: FederationConfig, + manual_secret: Option<[u8; 64]>, + ) -> Result { let federation_id = config.invite_code.federation_id(); let db_path = self.work_dir.join(format!("{federation_id}.db")); @@ -43,39 +50,43 @@ impl LocalClientBuilder { Default::default(), ); - let mut client_builder = Client::builder(); - client_builder.with_database(db.clone()); + let mut client_builder = Client::builder(db); client_builder.with_module(WalletClientInit(None)); client_builder.with_module(MintClientInit); client_builder.with_module(LightningClientInit); client_builder.with_primary_module(1); - let client_secret = match client_builder.load_decodable_client_secret().await { - Ok(secret) => secret, - Err(_) => { - if let Some(manual_secret) = manual_secret { - info!("Using manual secret provided by user and writing to client storage"); - client_builder.store_encodable_client_secret(manual_secret).await?; - manual_secret - } else { - info!("Generating new secret and writing to client storage"); - let secret = PlainRootSecretStrategy::random(&mut thread_rng()); - client_builder.store_encodable_client_secret(secret).await?; - secret + let client_secret = + match Client::load_decodable_client_secret::<[u8; 64]>(client_builder.db()).await { + Ok(secret) => secret, + Err(_) => { + if let Some(manual_secret) = manual_secret { + info!("Using manual secret provided by user and writing to client storage"); + Client::store_encodable_client_secret(client_builder.db(), manual_secret) + .await?; + manual_secret + } else { + info!("Generating new secret and writing to client storage"); + let secret = PlainRootSecretStrategy::random(&mut thread_rng()); + Client::store_encodable_client_secret(client_builder.db(), secret).await?; + secret + } } - } - }; + }; let root_secret = PlainRootSecretStrategy::to_root_secret(&client_secret); - - if get_config_from_db(&db).await.is_none() { - let federation_info = FederationInfo::from_invite_code(config.invite_code).await?; - client_builder.with_federation_info(federation_info); - }; - - let client_res = client_builder.build(root_secret.clone()).await?; - - Ok(client_res) + let client_res = if Client::is_initialized(client_builder.db()).await { + client_builder.open(root_secret).await + } else { + let client_config = + ClientConfig::download_from_invite_code(&config.invite_code).await?; + client_builder + // TODO: make this configurable? + .join(root_secret, client_config.to_owned()) + .await + }?; + + Ok(Arc::new(client_res)) } /// Save the federation config to the database diff --git a/multimint/src/lib.rs b/multimint/src/lib.rs index 24c9106..832df4a 100644 --- a/multimint/src/lib.rs +++ b/multimint/src/lib.rs @@ -1,40 +1,48 @@ //! # Multimint //! -//! `multimint` is a library for managing Fedimint Clients across multiple federations. -//! -//! The main struct is `MultiMint` which holds a map of `ClientArc`s keyed by `FederationId`, and provides methods for managing and interacting with the clients. -//! -//! Multimint uses 1 top level directory for all its data, and creates subdirectories for each client. Each client's directory behaves like a standalone Fedimint client. -//! -//! Example file tree with 2 clients +//! `multimint` is a library for managing Fedimint Clients across multiple +//! federations. +//! +//! The main struct is `MultiMint` which holds a map of `ClientHandleArc`s keyed +//! by `FederationId`, and provides methods for managing and interacting with +//! the clients. +//! +//! Multimint uses 1 top level directory for all its data, and creates +//! subdirectories for each client. Each client's directory behaves like a +//! standalone Fedimint client. +//! +//! Example file tree with 2 clients //! ```text //! ├── fm_data_dir //! │ ├── 15db8cb4f1ec8e484d73b889372bec94812580f929e8148b7437d359af422cd3.db //! │ ├── 412d2a9338ebeee5957382eb06eac07fa5235087b5a7d5d0a6e18c635394e9ed.db //! │ ├── multimint.db //! ``` -//! -//! When you create a new `MultiMint` instance you pass it a path to the top level directory for all its data. If the directory does not exist it will be created. If the directory already has data from a previous run, it will be loaded. -//! +//! +//! When you create a new `MultiMint` instance you pass it a path to the top +//! level directory for all its data. If the directory does not exist it will be +//! created. If the directory already has data from a previous run, it will be +//! loaded. +//! //! Example: -//! +//! //! ```rust //! use multimint::MultiMint; //! use std::path::PathBuf; -//! +//! //! #[tokio::main] //! async fn main() -> Result<(), Box> { //! let work_dir = PathBuf::from("/path/to/fm_data_dir"); -//! -//! // `new` handles creating a new multimint with no clients or will load the existing databases in the work_dir into ClientArcs +//! +//! // `new` handles creating a new multimint with no clients or will load the existing databases in the work_dir into ClientHandleArcs //! let multimint = MultiMint::new(work_dir).await?; -//! +//! //! // List the ids of the federations the multimint has clients for //! // E.g. if the work_dir has 2 clients, the ids will be [FederationId, FederationId] //! // If there are no clients, the ids will be an empty vector //! let federation_ids = multimint.ids().await; //! println!("Federation IDs: {:?}", federation_ids); -//! +//! //! // Create a new client by connecting to a federation with an invite code //! let invite_code = "fed1_invite_code"; //! // The client's keypair is created based off a 64 byte random secret that is either generated or provided by the user @@ -48,22 +56,24 @@ //! Ok(()) //! } //! ``` -//! -//! The `MultiMint` struct provides methods for adding, removing, and updating clients, as well as getting information about the clients and their balances. +//! +//! The `MultiMint` struct provides methods for adding, removing, and updating +//! clients, as well as getting information about the clients and their +//! balances. +use std::collections::BTreeMap; +use std::path::PathBuf; +use std::str::FromStr; +use std::sync::Arc; use anyhow::Result; -use fedimint_client::ClientArc; +use fedimint_client::ClientHandleArc; use fedimint_core::api::InviteCode; use fedimint_core::config::{FederationId, FederationIdPrefix, JsonClientConfig}; use fedimint_core::db::Database; use fedimint_core::Amount; use fedimint_mint_client::MintClientModule; use fedimint_wallet_client::WalletClientModule; -use std::collections::BTreeMap; -use std::path::PathBuf; -use std::str::FromStr; -use std::sync::Arc; use tokio::sync::Mutex; use tracing::warn; use types::InfoResponse; @@ -75,38 +85,41 @@ pub mod types; use crate::client::LocalClientBuilder; use crate::db::FederationConfig; -/// `MultiMint` is a struct for managing Fedimint Clients across multiple federations. +/// `MultiMint` is a struct for managing Fedimint Clients across multiple +/// federations. #[derive(Debug, Clone)] pub struct MultiMint { db: Database, pub client_builder: LocalClientBuilder, - pub clients: Arc>>, + pub clients: Arc>>, } impl MultiMint { /// Create a new `MultiMint` instance. - /// - /// The `work_dir` parameter is the path to the top level directory for all its data. If the directory does not exist it will be created. If the directory already has data from a previous run, it will be loaded. - /// + /// + /// The `work_dir` parameter is the path to the top level directory for all + /// its data. If the directory does not exist it will be created. If the + /// directory already has data from a previous run, it will be loaded. + /// /// # Example - /// + /// /// ```rust /// use multimint::MultiMint; /// use std::path::PathBuf; - /// + /// /// #[tokio::main] /// async fn main() -> Result<(), Box> { /// let work_dir = PathBuf::from("/path/to/fm_data_dir"); - /// - /// // `new` handles creating a new multimint with no clients or will load the existing databases in the work_dir into ClientArcs + /// + /// // `new` handles creating a new multimint with no clients or will load the existing databases in the work_dir into ClientHandleArcs /// let multimint = MultiMint::new(work_dir).await?; - /// + /// /// // List the ids of the federations the multimint has clients for /// // E.g. if the work_dir has 2 clients, the ids will be [FederationId, FederationId] /// // If there are no clients, the ids will be an empty vector /// let federation_ids = multimint.ids().await; /// println!("Federation IDs: {:?}", federation_ids); - /// + /// /// // Create a new client by connecting to a federation with an invite code /// let invite_code = "fed1_invite_code"; /// // The client's keypair is created based off a 64 byte random secret that is either generated or provided by the user @@ -141,7 +154,7 @@ impl MultiMint { /// Load the clients from from the top level database in the work directory async fn load_clients( - clients: &mut Arc>>, + clients: &mut Arc>>, db: &Database, client_builder: &LocalClientBuilder, ) -> Result<()> { @@ -164,16 +177,26 @@ impl MultiMint { } /// Register a new client by connecting to a federation with an invite code. - /// + /// /// If the client already exists, it will be updated. - /// - /// You can provide a manual secret to use for the client's keypair. If you don't provide a secret, a 64 byte random secret will be generated, which you can extract from the client if needed. - pub async fn register_new(&mut self, invite_code: InviteCode, manual_secret: Option) -> Result { + /// + /// You can provide a manual secret to use for the client's keypair. If you + /// don't provide a secret, a 64 byte random secret will be generated, which + /// you can extract from the client if needed. + pub async fn register_new( + &mut self, + invite_code: InviteCode, + manual_secret: Option, + ) -> Result { let manual_secret: Option<[u8; 64]> = match manual_secret { Some(manual_secret) => { let bytes = hex::decode(&manual_secret)?; - Some(bytes.try_into().map_err(|_| anyhow::anyhow!("Manual secret must be 64 bytes long"))?) - }, + Some( + bytes + .try_into() + .map_err(|_| anyhow::anyhow!("Manual secret must be 64 bytes long"))?, + ) + } None => None, }; let federation_id = invite_code.federation_id(); @@ -193,7 +216,10 @@ impl MultiMint { let client_cfg = FederationConfig { invite_code }; - let client = self.client_builder.build(client_cfg.clone(), manual_secret).await?; + let client = self + .client_builder + .build(client_cfg.clone(), manual_secret) + .await?; self.clients.lock().await.insert(federation_id, client); @@ -206,7 +232,7 @@ impl MultiMint { } /// Get all the clients in the multimint. - pub async fn all(&self) -> Vec { + pub async fn all(&self) -> Vec { self.clients.lock().await.values().cloned().collect() } @@ -216,21 +242,23 @@ impl MultiMint { } /// Get a client by its federation id. - pub async fn get(&self, federation_id: &FederationId) -> Option { + pub async fn get(&self, federation_id: &FederationId) -> Option { self.clients.lock().await.get(federation_id).cloned() } - /// Get a client by its federation id as a string. (Useful for passing in from the command line or typescript/python/golang sdks) - pub async fn get_by_str(&self, federation_id_str: &str) -> Option { + /// Get a client by its federation id as a string. (Useful for passing in + /// from the command line or typescript/python/golang sdks) + pub async fn get_by_str(&self, federation_id_str: &str) -> Option { let federation_id = FederationId::from_str(federation_id_str).ok()?; self.get(&federation_id).await } - /// Get a client by its federation id prefix. (Useful for checking if a client exists for given ecash notes) + /// Get a client by its federation id prefix. (Useful for checking if a + /// client exists for given ecash notes) pub async fn get_by_prefix( &self, federation_id_prefix: &FederationIdPrefix, - ) -> Option { + ) -> Option { let keys = self .clients .lock() @@ -249,7 +277,7 @@ impl MultiMint { } /// Update a client by its federation id. - pub async fn update(&self, federation_id: &FederationId, new_client: ClientArc) { + pub async fn update(&self, federation_id: &FederationId, new_client: ClientHandleArc) { self.clients .lock() .await diff --git a/multimint/src/types.rs b/multimint/src/types.rs index d7557a3..820614c 100644 --- a/multimint/src/types.rs +++ b/multimint/src/types.rs @@ -1,6 +1,7 @@ use std::collections::BTreeMap; -use fedimint_core::{config::FederationId, Amount, TieredSummary}; +use fedimint_core::config::FederationId; +use fedimint_core::{Amount, TieredSummary}; use serde::Serialize; /// InfoResponse for getting the Federation Config info