saving to wip

This commit is contained in:
Lorenzo Tucci 2022-11-15 20:24:04 +01:00 committed by binarybaron
parent 87e5dd8b53
commit 22deb6b47e
4 changed files with 413 additions and 306 deletions

View File

@ -3,6 +3,7 @@ use comfy_table::Table;
use jsonrpsee::http_server::{HttpServerHandle}; use jsonrpsee::http_server::{HttpServerHandle};
use qrcode::render::unicode; use qrcode::render::unicode;
use qrcode::QrCode; use qrcode::QrCode;
use crate::env::GetConfig;
use std::cmp::min; use std::cmp::min;
use crate::network::rendezvous::XmrBtcNamespace; use crate::network::rendezvous::XmrBtcNamespace;
use std::net::SocketAddr; use std::net::SocketAddr;
@ -15,11 +16,10 @@ use std::path::PathBuf;
use std::sync::Arc; use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use crate::bitcoin::TxLock; use crate::bitcoin::TxLock;
use crate::cli::command::{parse_args_and_apply_defaults, Command, ParseResult, Options}; use crate::cli::command::{parse_args_and_apply_defaults, Command, ParseResult, Options, Bitcoin, Monero, Tor};
use crate::cli::{list_sellers, EventLoop, SellerStatus}; use crate::cli::{list_sellers, EventLoop, SellerStatus};
use crate::common::check_latest_version; use crate::common::check_latest_version;
use crate::database::open_db; use crate::database::open_db;
use crate::env::Config;
use crate::libp2p_ext::MultiAddrExt; use crate::libp2p_ext::MultiAddrExt;
use crate::network::quote::{BidQuote, ZeroQuoteReceived}; use crate::network::quote::{BidQuote, ZeroQuoteReceived};
use crate::network::swarm; use crate::network::swarm;
@ -30,86 +30,49 @@ use crate::rpc;
use crate::{bitcoin, cli, monero}; use crate::{bitcoin, cli, monero};
use url::Url; use url::Url;
use uuid::Uuid; use uuid::Uuid;
use crate::protocol::Database;
use crate::env::{Config, Mainnet, Testnet};
use crate::fs::system_data_dir;
#[derive(Debug, PartialEq)] pub struct Request {
pub struct InternalApi {
pub opts: Options,
pub params: Params, pub params: Params,
pub cmd: Command, pub cmd: Command,
} }
#[derive(Debug, PartialEq, Default)] #[derive(Default)]
pub struct Params { pub struct Params {
pub bitcoin_electrum_rpc_url: Option<Url>,
pub bitcoin_target_block: Option<usize>,
pub seller: Option<Multiaddr>, pub seller: Option<Multiaddr>,
pub bitcoin_change_address: Option<bitcoin::Address>, pub bitcoin_change_address: Option<bitcoin::Address>,
pub monero_receive_address: Option<monero::Address>, pub monero_receive_address: Option<monero::Address>,
pub monero_daemon_address: Option<String>,
pub tor_socks5_port: Option<u16>,
pub namespace: Option<XmrBtcNamespace>,
pub rendezvous_point: Option<Multiaddr>, pub rendezvous_point: Option<Multiaddr>,
pub swap_id: Option<Uuid>, pub swap_id: Option<Uuid>,
pub server_address: Option<SocketAddr>,
pub amount: Option<Amount>, pub amount: Option<Amount>,
pub address: Option<bitcoin::Address>, pub address: Option<bitcoin::Address>,
} }
impl InternalApi { pub struct Init {
pub async fn call(self) -> Result<()> { db: Arc<dyn Database + Send + Sync>,
let opts = &self.opts; bitcoin_wallet: Option<bitcoin::Wallet>,
let params = self.params; monero_wallet: Option<(monero::Wallet, monero::WalletRpcProcess)>,
tor_socks5_port: Option<u16>,
namespace: XmrBtcNamespace,
server_handle: Option<HttpServerHandle>,
debug: bool,
json: bool,
is_testnet: bool,
}
impl Request {
pub async fn call(&self, api_init: &Init) -> Result<()> {
match self.cmd { match self.cmd {
Command::BuyXmr => { } Command::BuyXmr => { }
Command::History => { Command::History => {
cli::tracing::init(opts.debug, opts.json, opts.data_dir.join("logs"), None)?;
let db = open_db(opts.data_dir.join("sqlite")).await?;
let swaps = db.all().await?;
if opts.json {
for (swap_id, state) in swaps {
let state: BobState = state.try_into()?;
tracing::info!(swap_id=%swap_id.to_string(), state=%state.to_string(), "Read swap state from database");
}
} else {
let mut table = Table::new();
table.set_header(vec!["SWAP ID", "STATE"]);
for (swap_id, state) in swaps {
let state: BobState = state.try_into()?;
table.add_row(vec![swap_id.to_string(), state.to_string()]);
}
println!("{}", table);
}
} }
Command::Config => { } Command::Config => { }
Command::WithdrawBtc => { } Command::WithdrawBtc => { }
Command::StartDaemon => { Command::StartDaemon => {
let handle = rpc::run_server(params.server_address.unwrap()).await?;
loop {}
} }
Command::Balance => { Command::Balance => {
cli::tracing::init(opts.debug, opts.json, opts.data_dir.join("logs"), None)?;
let seed = Seed::from_file_or_generate(opts.data_dir.as_path())
.context("Failed to read in seed file")?;
let bitcoin_wallet = init_bitcoin_wallet(
params.bitcoin_electrum_rpc_url.unwrap(),
&seed,
opts.data_dir.clone(),
opts.env_config,
params.bitcoin_target_block.unwrap(),
)
.await?;
let bitcoin_balance = bitcoin_wallet.balance().await?;
tracing::info!(
balance = %bitcoin_balance,
"Checked Bitcoin balance",
);
} }
Command::Resume => { } Command::Resume => { }
Command::Cancel => { } Command::Cancel => { }
@ -121,6 +84,155 @@ impl InternalApi {
Ok(()) Ok(())
} }
} }
impl Init {
//pub async fn build_server(bitcoin_electrum_rpc_url: Url, bitcoin_target_block: usize, monero_daemon_address: String, tor_socks5_port: u16, namespace: XmrBtcNamespace, server_address: SocketAddr, data_dir: PathBuf, env_config: Config) -> Result<Init> {
pub async fn build(
bitcoin: Bitcoin,
monero: Monero,
tor: Option<Tor>,
data: Option<PathBuf>,
is_testnet: bool,
debug: bool,
json: bool,
server_address: Option<SocketAddr>,
) -> Result<Init> {
let (bitcoin_electrum_rpc_url, bitcoin_target_block) =
bitcoin.apply_defaults(is_testnet)?;
let monero_daemon_address = monero.apply_defaults(is_testnet);
let data_dir = data::data_dir_from(data, is_testnet)?;
let env_config = env_config_from(is_testnet);
let seed = Seed::from_file_or_generate(data_dir.as_path())
.context("Failed to read seed in file")?;
let server_handle = {
if let Some(addr) = server_address {
let (_addr, handle) = rpc::run_server(addr).await?;
Some(handle)
} else {
None
}
};
let tor_socks5_port = {
if let Some(tor) = tor {
Some(tor.tor_socks5_port)
} else {
None
}
};
let init = Init {
bitcoin_wallet: Some(init_bitcoin_wallet(
bitcoin_electrum_rpc_url,
&seed,
data_dir.clone(),
env_config,
bitcoin_target_block,
)
.await?),
monero_wallet: Some(init_monero_wallet(
data_dir.clone(),
monero_daemon_address,
env_config,
)
.await?),
tor_socks5_port: tor_socks5_port,
namespace: XmrBtcNamespace::from_is_testnet(is_testnet),
db: open_db(data_dir.join("sqlite")).await?,
debug,
json,
is_testnet,
server_handle,
};
Ok(init)
}
pub async fn build_walletless(
tor: Option<Tor>,
data: Option<PathBuf>,
is_testnet: bool,
debug: bool,
json: bool,
) -> Result<Init> {
let data_dir = data::data_dir_from(data, is_testnet)?;
let env_config = env_config_from(is_testnet);
let tor_socks5_port = {
if let Some(tor) = tor {
Some(tor.tor_socks5_port)
} else {
None
}
};
let init = Init {
bitcoin_wallet: None,
monero_wallet: None,
tor_socks5_port,
namespace: XmrBtcNamespace::from_is_testnet(is_testnet),
db: open_db(data_dir.join("sqlite")).await?,
debug,
json,
is_testnet,
server_handle: None,
};
Ok(init)
}
pub async fn build_with_btc(
bitcoin: Bitcoin,
tor: Option<Tor>,
data: Option<PathBuf>,
is_testnet: bool,
debug: bool,
json: bool,
) -> Result<Init> {
let (bitcoin_electrum_rpc_url, bitcoin_target_block) =
bitcoin.apply_defaults(is_testnet)?;
let data_dir = data::data_dir_from(data, is_testnet)?;
let env_config = env_config_from(is_testnet);
let seed = Seed::from_file_or_generate(data_dir.as_path())
.context("Failed to read seed in file")?;
let tor_socks5_port = {
if let Some(tor) = tor {
Some(tor.tor_socks5_port)
} else {
None
}
};
let init = Init {
bitcoin_wallet: Some(init_bitcoin_wallet(
bitcoin_electrum_rpc_url,
&seed,
data_dir.clone(),
env_config,
bitcoin_target_block,
)
.await?),
monero_wallet: None,
tor_socks5_port,
namespace: XmrBtcNamespace::from_is_testnet(is_testnet),
db: open_db(data_dir.join("sqlite")).await?,
debug,
json,
is_testnet,
server_handle: None,
};
Ok(init)
}
}
async fn init_bitcoin_wallet( async fn init_bitcoin_wallet(
electrum_rpc_url: Url, electrum_rpc_url: Url,
@ -272,3 +384,30 @@ async fn init_monero_wallet(
Ok((monero_wallet, monero_wallet_rpc_process)) Ok((monero_wallet, monero_wallet_rpc_process))
} }
mod data {
use super::*;
pub fn data_dir_from(arg_dir: Option<PathBuf>, testnet: bool) -> Result<PathBuf> {
let base_dir = match arg_dir {
Some(custom_base_dir) => custom_base_dir,
None => os_default()?,
};
let sub_directory = if testnet { "testnet" } else { "mainnet" };
Ok(base_dir.join(sub_directory))
}
fn os_default() -> Result<PathBuf> {
Ok(system_data_dir()?.join("cli"))
}
}
fn env_config_from(testnet: bool) -> Config {
if testnet {
Testnet::get_config()
} else {
Mainnet::get_config()
}
}

View File

@ -19,18 +19,18 @@ use swap::common::check_latest_version;
#[tokio::main] #[tokio::main]
async fn main() -> Result<()> { async fn main() -> Result<()> {
let api = match parse_args_and_apply_defaults(env::args_os())? { // let api = match parse_args_and_apply_defaults(env::args_os()).await? {
ParseResult::InternalApi(api) => *api, // ParseResult::InternalApi(api) => *api,
ParseResult::PrintAndExitZero { message } => { // ParseResult::PrintAndExitZero { message } => {
println!("{}", message); // println!("{}", message);
std::process::exit(0); // std::process::exit(0);
} // }
}; // };
if let Err(e) = check_latest_version(env!("CARGO_PKG_VERSION")).await { if let Err(e) = check_latest_version(env!("CARGO_PKG_VERSION")).await {
eprintln!("{}", e); eprintln!("{}", e);
} }
api.call().await?; //api.call().await?;
Ok(()) Ok(())
} }

View File

@ -3,7 +3,7 @@ use crate::env::GetConfig;
use crate::fs::system_data_dir; use crate::fs::system_data_dir;
use crate::network::rendezvous::XmrBtcNamespace; use crate::network::rendezvous::XmrBtcNamespace;
use crate::{env, monero}; use crate::{env, monero};
use crate::api::{InternalApi, Params}; use crate::api::{Request, Params, Init};
use anyhow::{bail, Context, Result}; use anyhow::{bail, Context, Result};
use bitcoin::{Address, AddressType}; use bitcoin::{Address, AddressType};
use libp2p::core::Multiaddr; use libp2p::core::Multiaddr;
@ -15,6 +15,7 @@ use structopt::{clap, StructOpt};
use url::Url; use url::Url;
use uuid::Uuid; use uuid::Uuid;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::sync::Arc;
// See: https://moneroworld.com/ // See: https://moneroworld.com/
pub const DEFAULT_MONERO_DAEMON_ADDRESS: &str = "node.community.rino.io:18081"; pub const DEFAULT_MONERO_DAEMON_ADDRESS: &str = "node.community.rino.io:18081";
@ -30,7 +31,7 @@ pub const DEFAULT_BITCOIN_CONFIRMATION_TARGET_TESTNET: usize = 1;
const DEFAULT_TOR_SOCKS5_PORT: &str = "9050"; const DEFAULT_TOR_SOCKS5_PORT: &str = "9050";
#[derive(Debug, PartialEq)] #[derive(Debug,)]
pub struct Options { pub struct Options {
pub env_config: env::Config, pub env_config: env::Config,
pub debug: bool, pub debug: bool,
@ -39,10 +40,9 @@ pub struct Options {
} }
/// Represents the result of parsing the command-line parameters. /// Represents the result of parsing the command-line parameters.
#[derive(Debug, PartialEq)]
pub enum ParseResult { pub enum ParseResult {
/// The arguments we were invoked in. /// The arguments we were invoked in.
InternalApi(Box<InternalApi>), Init(Arc<Init>, Box<Request>),
/// A flag or command was given that does not need further processing other /// A flag or command was given that does not need further processing other
/// than printing the provided message. /// than printing the provided message.
/// ///
@ -50,7 +50,7 @@ pub enum ParseResult {
PrintAndExitZero { message: String }, PrintAndExitZero { message: String },
} }
pub fn parse_args_and_apply_defaults<I, T>(raw_args: I) -> Result<ParseResult> pub async fn parse_args_and_apply_defaults<I, T>(raw_args: I) -> Result<ParseResult>
where where
I: IntoIterator<Item = T>, I: IntoIterator<Item = T>,
T: Into<OsString> + Clone, T: Into<OsString> + Clone,
@ -70,267 +70,252 @@ where
let is_testnet = args.testnet; let is_testnet = args.testnet;
let data = args.data; let data = args.data;
let api = match args.cmd { let (init, request) = match args.cmd {
RawCommand::BuyXmr { RawCommand::BuyXmr {
seller: Seller { seller }, seller: Seller { seller },
bitcoin, bitcoin,
bitcoin_change_address, bitcoin_change_address,
monero, monero,
monero_receive_address, monero_receive_address,
tor: Tor { tor_socks5_port }, tor,
} => { } => {
let (bitcoin_electrum_rpc_url, bitcoin_target_block) = let init = Init::build(
bitcoin.apply_defaults(is_testnet)?; bitcoin,
let monero_daemon_address = monero.apply_defaults(is_testnet); monero,
let monero_receive_address = Some(tor),
validate_monero_address(monero_receive_address, is_testnet)?; data,
let bitcoin_change_address = is_testnet,
validate_bitcoin_address(bitcoin_change_address, is_testnet)?; debug,
json,
InternalApi { None
opts: Options { ).await?;
env_config: env_config_from(is_testnet), let request = Request {
debug,
json,
data_dir: data::data_dir_from(data, is_testnet)?,
},
params: Params { params: Params {
seller: Some(seller),
bitcoin_electrum_rpc_url: Some(bitcoin_electrum_rpc_url),
bitcoin_target_block: Some(bitcoin_target_block),
bitcoin_change_address: Some(bitcoin_change_address), bitcoin_change_address: Some(bitcoin_change_address),
monero_receive_address: Some(monero_receive_address), monero_receive_address: Some(monero_receive_address),
monero_daemon_address: Some(monero_daemon_address), seller: Some(seller),
tor_socks5_port: Some(tor_socks5_port),
namespace: Some(XmrBtcNamespace::from_is_testnet(is_testnet)),
..Default::default() ..Default::default()
}, },
cmd: Command::BuyXmr, cmd: Command::BuyXmr,
} };
(init, request)
} }
RawCommand::History => InternalApi { RawCommand::History => {
opts: Options { let init = Init::build_walletless(
env_config: env_config_from(is_testnet), None,
data,
is_testnet,
debug, debug,
json, json
data_dir: data::data_dir_from(data, is_testnet)?, ).await?;
},
params: Params { let request = Request {
..Default::default() params: Params::default(),
}, cmd: Command::History,
cmd: Command::History, };
(init, request)
}, },
RawCommand::Config => InternalApi { RawCommand::Config => {
opts: Options { let init = Init::build_walletless(
env_config: env_config_from(is_testnet), None,
data,
is_testnet,
debug, debug,
json, json
data_dir: data::data_dir_from(data, is_testnet)?, ).await?;
},
params: Params { let request = Request {
..Default::default() params: Params::default(),
}, cmd: Command::Config,
cmd: Command::Config, };
(init, request)
}, },
RawCommand::Balance { RawCommand::Balance {
bitcoin_electrum_rpc_url, bitcoin,
} => { } => {
let bitcoin = Bitcoin { let init = Init::build_with_btc(
bitcoin_electrum_rpc_url, bitcoin,
bitcoin_target_block: None, None,
data,
is_testnet,
debug,
json
).await?;
let request = Request {
params: Params::default(),
cmd: Command::Config,
}; };
let (bitcoin_electrum_rpc_url, bitcoin_target_block) = (init, request)
bitcoin.apply_defaults(is_testnet)?;
InternalApi {
opts: Options {
env_config: env_config_from(is_testnet),
debug,
json,
data_dir: data::data_dir_from(data, is_testnet)?,
},
params: Params {
bitcoin_electrum_rpc_url: Some(bitcoin_electrum_rpc_url),
bitcoin_target_block: Some(bitcoin_target_block),
..Default::default()
},
cmd: Command::Balance,
}
} }
RawCommand::StartDaemon { RawCommand::StartDaemon {
server_address, server_address,
bitcoin,
monero,
tor,
} => { } => {
let server_address = "127.0.0.1:1234".parse()?; let init = Init::build(
InternalApi { bitcoin,
opts: Options { monero,
env_config: env_config_from(is_testnet), Some(tor),
debug, data,
json, is_testnet,
data_dir: data::data_dir_from(data, is_testnet)?, debug,
json,
}, server_address,
params: Params { ).await?;
server_address: Some(server_address), let request = Request {
..Default::default() params: Params::default(),
},
cmd: Command::StartDaemon, cmd: Command::StartDaemon,
} };
(init, request)
} }
RawCommand::WithdrawBtc { RawCommand::WithdrawBtc {
bitcoin, bitcoin,
amount, amount,
address, address,
} => { } => {
let (bitcoin_electrum_rpc_url, bitcoin_target_block) = let init = Init::build_with_btc(
bitcoin.apply_defaults(is_testnet)?; bitcoin,
None,
InternalApi { data,
opts: Options { is_testnet,
env_config: env_config_from(is_testnet), debug,
debug, json
json, ).await?;
data_dir: data::data_dir_from(data, is_testnet)?, let request = Request {
},
params: Params { params: Params {
bitcoin_electrum_rpc_url: Some(bitcoin_electrum_rpc_url), amount: amount,
bitcoin_target_block: Some(bitcoin_target_block), address: Some(address),
amount,
address: Some(bitcoin_address(address, is_testnet)?),
..Default::default() ..Default::default()
}, },
cmd: Command::WithdrawBtc, cmd: Command::WithdrawBtc,
} };
(init, request)
} }
RawCommand::Resume { RawCommand::Resume {
swap_id: SwapId { swap_id }, swap_id: SwapId { swap_id },
bitcoin, bitcoin,
monero, monero,
tor: Tor { tor_socks5_port }, tor,
} => { } => {
let (bitcoin_electrum_rpc_url, bitcoin_target_block) = let init = Init::build(
bitcoin.apply_defaults(is_testnet)?; bitcoin,
let monero_daemon_address = monero.apply_defaults(is_testnet); monero,
Some(tor),
InternalApi { data,
opts: Options { is_testnet,
env_config: env_config_from(is_testnet), debug,
debug, json,
json, None,
data_dir: data::data_dir_from(data, is_testnet)?, ).await?;
let request = Request {
},
params: Params { params: Params {
swap_id: Some(swap_id), swap_id: Some(swap_id),
bitcoin_electrum_rpc_url: Some(bitcoin_electrum_rpc_url),
bitcoin_target_block: Some(bitcoin_target_block),
monero_daemon_address: Some(monero_daemon_address),
tor_socks5_port: Some(tor_socks5_port),
namespace: Some(XmrBtcNamespace::from_is_testnet(is_testnet)),
..Default::default() ..Default::default()
}, },
cmd: Command::Resume, cmd: Command::Resume,
} };
(init, request)
} }
RawCommand::Cancel { RawCommand::Cancel {
swap_id: SwapId { swap_id }, swap_id: SwapId { swap_id },
bitcoin, bitcoin,
} => { } => {
let (bitcoin_electrum_rpc_url, bitcoin_target_block) = let init = Init::build_with_btc(
bitcoin.apply_defaults(is_testnet)?; bitcoin,
None,
InternalApi { data,
opts: Options { is_testnet,
env_config: env_config_from(is_testnet), debug,
debug, json
json, ).await?;
data_dir: data::data_dir_from(data, is_testnet)?, let request = Request {
},
params: Params { params: Params {
swap_id: Some(swap_id), swap_id: Some(swap_id),
bitcoin_electrum_rpc_url: Some(bitcoin_electrum_rpc_url),
bitcoin_target_block: Some(bitcoin_target_block),
..Default::default() ..Default::default()
}, },
cmd: Command::Cancel, cmd: Command::Cancel,
} };
(init, request)
} }
RawCommand::Refund { RawCommand::Refund {
swap_id: SwapId { swap_id }, swap_id: SwapId { swap_id },
bitcoin, bitcoin,
} => { } => {
let (bitcoin_electrum_rpc_url, bitcoin_target_block) = let init = Init::build_with_btc(
bitcoin.apply_defaults(is_testnet)?; bitcoin,
None,
InternalApi { data,
opts: Options { is_testnet,
env_config: env_config_from(is_testnet), debug,
debug, json
json, ).await?;
data_dir: data::data_dir_from(data, is_testnet)?, let request = Request {
},
params: Params { params: Params {
swap_id: Some(swap_id), swap_id: Some(swap_id),
bitcoin_electrum_rpc_url: Some(bitcoin_electrum_rpc_url),
bitcoin_target_block: Some(bitcoin_target_block),
..Default::default() ..Default::default()
}, },
cmd: Command::Refund, cmd: Command::Refund,
};
} (init, request)
} }
RawCommand::ListSellers { RawCommand::ListSellers {
rendezvous_point, rendezvous_point,
tor: Tor { tor_socks5_port }, tor,
} => InternalApi { } => {
opts: Options { let init = Init::build_walletless(
env_config: env_config_from(is_testnet), Some(tor),
data,
is_testnet,
debug, debug,
json, json
data_dir: data::data_dir_from(data, is_testnet)?, ).await?;
},
params: Params {
rendezvous_point: Some(rendezvous_point),
tor_socks5_port: Some(tor_socks5_port),
namespace: Some(XmrBtcNamespace::from_is_testnet(is_testnet)),
..Default::default()
},
cmd: Command::ListSellers,
},
RawCommand::ExportBitcoinWallet { bitcoin } => {
let (bitcoin_electrum_rpc_url, bitcoin_target_block) =
bitcoin.apply_defaults(is_testnet)?;
InternalApi { let request = Request {
opts: Options {
env_config: env_config_from(is_testnet),
debug,
json,
data_dir: data::data_dir_from(data, is_testnet)?,
},
params: Params { params: Params {
bitcoin_target_block: Some(bitcoin_target_block), rendezvous_point: Some(rendezvous_point),
bitcoin_electrum_rpc_url: Some(bitcoin_electrum_rpc_url),
..Default::default() ..Default::default()
}, },
cmd: Command::ExportBitcoinWallet, cmd: Command::ListSellers,
} };
}, (init, request)
RawCommand::MoneroRecovery { swap_id } => InternalApi { }
opts: Options { RawCommand::ExportBitcoinWallet { bitcoin } => {
env_config: env_config_from(is_testnet), let init = Init::build_with_btc(
bitcoin,
None,
data,
is_testnet,
debug, debug,
json, json
data_dir: data::data_dir_from(data, is_testnet)?, ).await?;
}, let request = Request {
params: Params { params: Params::default(),
swap_id: Some(swap_id.swap_id), cmd: Command::ExportBitcoinWallet,
..Default::default() };
}, (init, request)
cmd: Command::MoneroRecovery, },
RawCommand::MoneroRecovery { swap_id } => {
let init = Init::build_walletless(
None,
data,
is_testnet,
debug,
json
).await?;
let request = Request {
params: Params {
swap_id: Some(swap_id.swap_id),
..Default::default()
},
cmd: Command::MoneroRecovery,
};
(init, request)
}, },
}; };
Ok(ParseResult::InternalApi(Box::new(api))) Ok(ParseResult::Init(Arc::new(init), Box::new(request)))
} }
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum Command { pub enum Command {
@ -433,12 +418,21 @@ enum RawCommand {
}, },
#[structopt(about = "Prints the Bitcoin balance.")] #[structopt(about = "Prints the Bitcoin balance.")]
Balance { Balance {
#[structopt(long = "electrum-rpc", help = "Provide the Bitcoin Electrum RPC URL")] #[structopt(flatten)]
bitcoin_electrum_rpc_url: Option<Url>, bitcoin: Bitcoin,
}, },
#[structopt(about="Starts a JSON-RPC server")] #[structopt(about="Starts a JSON-RPC server")]
StartDaemon { StartDaemon {
#[structopt(flatten)]
bitcoin: Bitcoin,
#[structopt(flatten)]
monero: Monero,
#[structopt(long="server-address", help = "The socket address the server should use")]
server_address: Option<SocketAddr>, server_address: Option<SocketAddr>,
#[structopt(flatten)]
tor: Tor,
}, },
/// Resume a swap /// Resume a swap
Resume { Resume {
@ -498,7 +492,7 @@ enum RawCommand {
} }
#[derive(structopt::StructOpt, Debug)] #[derive(structopt::StructOpt, Debug)]
struct Monero { pub struct Monero {
#[structopt( #[structopt(
long = "monero-daemon-address", long = "monero-daemon-address",
help = "Specify to connect to a monero daemon of your choice: <host>:<port>" help = "Specify to connect to a monero daemon of your choice: <host>:<port>"
@ -507,7 +501,7 @@ struct Monero {
} }
impl Monero { impl Monero {
fn apply_defaults(self, testnet: bool) -> String { pub fn apply_defaults(self, testnet: bool) -> String {
if let Some(address) = self.monero_daemon_address { if let Some(address) = self.monero_daemon_address {
address address
} else if testnet { } else if testnet {
@ -519,19 +513,19 @@ impl Monero {
} }
#[derive(structopt::StructOpt, Debug)] #[derive(structopt::StructOpt, Debug)]
struct Bitcoin { pub struct Bitcoin {
#[structopt(long = "electrum-rpc", help = "Provide the Bitcoin Electrum RPC URL")] #[structopt(long = "electrum-rpc", help = "Provide the Bitcoin Electrum RPC URL")]
bitcoin_electrum_rpc_url: Option<Url>, pub bitcoin_electrum_rpc_url: Option<Url>,
#[structopt( #[structopt(
long = "bitcoin-target-block", long = "bitcoin-target-block",
help = "Estimate Bitcoin fees such that transactions are confirmed within the specified number of blocks" help = "Estimate Bitcoin fees such that transactions are confirmed within the specified number of blocks"
)] )]
bitcoin_target_block: Option<usize>, pub bitcoin_target_block: Option<usize>,
} }
impl Bitcoin { impl Bitcoin {
fn apply_defaults(self, testnet: bool) -> Result<(Url, usize)> { pub fn apply_defaults(self, testnet: bool) -> Result<(Url, usize)> {
let bitcoin_electrum_rpc_url = if let Some(url) = self.bitcoin_electrum_rpc_url { let bitcoin_electrum_rpc_url = if let Some(url) = self.bitcoin_electrum_rpc_url {
url url
} else if testnet { } else if testnet {
@ -553,13 +547,13 @@ impl Bitcoin {
} }
#[derive(structopt::StructOpt, Debug)] #[derive(structopt::StructOpt, Debug)]
struct Tor { pub struct Tor {
#[structopt( #[structopt(
long = "tor-socks5-port", long = "tor-socks5-port",
help = "Your local Tor socks5 proxy port", help = "Your local Tor socks5 proxy port",
default_value = DEFAULT_TOR_SOCKS5_PORT default_value = DEFAULT_TOR_SOCKS5_PORT
)] )]
tor_socks5_port: u16, pub tor_socks5_port: u16,
} }
#[derive(structopt::StructOpt, Debug)] #[derive(structopt::StructOpt, Debug)]
@ -580,32 +574,6 @@ struct Seller {
seller: Multiaddr, seller: Multiaddr,
} }
mod data {
use super::*;
pub fn data_dir_from(arg_dir: Option<PathBuf>, testnet: bool) -> Result<PathBuf> {
let base_dir = match arg_dir {
Some(custom_base_dir) => custom_base_dir,
None => os_default()?,
};
let sub_directory = if testnet { "testnet" } else { "mainnet" };
Ok(base_dir.join(sub_directory))
}
fn os_default() -> Result<PathBuf> {
Ok(system_data_dir()?.join("cli"))
}
}
fn env_config_from(testnet: bool) -> env::Config {
if testnet {
env::Testnet::get_config()
} else {
env::Mainnet::get_config()
}
}
fn bitcoin_address(address: Address, is_testnet: bool) -> Result<Address> { fn bitcoin_address(address: Address, is_testnet: bool) -> Result<Address> {
let network = if is_testnet { let network = if is_testnet {

View File

@ -1,5 +1,5 @@
use jsonrpsee::http_server::{RpcModule}; use jsonrpsee::http_server::{RpcModule};
use crate::api::{InternalApi, Params}; use crate::api::{Request, Params};
use crate::env::{Config, GetConfig, Testnet}; use crate::env::{Config, GetConfig, Testnet};
use crate::fs::system_data_dir; use crate::fs::system_data_dir;
use url::Url; use url::Url;
@ -21,22 +21,22 @@ pub fn register_modules() -> RpcModule<()> {
} }
async fn get_bitcoin_balance() -> anyhow::Result<(), Error> { async fn get_bitcoin_balance() -> anyhow::Result<(), Error> {
let api = InternalApi { // let api = InternalApi {
opts: Options { // opts: Options {
env_config: Testnet::get_config(), // env_config: Testnet::get_config(),
debug: false, // debug: false,
json: true, // json: true,
data_dir: system_data_dir().unwrap().join("cli") // data_dir: system_data_dir().unwrap().join("cli")
//
}, // },
params: Params { // params: Params {
bitcoin_electrum_rpc_url: Some(Url::from_str(DEFAULT_ELECTRUM_RPC_URL_TESTNET).unwrap()), // bitcoin_electrum_rpc_url: Some(Url::from_str(DEFAULT_ELECTRUM_RPC_URL_TESTNET).unwrap()),
bitcoin_target_block: Some(DEFAULT_BITCOIN_CONFIRMATION_TARGET_TESTNET), // bitcoin_target_block: Some(DEFAULT_BITCOIN_CONFIRMATION_TARGET_TESTNET),
..Default::default() // ..Default::default()
}, // },
cmd: Command::Balance, // cmd: Command::Balance,
}; // };
api.call().await; // api.call().await;
Ok(()) Ok(())
} }