-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #54 from input-output-hk/iapyx_get_address_from_qr
Iapyx get address from qr
- Loading branch information
Showing
5 changed files
with
260 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
use crate::PinReadMode; | ||
use crate::QrReader; | ||
|
||
use crate::cli::args::qr::IapyxQrCommandError; | ||
use chain_addr::AddressReadable; | ||
use chain_addr::{Discrimination, Kind}; | ||
use chain_core::mempack::ReadBuf; | ||
use chain_core::mempack::Readable; | ||
use chain_core::property::Deserialize; | ||
use chain_crypto::Ed25519Extended; | ||
use chain_crypto::SecretKey; | ||
use chain_impl_mockchain::block::Block; | ||
use jormungandr_lib::interfaces::{Block0Configuration, Initial}; | ||
use std::convert::TryInto; | ||
use std::io::BufReader; | ||
use std::path::Path; | ||
use std::path::PathBuf; | ||
use structopt::StructOpt; | ||
use url::Url; | ||
#[derive(StructOpt, Debug)] | ||
pub struct GetAddressFromQRCommand { | ||
#[structopt(long = "qr")] | ||
pub qr: PathBuf, | ||
|
||
#[structopt(short = "p", long = "pin", default_value = "1234")] | ||
pub pin: String, | ||
|
||
#[structopt(short = "f", long = "read-from-filename")] | ||
pub read_pin_from_filename: bool, | ||
|
||
// if true then testing discrimination would be used | ||
#[structopt(long = "testing")] | ||
pub testing: bool, | ||
|
||
// if true then testing discrimination would be used | ||
#[structopt(long = "prefix", default_value = "ca")] | ||
pub prefix: String, | ||
|
||
#[structopt(long = "block0")] | ||
pub block0: Option<String>, | ||
} | ||
|
||
impl GetAddressFromQRCommand { | ||
pub fn exec(&self) -> Result<(), IapyxQrCommandError> { | ||
println!("Decoding qr from file: {:?}...", self.qr); | ||
let pin_read_mode = PinReadMode::new(self.read_pin_from_filename, &self.pin); | ||
let pin_reader = QrReader::new(pin_read_mode); | ||
let secret = pin_reader.read_qr(&self.qr)?; | ||
let bin: [u8; 64] = secret.leak_secret().as_ref().try_into().unwrap(); | ||
let secret_key: SecretKey<Ed25519Extended> = SecretKey::from_binary(&bin).unwrap(); | ||
let kind = Kind::Single(secret_key.to_public()); | ||
let address = chain_addr::Address(Discrimination::Production, kind); | ||
|
||
if let Some(block0_path) = &self.block0 { | ||
println!("Reading block0 from location {:?}...", block0_path); | ||
|
||
let block = { | ||
if Path::new(block0_path).exists() { | ||
let reader = std::fs::OpenOptions::new() | ||
.create(false) | ||
.write(false) | ||
.read(true) | ||
.append(false) | ||
.open(block0_path)?; | ||
let reader = BufReader::new(reader); | ||
Block::deserialize(reader)? | ||
} else if Url::parse(block0_path).is_ok() { | ||
let response = reqwest::blocking::get(block0_path)?; | ||
let block0_bytes = response.bytes()?.to_vec(); | ||
Block::read(&mut ReadBuf::from(&block0_bytes))? | ||
} else { | ||
panic!(" block0 should be either path to filesystem or url "); | ||
} | ||
}; | ||
let genesis = Block0Configuration::from_block(&block)?; | ||
|
||
for initial in genesis.initial.iter() { | ||
if let Initial::Fund(initial_utxos) = initial { | ||
if let Some(entry) = initial_utxos.iter().find(|x| { | ||
let entry_address: chain_addr::Address = x.address.clone().into(); | ||
entry_address == address | ||
}) { | ||
println!( | ||
"Address corresponding to input qr found in block0: '{}' with value: '{}'", | ||
AddressReadable::from_address(&self.prefix, &entry.address.clone().into()).to_string(),entry.value | ||
); | ||
return Ok(()); | ||
} | ||
} | ||
} | ||
println!("Address corresponding to input qr not found in block0"); | ||
} else { | ||
println!( | ||
"Address: {}", | ||
AddressReadable::from_address(&self.prefix, &address).to_string() | ||
); | ||
} | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,59 +1,44 @@ | ||
use crate::PinReadMode; | ||
use crate::QrReader; | ||
use crate::Wallet; | ||
use std::convert::TryInto; | ||
use std::path::PathBuf; | ||
mod address; | ||
mod secret; | ||
mod verify; | ||
use crate::cli::args::qr::secret::GetSecretFromQRCommand; | ||
use address::GetAddressFromQRCommand; | ||
use jormungandr_lib::interfaces::Block0ConfigurationError; | ||
use structopt::StructOpt; | ||
use thiserror::Error; | ||
#[derive(Error, Debug)] | ||
pub enum IapyxQrCommandError { | ||
#[error("proxy error")] | ||
ProxyError(#[from] crate::backend::ProxyServerError), | ||
} | ||
use verify::VerifyQrCommand; | ||
|
||
#[derive(StructOpt, Debug)] | ||
pub struct IapyxQrCommand { | ||
#[structopt(short = "q", long = "qr-codes-folder")] | ||
pub qr_codes_folder: PathBuf, | ||
|
||
#[structopt(short = "g", long = "global-pin", default_value = "1234")] | ||
pub global_pin: String, | ||
|
||
#[structopt(short = "f", long = "read-from-filename")] | ||
pub read_pin_from_filename: bool, | ||
|
||
#[structopt(short = "s", long = "stop-at-fail")] | ||
pub stop_at_fail: bool, | ||
pub enum IapyxQrCommand { | ||
Verify(VerifyQrCommand), | ||
CheckAddress(GetAddressFromQRCommand), | ||
Secret(GetSecretFromQRCommand), | ||
} | ||
|
||
impl IapyxQrCommand { | ||
pub fn exec(&self) -> Result<(), IapyxQrCommandError> { | ||
println!("Decoding..."); | ||
|
||
let pin_read_mode = PinReadMode::new(self.read_pin_from_filename, &self.global_pin); | ||
|
||
let qr_codes: Vec<PathBuf> = std::fs::read_dir(&self.qr_codes_folder) | ||
.unwrap() | ||
.into_iter() | ||
.map(|x| x.unwrap().path()) | ||
.collect(); | ||
|
||
let pin_reader = QrReader::new(pin_read_mode); | ||
let secrets = pin_reader.read_qrs(&qr_codes, self.stop_at_fail); | ||
let wallets: Vec<Wallet> = secrets | ||
.into_iter() | ||
.map(|secret| { | ||
Wallet::recover_from_utxo(secret.leak_secret().as_ref().try_into().unwrap()) | ||
.unwrap() | ||
}) | ||
.collect(); | ||
|
||
println!( | ||
"{} QR read. {} succesfull, {} failed", | ||
qr_codes.len(), | ||
wallets.len(), | ||
qr_codes.len() - wallets.len() | ||
); | ||
Ok(()) | ||
match self { | ||
Self::Verify(verify) => verify.exec(), | ||
Self::CheckAddress(check_address) => check_address.exec(), | ||
Self::Secret(secret) => secret.exec(), | ||
} | ||
} | ||
} | ||
|
||
#[derive(Error, Debug)] | ||
pub enum IapyxQrCommandError { | ||
#[error("proxy error")] | ||
ProxyError(#[from] crate::backend::ProxyServerError), | ||
#[error("pin error")] | ||
PinError(#[from] crate::qr::PinReadError), | ||
#[error("reqwest error")] | ||
IapyxQrCommandError(#[from] reqwest::Error), | ||
#[error("block0 parse error")] | ||
Block0ParseError(#[from] Block0ConfigurationError), | ||
#[error("io error")] | ||
IoError(#[from] std::io::Error), | ||
#[error("read error")] | ||
ReadError(#[from] chain_core::mempack::ReadError), | ||
#[error("bech32 error")] | ||
Bech32Error(#[from] bech32::Error), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
use crate::PinReadMode; | ||
use crate::QrReader; | ||
|
||
use crate::cli::args::qr::IapyxQrCommandError; | ||
use bech32::ToBase32; | ||
use chain_crypto::AsymmetricKey; | ||
use chain_crypto::Ed25519Extended; | ||
use chain_crypto::SecretKey; | ||
use std::convert::TryInto; | ||
use std::path::PathBuf; | ||
use structopt::StructOpt; | ||
|
||
#[derive(StructOpt, Debug)] | ||
pub struct GetSecretFromQRCommand { | ||
#[structopt(long = "qr")] | ||
pub qr: PathBuf, | ||
|
||
#[structopt(short = "p", long = "pin", default_value = "1234")] | ||
pub pin: String, | ||
|
||
#[structopt(short = "f", long = "read-from-filename")] | ||
pub read_pin_from_filename: bool, | ||
} | ||
|
||
impl GetSecretFromQRCommand { | ||
pub fn exec(&self) -> Result<(), IapyxQrCommandError> { | ||
println!("Decoding qr from file: {:?}...", self.qr); | ||
let pin_read_mode = PinReadMode::new(self.read_pin_from_filename, &self.pin); | ||
let pin_reader = QrReader::new(pin_read_mode); | ||
let secret = pin_reader.read_qr(&self.qr)?; | ||
let bin: [u8; 64] = secret.leak_secret().as_ref().try_into().unwrap(); | ||
let secret_key: SecretKey<Ed25519Extended> = SecretKey::from_binary(&bin).unwrap(); | ||
let hrp = Ed25519Extended::SECRET_BECH32_HRP; | ||
println!( | ||
"{}", | ||
bech32::encode(hrp, secret_key.leak_secret().to_base32())? | ||
); | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
use crate::cli::args::qr::IapyxQrCommandError; | ||
use crate::PinReadMode; | ||
use crate::QrReader; | ||
use crate::Wallet; | ||
use chain_addr::AddressReadable; | ||
use chain_addr::{Discrimination, Kind}; | ||
use chain_crypto::Ed25519Extended; | ||
use chain_crypto::SecretKey; | ||
use std::convert::TryInto; | ||
use std::path::PathBuf; | ||
use structopt::StructOpt; | ||
|
||
#[derive(StructOpt, Debug)] | ||
pub struct VerifyQrCommand { | ||
#[structopt(short = "q", long = "qr-codes-folder")] | ||
pub qr_codes_folder: PathBuf, | ||
|
||
#[structopt(short = "g", long = "global-pin", default_value = "1234")] | ||
pub global_pin: String, | ||
|
||
#[structopt(short = "f", long = "read-from-filename")] | ||
pub read_pin_from_filename: bool, | ||
|
||
#[structopt(short = "s", long = "stop-at-fail")] | ||
pub stop_at_fail: bool, | ||
} | ||
|
||
impl VerifyQrCommand { | ||
pub fn exec(&self) -> Result<(), IapyxQrCommandError> { | ||
println!("Decoding..."); | ||
|
||
let pin_read_mode = PinReadMode::new(self.read_pin_from_filename, &self.global_pin); | ||
|
||
let qr_codes: Vec<PathBuf> = std::fs::read_dir(&self.qr_codes_folder) | ||
.unwrap() | ||
.into_iter() | ||
.map(|x| x.unwrap().path()) | ||
.collect(); | ||
|
||
let pin_reader = QrReader::new(pin_read_mode); | ||
let secrets = pin_reader.read_qrs(&qr_codes, self.stop_at_fail); | ||
let wallets: Vec<Wallet> = secrets | ||
.into_iter() | ||
.map(|secret| { | ||
let bin: [u8; 64] = secret.leak_secret().as_ref().try_into().unwrap(); | ||
|
||
let secret_key: SecretKey<Ed25519Extended> = SecretKey::from_binary(&bin).unwrap(); | ||
let kind = Kind::Single(secret_key.to_public()); | ||
let address = chain_addr::Address(Discrimination::Production, kind); | ||
println!( | ||
"{}", | ||
AddressReadable::from_address("ca", &address).to_string() | ||
); | ||
|
||
Wallet::recover_from_utxo(&bin).unwrap() | ||
}) | ||
.collect(); | ||
|
||
println!( | ||
"{} QR read. {} succesfull, {} failed", | ||
qr_codes.len(), | ||
wallets.len(), | ||
qr_codes.len() - wallets.len() | ||
); | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters