Print the Bitcoin address to the terminal as a QR code

This commit is contained in:
xscd 2021-05-30 14:53:43 +03:00
parent d5d0dda6e7
commit 03857ca835
4 changed files with 86 additions and 1 deletions

View File

@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
- Printing the deposit address to the terminal as a QR code.
To not break automated scripts or integrations with other software, this behaviour is disabled if `--json` is passed to the application.
## [0.7.0] - 2021-05-28
### Fixed

56
Cargo.lock generated
View File

@ -486,6 +486,12 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
[[package]]
name = "bytemuck"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bed57e2090563b83ba8f83366628ce535a7584c9afa4c9fc0612a03925c6df58"
[[package]]
name = "byteorder"
version = "1.4.3"
@ -578,6 +584,12 @@ dependencies = [
"zeroize",
]
[[package]]
name = "checked_int_cast"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17cc5e6b5ab06331c33589842070416baa137e8b0eb912b008cfd4a78ada7919"
[[package]]
name = "chrono"
version = "0.4.19"
@ -624,6 +636,12 @@ dependencies = [
"bitflags",
]
[[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.11.0"
@ -1560,6 +1578,20 @@ dependencies = [
"libc",
]
[[package]]
name = "image"
version = "0.23.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1"
dependencies = [
"bytemuck",
"byteorder",
"color_quant",
"num-iter",
"num-rational 0.3.2",
"num-traits",
]
[[package]]
name = "indexmap"
version = "1.6.2"
@ -2372,7 +2404,7 @@ dependencies = [
"num-complex",
"num-integer",
"num-iter",
"num-rational",
"num-rational 0.1.42",
"num-traits",
]
@ -2431,6 +2463,17 @@ dependencies = [
"rustc-serialize",
]
[[package]]
name = "num-rational"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07"
dependencies = [
"autocfg 1.0.1",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.14"
@ -2833,6 +2876,16 @@ dependencies = [
"prost",
]
[[package]]
name = "qrcode"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16d2f1455f3630c6e5107b4f2b94e74d76dea80736de0981fd27644216cff57f"
dependencies = [
"checked_int_cast",
"image",
]
[[package]]
name = "quick-error"
version = "1.2.3"
@ -3913,6 +3966,7 @@ dependencies = [
"port_check",
"prettytable-rs",
"proptest",
"qrcode",
"rand 0.8.3",
"rand_chacha 0.3.0",
"reqwest",

View File

@ -37,6 +37,7 @@ monero-rpc = { path = "../monero-rpc" }
pem = "0.8"
prettytable-rs = "0.8"
proptest = "1"
qrcode = "0.12"
rand = "0.8"
rand_chacha = "0.3"
reqwest = { version = "0.11", features = [ "rustls-tls", "stream", "socks" ], default-features = false }

View File

@ -14,6 +14,8 @@
use anyhow::{bail, Context, Result};
use prettytable::{row, Table};
use qrcode::render::unicode;
use qrcode::QrCode;
use std::cmp::min;
use std::env;
use std::future::Future;
@ -101,6 +103,7 @@ async fn main() -> Result<()> {
let max_givable = || bitcoin_wallet.max_giveable(TxLock::script_size());
let (amount, fees) = determine_btc_to_swap(
json,
event_loop_handle.request_quote(),
bitcoin_wallet.new_address(),
|| bitcoin_wallet.balance(),
@ -325,7 +328,18 @@ async fn init_monero_wallet(
Ok((monero_wallet, monero_wallet_rpc_process))
}
fn qr_code(value: &impl ToString) -> Result<String> {
let code = QrCode::new(value.to_string())?;
let qr_code = code
.render::<unicode::Dense1x2>()
.dark_color(unicode::Dense1x2::Light)
.light_color(unicode::Dense1x2::Dark)
.build();
Ok(qr_code)
}
async fn determine_btc_to_swap<FB, TB, FMG, TMG, FS, TS>(
json: bool,
bid_quote: impl Future<Output = Result<BidQuote>>,
get_new_address: impl Future<Output = Result<bitcoin::Address>>,
balance: FB,
@ -358,6 +372,10 @@ where
let minimum_amount = bid_quote.min_quantity;
let maximum_amount = bid_quote.max_quantity;
if !json {
eprintln!("{}", qr_code(&deposit_address)?);
}
info!(
%deposit_address,
%current_maximum_giveable,
@ -449,6 +467,7 @@ mod tests {
])));
let (amount, fees) = determine_btc_to_swap(
true,
async { Ok(quote_with_max(0.01)) },
get_dummy_address(),
|| async { Ok(Amount::from_btc(0.001)?) },
@ -475,6 +494,7 @@ mod tests {
])));
let (amount, fees) = determine_btc_to_swap(
true,
async { Ok(quote_with_max(0.01)) },
get_dummy_address(),
|| async { Ok(Amount::from_btc(0.1001)?) },
@ -502,6 +522,7 @@ mod tests {
])));
let (amount, fees) = determine_btc_to_swap(
true,
async { Ok(quote_with_max(0.01)) },
async { panic!("should not request new address when initial balance is > 0") },
|| async { Ok(Amount::from_btc(0.005)?) },
@ -529,6 +550,7 @@ mod tests {
])));
let (amount, fees) = determine_btc_to_swap(
true,
async { Ok(quote_with_max(0.01)) },
async { panic!("should not request new address when initial balance is > 0") },
|| async { Ok(Amount::from_btc(0.1001)?) },
@ -556,6 +578,7 @@ mod tests {
])));
let (amount, fees) = determine_btc_to_swap(
true,
async { Ok(quote_with_min(0.01)) },
get_dummy_address(),
|| async { Ok(Amount::from_btc(0.0101)?) },
@ -583,6 +606,7 @@ mod tests {
])));
let (amount, fees) = determine_btc_to_swap(
true,
async { Ok(quote_with_min(0.01)) },
get_dummy_address(),
|| async { Ok(Amount::from_btc(0.0101)?) },
@ -615,6 +639,7 @@ mod tests {
let error = tokio::time::timeout(
Duration::from_secs(1),
determine_btc_to_swap(
true,
async { Ok(quote_with_min(0.1)) },
get_dummy_address(),
|| async { Ok(Amount::from_btc(0.0101)?) },