diff --git a/Cargo.lock b/Cargo.lock index 91a2fdf..0f819f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "ahash" version = "0.7.6" @@ -154,9 +160,9 @@ checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "414dcefbc63d77c526a76b3afcf6fbb9b5e2791c19c3aa2297733208750c6e53" [[package]] name = "base64-compat" @@ -307,6 +313,12 @@ version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +[[package]] +name = "bytemuck" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" + [[package]] name = "byteorder" version = "1.4.3" @@ -370,6 +382,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "186dce98367766de751c42c4f03970fc60fc012296e706ccbb9d5df9b6c1e271" +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + [[package]] name = "config" version = "0.13.3" @@ -437,6 +455,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + [[package]] name = "crunchy" version = "0.2.2" @@ -569,6 +596,15 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +[[package]] +name = "fdeflate" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" +dependencies = [ + "simd-adler32", +] + [[package]] name = "fedimint-aead" version = "0.1.0" @@ -714,6 +750,7 @@ version = "0.1.0" dependencies = [ "anyhow", "async-trait", + "base64 0.21.3", "console_error_panic_hook", "fedimint-client", "fedimint-core", @@ -726,6 +763,7 @@ dependencies = [ "leptos-qr-scanner", "leptos_meta", "lightning-invoice", + "qrcode-generator", "rexie", "serde", "thiserror", @@ -935,6 +973,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "flate2" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -1309,6 +1357,20 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" +[[package]] +name = "image" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-rational", + "num-traits", + "png", +] + [[package]] name = "impl-tools" version = "0.8.0" @@ -1666,7 +1728,7 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5500318e457b4ab841722a5988e8db0def1ee7ac66b816ba9073c100c4984a" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", "cfg-if", "futures", "indexmap 2.0.0", @@ -1804,6 +1866,16 @@ dependencies = [ "serde", ] +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", + "simd-adler32", +] + [[package]] name = "mio" version = "0.8.8" @@ -1856,6 +1928,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.15" @@ -2046,6 +2129,19 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "png" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" +dependencies = [ + "bitflags", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -2119,6 +2215,23 @@ dependencies = [ "yansi", ] +[[package]] +name = "qrcode-generator" +version = "4.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc713c23eb7e1a5f18b84e72be88b82a617ee25783a524a38f0caa4c986b2d76" +dependencies = [ + "html-escape", + "image", + "qrcodegen", +] + +[[package]] +name = "qrcodegen" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4339fc7a1021c9c1621d87f5e3505f2805c8c105420ba2f2a4df86814590c142" + [[package]] name = "quote" version = "1.0.28" @@ -2223,7 +2336,7 @@ version = "0.11.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", "bytes", "encoding_rs", "futures-core", @@ -2357,7 +2470,7 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" dependencies = [ - "base64 0.21.2", + "base64 0.21.3", ] [[package]] @@ -2635,6 +2748,12 @@ dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + [[package]] name = "slab" version = "0.4.8" diff --git a/Cargo.toml b/Cargo.toml index 07e6960..93e20cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ opt-level = 'z' [dependencies] async-trait = "0.1.68" anyhow = "1.0.71" +base64 = "0.21.3" fedimint-client = { git = "https://github.com/fedimint/fedimint", rev = "183bff69f030b89f2cd78dbb91bdecf895048e3e" } fedimint-core = { git = "https://github.com/fedimint/fedimint", rev = "183bff69f030b89f2cd78dbb91bdecf895048e3e" } fedimint-wallet-client = { git = "https://github.com/fedimint/fedimint", rev = "183bff69f030b89f2cd78dbb91bdecf895048e3e" } @@ -22,6 +23,7 @@ leptos = { version = "0.4.8", features = ["csr"] } leptos-qr-scanner = { git = "https://github.com/elsirion/leptos-qr-scanner", rev = "75e976e99d9c1ed64921081a23f7da823d2a0b6d" } leptos_meta = { version = "0.4.8", features = ["csr"] } lightning-invoice = { version = "0.21.0", features = [ "serde" ] } +qrcode-generator = "4.1.8" console_error_panic_hook = "0.1.7" tracing = "0.1.37" diff --git a/src/components/mod.rs b/src/components/mod.rs index 043cfa2..7f7a416 100644 --- a/src/components/mod.rs +++ b/src/components/mod.rs @@ -6,6 +6,7 @@ pub mod ln_receive_form; pub mod loader_icon; pub mod logo; pub mod logo_fedimint; +pub mod qrcode; pub mod receive; pub mod receive_ln; pub mod send; diff --git a/src/components/qrcode.rs b/src/components/qrcode.rs new file mode 100644 index 0000000..0374f71 --- /dev/null +++ b/src/components/qrcode.rs @@ -0,0 +1,31 @@ +use leptos::*; + +#[component] +pub fn QrCode( + cx: Scope, + #[prop(into)] data: Signal, + #[prop(optional, into)] qr_image_size: Option, + #[prop(optional, into)] class: Option, +) -> impl IntoView { + let qr_image_size = qr_image_size.unwrap_or(1024); + let qr_data_url = move || { + let png_bytes = qrcode_generator::to_png_to_vec_from_str( + &data.get(), + qrcode_generator::QrCodeEcc::Medium, + qr_image_size, + ) + .expect("Failed to generate QR code"); + let png_base64 = base64::display::Base64Display::new( + &png_bytes, + &base64::engine::general_purpose::STANDARD, + ); + format!("data:image/png;base64,{png_base64}") + }; + + view! { cx, + + } +} diff --git a/src/components/receive_ln.rs b/src/components/receive_ln.rs index 5de2ae9..f5b8acc 100644 --- a/src/components/receive_ln.rs +++ b/src/components/receive_ln.rs @@ -1,4 +1,6 @@ use crate::components::ln_receive_form::LnReceiveForm; +use crate::components::loader_icon::LoaderIcon; +use crate::components::qrcode::QrCode; use crate::context::ClientContext; use crate::utils::empty_view; use leptos::*; @@ -28,16 +30,39 @@ pub fn ReceiveLn(cx: Scope) -> impl IntoView { submit_action.dispatch((amount_msat, description)); } /> - { move || { - if let Some(invoice) = submit_action.value().get() { - view!(cx, -
- {invoice} -
- ).into_view(cx) - } else { - empty_view().into_view(cx) - } - }} +
+ } + > + { move || { + match submit_action.value().get() { + Some(Ok(invoice)) => { + let qr_invoice_upper = format!("lightning:{invoice}").to_ascii_uppercase(); + view!{ cx, +
+ {&invoice} + +
+ }.into_view(cx) + } + Some(Err(e)) => { + view!{ cx, + + }.into_view(cx) + } + None => { + empty_view().into_view(cx) + } + } + }} +
+
} }