mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-01-21 21:01:15 -05:00
saving to wip
This commit is contained in:
parent
87e5dd8b53
commit
22deb6b47e
255
swap/src/api.rs
255
swap/src/api.rs
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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(())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user