230: Use testnet demo defaults if config file or cli args are not provided r=thomaseizinger a=rishflab

Closes #229 

Also connects to the ASB running by default if peer id and addr are not supplied in the cli args 


`swap_cli -- buy-xmr --send-btc 0.0006` will trigger a swap

Co-authored-by: rishflab <rishflab@hotmail.com>
This commit is contained in:
bors[bot] 2021-02-26 02:18:15 +00:00 committed by GitHub
commit e3457bea79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 85 deletions

View File

@ -21,15 +21,11 @@ use swap::{
bitcoin, bitcoin,
cli::{ cli::{
command::{Arguments, Cancel, Command, Refund, Resume}, command::{Arguments, Cancel, Command, Refund, Resume},
config::{ config::{read_config, Config},
initial_setup, query_user_for_initial_testnet_config, read_config, Config,
ConfigNotInitialized,
},
}, },
database::Database, database::Database,
execution_params, execution_params,
execution_params::GetExecutionParams, execution_params::GetExecutionParams,
fs::default_config_path,
monero, monero,
monero::{CreateWallet, OpenWallet}, monero::{CreateWallet, OpenWallet},
protocol::{ protocol::{
@ -54,18 +50,9 @@ async fn main() -> Result<()> {
let opt = Arguments::from_args(); let opt = Arguments::from_args();
let config_path = if let Some(config_path) = opt.config { let config = match opt.config {
config_path Some(config_path) => read_config(config_path)??,
} else { None => Config::testnet(),
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!( info!(

View File

@ -4,6 +4,9 @@ use libp2p::{core::Multiaddr, PeerId};
use std::path::PathBuf; use std::path::PathBuf;
use uuid::Uuid; use uuid::Uuid;
const DEFAULT_ALICE_MULTIADDR: &str = "/dns4/xmr-btc-asb.coblox.tech/tcp/9876";
const DEFAULT_ALICE_PEER_ID: &str = "12D3KooWCdMKjesXMJz1SiZ7HgotrxuqhQJbP5sgBm2BwP1cqThi";
#[derive(structopt::StructOpt, Debug)] #[derive(structopt::StructOpt, Debug)]
pub struct Arguments { pub struct Arguments {
#[structopt( #[structopt(
@ -21,10 +24,13 @@ pub struct Arguments {
#[structopt(name = "xmr_btc-swap", about = "XMR BTC atomic swap")] #[structopt(name = "xmr_btc-swap", about = "XMR BTC atomic swap")]
pub enum Command { pub enum Command {
BuyXmr { BuyXmr {
#[structopt(long = "connect-peer-id")] #[structopt(long = "connect-peer-id", default_value = DEFAULT_ALICE_PEER_ID)]
alice_peer_id: PeerId, alice_peer_id: PeerId,
#[structopt(long = "connect-addr")] #[structopt(
long = "connect-addr",
default_value = DEFAULT_ALICE_MULTIADDR
)]
alice_addr: Multiaddr, alice_addr: Multiaddr,
#[structopt(long = "send-btc", help = "Bitcoin amount as floating point nr without denomination (e.g. 1.25)", parse(try_from_str = parse_btc))] #[structopt(long = "send-btc", help = "Bitcoin amount as floating point nr without denomination (e.g. 1.25)", parse(try_from_str = parse_btc))]
@ -42,10 +48,13 @@ pub enum Resume {
#[structopt(long = "swap-id")] #[structopt(long = "swap-id")]
swap_id: Uuid, swap_id: Uuid,
#[structopt(long = "counterpart-peer-id")] #[structopt(long = "counterpart-peer-id", default_value = DEFAULT_ALICE_PEER_ID)]
alice_peer_id: PeerId, alice_peer_id: PeerId,
#[structopt(long = "counterpart-addr")] #[structopt(
long = "counterpart-addr",
default_value = DEFAULT_ALICE_MULTIADDR
)]
alice_addr: Multiaddr, alice_addr: Multiaddr,
}, },
} }
@ -58,9 +67,13 @@ pub enum Cancel {
// TODO: Remove Alice peer-id/address, it should be saved in the database when running swap // TODO: Remove Alice peer-id/address, it should be saved in the database when running swap
// and loaded from the database when running resume/cancel/refund // and loaded from the database when running resume/cancel/refund
#[structopt(long = "counterpart-peer-id")] #[structopt(long = "counterpart-peer-id", default_value = DEFAULT_ALICE_PEER_ID)]
alice_peer_id: PeerId, alice_peer_id: PeerId,
#[structopt(long = "counterpart-addr")]
#[structopt(
long = "counterpart-addr",
default_value = DEFAULT_ALICE_MULTIADDR
)]
alice_addr: Multiaddr, alice_addr: Multiaddr,
#[structopt(short, long)] #[structopt(short, long)]
@ -76,9 +89,13 @@ pub enum Refund {
// TODO: Remove Alice peer-id/address, it should be saved in the database when running swap // TODO: Remove Alice peer-id/address, it should be saved in the database when running swap
// and loaded from the database when running resume/cancel/refund // and loaded from the database when running resume/cancel/refund
#[structopt(long = "counterpart-peer-id")] #[structopt(long = "counterpart-peer-id", default_value = DEFAULT_ALICE_PEER_ID)]
alice_peer_id: PeerId, alice_peer_id: PeerId,
#[structopt(long = "counterpart-addr")]
#[structopt(
long = "counterpart-addr",
default_value = DEFAULT_ALICE_MULTIADDR
)]
alice_addr: Multiaddr, alice_addr: Multiaddr,
#[structopt(short, long)] #[structopt(short, long)]

View File

@ -1,11 +1,9 @@
use crate::fs::{default_data_dir, ensure_directory_exists}; use crate::fs::default_data_dir;
use anyhow::{Context, Result}; use anyhow::{Context, Result};
use config::ConfigError; use config::ConfigError;
use dialoguer::{theme::ColorfulTheme, Input};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::{ use std::{
ffi::OsStr, ffi::OsStr,
fs,
path::{Path, PathBuf}, path::{Path, PathBuf},
}; };
use tracing::info; use tracing::info;
@ -31,6 +29,22 @@ impl Config {
config.merge(config::File::from(config_file))?; config.merge(config::File::from(config_file))?;
config.try_into() config.try_into()
} }
pub fn testnet() -> Self {
Self {
data: Data {
dir: default_data_dir().expect("computed valid path for data dir"),
},
bitcoin: Bitcoin {
electrum_http_url: DEFAULT_ELECTRUM_HTTP_URL
.parse()
.expect("default electrum http str is a valid url"),
electrum_rpc_url: DEFAULT_ELECTRUM_RPC_URL
.parse()
.expect("default electrum rpc str is a valid url"),
},
}
}
} }
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
@ -66,67 +80,22 @@ pub fn read_config(config_path: PathBuf) -> Result<Result<Config, ConfigNotIniti
Ok(Ok(file)) Ok(Ok(file))
} }
pub fn initial_setup<F>(config_path: PathBuf, config_file: F) -> Result<()>
where
F: Fn() -> Result<Config>,
{
info!("Config file not found, running initial setup...");
ensure_directory_exists(config_path.as_path())?;
let initial_config = config_file()?;
let toml = toml::to_string(&initial_config)?;
fs::write(&config_path, toml)?;
info!(
"Initial setup complete, config file created at {} ",
config_path.as_path().display()
);
Ok(())
}
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 electrum_http_url: String = Input::with_theme(&ColorfulTheme::default())
.with_prompt("Enter Electrum HTTP URL or hit return to use default")
.default(DEFAULT_ELECTRUM_HTTP_URL.to_owned())
.interact_text()?;
let electrum_http_url = Url::parse(electrum_http_url.as_str())?;
let electrum_rpc_url: String = Input::with_theme(&ColorfulTheme::default())
.with_prompt("Enter Electrum RPC URL or hit return to use default")
.default(DEFAULT_ELECTRUM_RPC_URL.to_owned())
.interact_text()?;
let electrum_rpc_url = Url::parse(electrum_rpc_url.as_str())?;
println!();
Ok(Config {
data: Data { dir: data_dir },
bitcoin: Bitcoin {
electrum_http_url,
electrum_rpc_url,
},
})
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use std::str::FromStr; use crate::fs::ensure_directory_exists;
use std::{fs, str::FromStr};
use tempfile::tempdir; use tempfile::tempdir;
pub fn initial_setup(config_path: PathBuf, config: Config) -> Result<()> {
ensure_directory_exists(config_path.as_path())?;
let toml = toml::to_string(&config)?;
fs::write(&config_path, toml)?;
Ok(())
}
#[test] #[test]
fn config_roundtrip() { fn config_roundtrip() {
let temp_dir = tempdir().unwrap().path().to_path_buf(); let temp_dir = tempdir().unwrap().path().to_path_buf();
@ -142,7 +111,7 @@ mod tests {
}, },
}; };
initial_setup(config_path.clone(), || Ok(expected.clone())).unwrap(); initial_setup(config_path.clone(), expected.clone()).unwrap();
let actual = read_config(config_path).unwrap().unwrap(); let actual = read_config(config_path).unwrap().unwrap();
assert_eq!(expected, actual); assert_eq!(expected, actual);