diff --git a/qr_code_crypto/.gitignore b/qr_code_crypto/.gitignore new file mode 100644 index 0000000..6985cf1 --- /dev/null +++ b/qr_code_crypto/.gitignore @@ -0,0 +1,14 @@ +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb diff --git a/qr_code_crypto/Cargo.toml b/qr_code_crypto/Cargo.toml new file mode 100644 index 0000000..956c76b --- /dev/null +++ b/qr_code_crypto/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "qr_code_crypto" +version = "0.1.0" +edition = "2024" + +[dependencies] +qrcode = { version = "0.14.1" } +rust_decimal = "1.39.0" diff --git a/qr_code_crypto/src/lib.rs b/qr_code_crypto/src/lib.rs new file mode 100644 index 0000000..bb89276 --- /dev/null +++ b/qr_code_crypto/src/lib.rs @@ -0,0 +1,45 @@ +pub trait CryptoInvoice { + fn new(address: &str) -> Self; + fn set_query_part(self, name: &str, value: &str) -> Self; + fn validate(self) -> bool; + fn address(self) -> String; + fn uri(self) -> String; +} + +// See: https://github.com/monero-project/monero/wiki/URI-Formatting +#[derive(Clone)] +pub struct MoneroInvoice { + pub address: String, + pub query: String, +} + +impl CryptoInvoice for MoneroInvoice { + fn new(address: &str) -> Self { + MoneroInvoice { + address: address.to_string(), + query: String::new(), + } + } + + fn set_query_part(mut self, name: &str, value: &str) -> Self { + if self.query.is_empty() { + self.query.push('?'); + } + if self.query.len() > 1 { + self.query.push('&'); + } + self.query + .push_str(&format!("{}={}", name, value.replace(' ', "%20"))); + self + } + + fn validate(self) -> bool { + unimplemented!(); + } + fn address(self) -> String { + self.address + } + fn uri(self) -> String { + format!("monero:{}{}", self.address, self.query) + } +} diff --git a/qr_code_crypto/src/main.rs b/qr_code_crypto/src/main.rs new file mode 100644 index 0000000..c9132fd --- /dev/null +++ b/qr_code_crypto/src/main.rs @@ -0,0 +1,21 @@ +use qr_code_crypto::{CryptoInvoice, MoneroInvoice}; +use qrcode::QrCode; +use qrcode::render::unicode; +use rust_decimal::prelude::*; + +fn create_and_print_qr_invoice(invoice: impl CryptoInvoice) { + let code = QrCode::new(invoice.uri()).unwrap(); + let image = code + .render::() + .dark_color(unicode::Dense1x2::Light) + .light_color(unicode::Dense1x2::Dark) + .build(); + println!("{image}"); + //println!("{}", invoice.uri()); +} + +fn main() { + let monero_donation_adress = "888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H".to_string(); + let monero_invoice = MoneroInvoice::new(&monero_donation_adress); + create_and_print_qr_invoice(monero_invoice); +}