mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-10-01 01:45:40 -04:00
Make config
argument global
The `config` argument apply to all commands. It is now optional and needs to be passed before a command. E.g. `cli --config ./config.toml history`
This commit is contained in:
parent
83dcf4ba3c
commit
8fada42074
@ -15,20 +15,21 @@
|
||||
use anyhow::{Context, Result};
|
||||
use log::LevelFilter;
|
||||
use prettytable::{row, Table};
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
use std::sync::Arc;
|
||||
use structopt::StructOpt;
|
||||
use swap::{
|
||||
bitcoin,
|
||||
cli::{
|
||||
command::{Arguments, Cancel, Command, Refund, Resume},
|
||||
config::{
|
||||
initial_setup, query_user_for_initial_testnet_config, read_config, ConfigNotInitialized,
|
||||
initial_setup, query_user_for_initial_testnet_config, read_config, Config,
|
||||
ConfigNotInitialized,
|
||||
},
|
||||
},
|
||||
database::Database,
|
||||
execution_params,
|
||||
execution_params::GetExecutionParams,
|
||||
fs::{default_config_path, default_data_dir},
|
||||
fs::default_config_path,
|
||||
monero,
|
||||
monero::{CreateWallet, OpenWallet},
|
||||
protocol::{
|
||||
@ -53,19 +54,30 @@ async fn main() -> Result<()> {
|
||||
|
||||
let opt = Arguments::from_args();
|
||||
|
||||
let data_dir = if let Some(data_dir) = opt.data_dir {
|
||||
data_dir
|
||||
let config_path = if let Some(config_path) = opt.config {
|
||||
config_path
|
||||
} else {
|
||||
default_data_dir().context("unable to determine default data path")?
|
||||
default_config_path()?
|
||||
};
|
||||
|
||||
let config = match read_config(config_path.clone())? {
|
||||
Ok(config) => config,
|
||||
Err(ConfigNotInitialized {}) => {
|
||||
initial_setup(config_path.clone(), query_user_for_initial_testnet_config)?;
|
||||
read_config(config_path)?.expect("after initial setup config can be read")
|
||||
}
|
||||
};
|
||||
|
||||
info!(
|
||||
"Database and Seed will be stored in directory: {}",
|
||||
data_dir.display()
|
||||
config.data.dir.display()
|
||||
);
|
||||
|
||||
let db_path = data_dir.join("database");
|
||||
let seed = Seed::from_file_or_generate(&data_dir).expect("Could not retrieve/initialize seed");
|
||||
let db = Database::open(config.data.dir.join("database").as_path())
|
||||
.context("Could not open database")?;
|
||||
|
||||
let seed =
|
||||
Seed::from_file_or_generate(&config.data.dir).expect("Could not retrieve/initialize seed");
|
||||
|
||||
// hardcode to testnet/stagenet
|
||||
let bitcoin_network = bitcoin::Network::Testnet;
|
||||
@ -78,7 +90,6 @@ async fn main() -> Result<()> {
|
||||
alice_addr,
|
||||
send_bitcoin,
|
||||
receive_monero,
|
||||
config,
|
||||
} => {
|
||||
let swap_amounts = SwapAmounts {
|
||||
btc: send_bitcoin,
|
||||
@ -86,7 +97,7 @@ async fn main() -> Result<()> {
|
||||
};
|
||||
|
||||
let (bitcoin_wallet, monero_wallet) =
|
||||
init_wallets(config.path, bitcoin_network, monero_network).await?;
|
||||
init_wallets(config, bitcoin_network, monero_network).await?;
|
||||
|
||||
let swap_id = Uuid::new_v4();
|
||||
|
||||
@ -97,7 +108,7 @@ async fn main() -> Result<()> {
|
||||
|
||||
let bob_factory = Builder::new(
|
||||
seed,
|
||||
db_path,
|
||||
db,
|
||||
swap_id,
|
||||
Arc::new(bitcoin_wallet),
|
||||
Arc::new(monero_wallet),
|
||||
@ -115,8 +126,6 @@ async fn main() -> Result<()> {
|
||||
|
||||
table.add_row(row!["SWAP ID", "STATE"]);
|
||||
|
||||
let db = Database::open(db_path.as_path()).context("Could not open database")?;
|
||||
|
||||
for (swap_id, state) in db.all()? {
|
||||
table.add_row(row![swap_id, state]);
|
||||
}
|
||||
@ -128,14 +137,13 @@ async fn main() -> Result<()> {
|
||||
swap_id,
|
||||
alice_peer_id,
|
||||
alice_addr,
|
||||
config,
|
||||
}) => {
|
||||
let (bitcoin_wallet, monero_wallet) =
|
||||
init_wallets(config.path, bitcoin_network, monero_network).await?;
|
||||
init_wallets(config, bitcoin_network, monero_network).await?;
|
||||
|
||||
let bob_factory = Builder::new(
|
||||
seed,
|
||||
db_path,
|
||||
db,
|
||||
swap_id,
|
||||
Arc::new(bitcoin_wallet),
|
||||
Arc::new(monero_wallet),
|
||||
@ -152,16 +160,15 @@ async fn main() -> Result<()> {
|
||||
swap_id,
|
||||
alice_peer_id,
|
||||
alice_addr,
|
||||
config,
|
||||
force,
|
||||
}) => {
|
||||
// TODO: Optimization: Only init the Bitcoin wallet, Monero wallet unnecessary
|
||||
let (bitcoin_wallet, monero_wallet) =
|
||||
init_wallets(config.path, bitcoin_network, monero_network).await?;
|
||||
init_wallets(config, bitcoin_network, monero_network).await?;
|
||||
|
||||
let bob_factory = Builder::new(
|
||||
seed,
|
||||
db_path,
|
||||
db,
|
||||
swap_id,
|
||||
Arc::new(bitcoin_wallet),
|
||||
Arc::new(monero_wallet),
|
||||
@ -198,16 +205,15 @@ async fn main() -> Result<()> {
|
||||
swap_id,
|
||||
alice_peer_id,
|
||||
alice_addr,
|
||||
config,
|
||||
force,
|
||||
}) => {
|
||||
let (bitcoin_wallet, monero_wallet) =
|
||||
init_wallets(config.path, bitcoin_network, monero_network).await?;
|
||||
init_wallets(config, bitcoin_network, monero_network).await?;
|
||||
|
||||
// TODO: Optimize to only use the Bitcoin wallet, Monero wallet is unnecessary
|
||||
let bob_factory = Builder::new(
|
||||
seed,
|
||||
db_path,
|
||||
db,
|
||||
swap_id,
|
||||
Arc::new(bitcoin_wallet),
|
||||
Arc::new(monero_wallet),
|
||||
@ -234,24 +240,10 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
|
||||
async fn init_wallets(
|
||||
config_path: Option<PathBuf>,
|
||||
config: Config,
|
||||
bitcoin_network: bitcoin::Network,
|
||||
monero_network: monero::Network,
|
||||
) -> Result<(bitcoin::Wallet, monero::Wallet)> {
|
||||
let config_path = if let Some(config_path) = config_path {
|
||||
config_path
|
||||
} else {
|
||||
default_config_path()?
|
||||
};
|
||||
|
||||
let config = match read_config(config_path.clone())? {
|
||||
Ok(config) => config,
|
||||
Err(ConfigNotInitialized {}) => {
|
||||
initial_setup(config_path.clone(), query_user_for_initial_testnet_config)?;
|
||||
read_config(config_path)?.expect("after initial setup config can be read")
|
||||
}
|
||||
};
|
||||
|
||||
let bitcoin_wallet = bitcoin::Wallet::new(
|
||||
config.bitcoin.wallet_name.as_str(),
|
||||
config.bitcoin.bitcoind_url,
|
||||
|
@ -6,11 +6,11 @@ use uuid::Uuid;
|
||||
#[derive(structopt::StructOpt, Debug)]
|
||||
pub struct Arguments {
|
||||
#[structopt(
|
||||
long = "data-dir",
|
||||
help = "Provide a custom path to the data directory.",
|
||||
long = "config",
|
||||
help = "Provide a custom path to the configuration file. The configuration file must be a toml file.",
|
||||
parse(from_os_str)
|
||||
)]
|
||||
pub data_dir: Option<PathBuf>,
|
||||
pub config: Option<PathBuf>,
|
||||
|
||||
#[structopt(subcommand)]
|
||||
pub cmd: Command,
|
||||
@ -31,9 +31,6 @@ pub enum Command {
|
||||
|
||||
#[structopt(long = "receive-xmr", help = "Monero amount as floating point nr without denomination (e.g. 125.1)", parse(try_from_str = parse_xmr))]
|
||||
receive_monero: monero::Amount,
|
||||
|
||||
#[structopt(flatten)]
|
||||
config: Config,
|
||||
},
|
||||
History,
|
||||
Resume(Resume),
|
||||
@ -52,9 +49,6 @@ pub enum Resume {
|
||||
|
||||
#[structopt(long = "counterpart-addr")]
|
||||
alice_addr: Multiaddr,
|
||||
|
||||
#[structopt(flatten)]
|
||||
config: Config,
|
||||
},
|
||||
}
|
||||
|
||||
@ -71,9 +65,6 @@ pub enum Cancel {
|
||||
#[structopt(long = "counterpart-addr")]
|
||||
alice_addr: Multiaddr,
|
||||
|
||||
#[structopt(flatten)]
|
||||
config: Config,
|
||||
|
||||
#[structopt(short, long)]
|
||||
force: bool,
|
||||
},
|
||||
@ -92,24 +83,11 @@ pub enum Refund {
|
||||
#[structopt(long = "counterpart-addr")]
|
||||
alice_addr: Multiaddr,
|
||||
|
||||
#[structopt(flatten)]
|
||||
config: Config,
|
||||
|
||||
#[structopt(short, long)]
|
||||
force: bool,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(structopt::StructOpt, Debug)]
|
||||
pub struct Config {
|
||||
#[structopt(
|
||||
long = "config",
|
||||
help = "Provide a custom path to the configuration file. The configuration file must be a toml file.",
|
||||
parse(from_os_str)
|
||||
)]
|
||||
pub path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
fn parse_btc(str: &str) -> anyhow::Result<bitcoin::Amount> {
|
||||
let amount = bitcoin::Amount::from_str_in(str, ::bitcoin::Denomination::Bitcoin)?;
|
||||
Ok(amount)
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::fs::ensure_directory_exists;
|
||||
use crate::fs::{default_data_dir, ensure_directory_exists};
|
||||
use anyhow::{Context, Result};
|
||||
use config::ConfigError;
|
||||
use dialoguer::{theme::ColorfulTheme, Input};
|
||||
@ -16,6 +16,7 @@ const DEFAULT_MONERO_WALLET_RPC_TESTNET_URL: &str = "http://127.0.0.1:38083/json
|
||||
|
||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, PartialEq)]
|
||||
pub struct Config {
|
||||
pub data: Data,
|
||||
pub bitcoin: Bitcoin,
|
||||
pub monero: Monero,
|
||||
}
|
||||
@ -33,6 +34,12 @@ impl Config {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Data {
|
||||
pub dir: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Bitcoin {
|
||||
@ -86,6 +93,18 @@ where
|
||||
|
||||
pub fn query_user_for_initial_testnet_config() -> Result<Config> {
|
||||
println!();
|
||||
let data_dir = Input::with_theme(&ColorfulTheme::default())
|
||||
.with_prompt("Enter data directory for the swap CLI or hit return to use default")
|
||||
.default(
|
||||
default_data_dir()
|
||||
.context("No default data dir value for this system")?
|
||||
.to_str()
|
||||
.context("Unsupported characters in default path")?
|
||||
.to_string(),
|
||||
)
|
||||
.interact_text()?;
|
||||
let data_dir = data_dir.as_str().parse()?;
|
||||
|
||||
let bitcoind_url = Input::with_theme(&ColorfulTheme::default())
|
||||
.with_prompt("Enter Bitcoind URL (including username and password if applicable) or hit return to use default")
|
||||
.default(DEFAULT_BITCOIND_TESTNET_URL.to_owned())
|
||||
@ -104,6 +123,7 @@ pub fn query_user_for_initial_testnet_config() -> Result<Config> {
|
||||
println!();
|
||||
|
||||
Ok(Config {
|
||||
data: Data { dir: data_dir },
|
||||
bitcoin: Bitcoin {
|
||||
bitcoind_url,
|
||||
wallet_name: bitcoin_wallet_name,
|
||||
@ -126,6 +146,9 @@ mod tests {
|
||||
let config_path = Path::join(&temp_dir, "config.toml");
|
||||
|
||||
let expected = Config {
|
||||
data: Data {
|
||||
dir: Default::default(),
|
||||
},
|
||||
bitcoin: Bitcoin {
|
||||
bitcoind_url: Url::from_str("http://127.0.0.1:18332").unwrap(),
|
||||
wallet_name: "alice".to_string(),
|
||||
|
@ -15,7 +15,7 @@ use crate::{
|
||||
use anyhow::{bail, Error, Result};
|
||||
use libp2p::{core::Multiaddr, identity::Keypair, NetworkBehaviour, PeerId};
|
||||
use rand::rngs::OsRng;
|
||||
use std::{path::PathBuf, sync::Arc};
|
||||
use std::sync::Arc;
|
||||
use tracing::{debug, info};
|
||||
use uuid::Uuid;
|
||||
|
||||
@ -55,7 +55,7 @@ pub struct Builder {
|
||||
swap_id: Uuid,
|
||||
identity: Keypair,
|
||||
peer_id: PeerId,
|
||||
db_path: PathBuf,
|
||||
db: Database,
|
||||
|
||||
alice_address: Multiaddr,
|
||||
alice_peer_id: PeerId,
|
||||
@ -76,7 +76,7 @@ impl Builder {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn new(
|
||||
seed: Seed,
|
||||
db_path: PathBuf,
|
||||
db: Database,
|
||||
swap_id: Uuid,
|
||||
bitcoin_wallet: Arc<bitcoin::Wallet>,
|
||||
monero_wallet: Arc<monero::Wallet>,
|
||||
@ -91,7 +91,7 @@ impl Builder {
|
||||
swap_id,
|
||||
identity,
|
||||
peer_id,
|
||||
db_path,
|
||||
db,
|
||||
alice_address,
|
||||
alice_peer_id,
|
||||
bitcoin_wallet,
|
||||
@ -117,13 +117,11 @@ impl Builder {
|
||||
|
||||
let (event_loop, event_loop_handle) = self.init_event_loop()?;
|
||||
|
||||
let db = Database::open(self.db_path.as_path())?;
|
||||
|
||||
Ok((
|
||||
Swap {
|
||||
state: initial_state,
|
||||
event_loop_handle,
|
||||
db,
|
||||
db: self.db,
|
||||
bitcoin_wallet: self.bitcoin_wallet.clone(),
|
||||
monero_wallet: self.monero_wallet.clone(),
|
||||
swap_id: self.swap_id,
|
||||
@ -134,17 +132,15 @@ impl Builder {
|
||||
}
|
||||
|
||||
InitParams::None => {
|
||||
// reopen the existing database
|
||||
let db = Database::open(self.db_path.as_path())?;
|
||||
|
||||
let resume_state = if let database::Swap::Bob(state) = db.get_state(self.swap_id)? {
|
||||
state.into()
|
||||
} else {
|
||||
bail!(
|
||||
"Trying to load swap with id {} for the wrong direction.",
|
||||
self.swap_id
|
||||
)
|
||||
};
|
||||
let resume_state =
|
||||
if let database::Swap::Bob(state) = self.db.get_state(self.swap_id)? {
|
||||
state.into()
|
||||
} else {
|
||||
bail!(
|
||||
"Trying to load swap with id {} for the wrong direction.",
|
||||
self.swap_id
|
||||
)
|
||||
};
|
||||
|
||||
let (event_loop, event_loop_handle) = self.init_event_loop()?;
|
||||
|
||||
@ -152,7 +148,7 @@ impl Builder {
|
||||
Swap {
|
||||
state: resume_state,
|
||||
event_loop_handle,
|
||||
db,
|
||||
db: self.db,
|
||||
bitcoin_wallet: self.bitcoin_wallet.clone(),
|
||||
monero_wallet: self.monero_wallet.clone(),
|
||||
swap_id: self.swap_id,
|
||||
|
@ -51,7 +51,7 @@ impl BobParams {
|
||||
pub fn builder(&self) -> bob::Builder {
|
||||
bob::Builder::new(
|
||||
self.seed,
|
||||
self.db_path.clone(),
|
||||
Database::open(&self.db_path.clone().as_path()).unwrap(),
|
||||
self.swap_id,
|
||||
self.bitcoin_wallet.clone(),
|
||||
self.monero_wallet.clone(),
|
||||
|
Loading…
Reference in New Issue
Block a user