mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-11-19 09:25:33 +00:00
Merge #230
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:
commit
e3457bea79
@ -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!(
|
||||||
|
@ -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)]
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user