2021-04-30 01:01:30 +00:00
use crate ::fs ::system_data_dir ;
2021-03-03 23:46:54 +00:00
use anyhow ::{ Context , Result } ;
2021-03-04 00:28:58 +00:00
use libp2p ::core ::Multiaddr ;
use libp2p ::PeerId ;
2021-04-30 01:01:30 +00:00
use std ::path ::{ Path , PathBuf } ;
2021-03-04 00:28:58 +00:00
use std ::str ::FromStr ;
2021-03-15 01:02:42 +00:00
use url ::Url ;
2020-11-06 00:10:22 +00:00
use uuid ::Uuid ;
2020-10-29 03:45:45 +00:00
2021-03-05 05:10:45 +00:00
// Port is assumed to be stagenet standard port 38081
pub const DEFAULT_STAGENET_MONERO_DAEMON_HOST : & str = " monero-stagenet.exan.tech " ;
2021-03-15 01:02:42 +00:00
const DEFAULT_ELECTRUM_RPC_URL : & str = " ssl://electrum.blockstream.info:60002 " ;
2021-05-11 01:30:48 +00:00
const DEFAULT_BITCOIN_CONFIRMATION_TARGET : & str = " 3 " ;
2021-03-15 01:02:42 +00:00
2021-04-22 01:33:36 +00:00
const DEFAULT_TOR_SOCKS5_PORT : & str = " 9050 " ;
2020-12-15 10:26:02 +00:00
#[ derive(structopt::StructOpt, Debug) ]
2021-03-26 03:31:14 +00:00
#[ structopt(name = " swap " , about = " CLI for swapping BTC for XMR " , author) ]
2021-02-10 22:47:42 +00:00
pub struct Arguments {
2021-01-27 02:33:32 +00:00
#[ structopt(
2021-03-15 01:02:42 +00:00
long = " --data-dir " ,
help = " Provide the data directory path to be used to store application data " ,
default_value
2021-01-27 02:33:32 +00:00
) ]
2021-03-15 01:02:42 +00:00
pub data : Data ,
2020-12-15 10:26:02 +00:00
2021-03-01 01:19:05 +00:00
#[ structopt(long, help = " Activate debug logging. " ) ]
pub debug : bool ,
2020-12-15 10:26:02 +00:00
#[ structopt(subcommand) ]
2021-03-02 11:07:48 +00:00
pub cmd : Command ,
2020-12-15 10:26:02 +00:00
}
2020-10-15 22:14:39 +00:00
#[ derive(structopt::StructOpt, Debug) ]
2020-12-15 10:26:02 +00:00
pub enum Command {
2021-03-05 05:16:18 +00:00
/// Start a XMR for BTC swap
2020-12-04 05:27:17 +00:00
BuyXmr {
2021-04-01 04:13:29 +00:00
#[ structopt(long = " seller-peer-id " , help = " The seller's peer id " ) ]
2021-03-30 04:40:59 +00:00
alice_peer_id : PeerId ,
2021-04-01 04:13:29 +00:00
#[ structopt(long = " seller-addr " , help = " The seller's multiaddress " ) ]
2021-04-06 01:05:36 +00:00
alice_multiaddr : Multiaddr ,
2021-03-02 11:07:48 +00:00
2021-05-11 01:36:44 +00:00
#[ structopt(flatten) ]
2021-05-11 01:44:21 +00:00
bitcoin : Bitcoin ,
2021-03-15 01:02:42 +00:00
2021-03-05 05:00:52 +00:00
#[ structopt(flatten) ]
2021-05-11 01:44:21 +00:00
monero : Monero ,
2021-04-22 01:33:36 +00:00
#[ structopt(long = " tor-socks5-port " , help = " Your local Tor socks5 proxy port " , default_value = DEFAULT_TOR_SOCKS5_PORT) ]
tor_socks5_port : u16 ,
2020-10-29 03:45:45 +00:00
} ,
2021-03-05 05:16:18 +00:00
/// Show a list of past ongoing and completed swaps
2020-11-05 05:55:30 +00:00
History ,
2021-03-05 05:16:18 +00:00
/// Resume a swap
2021-02-26 03:44:48 +00:00
Resume {
2021-03-05 05:16:18 +00:00
#[ structopt(
long = " swap-id " ,
help = " The swap id can be retrieved using the history subcommand "
) ]
2020-12-21 03:43:44 +00:00
swap_id : Uuid ,
2021-04-01 04:13:29 +00:00
#[ structopt(long = " seller-addr " , help = " The seller's multiaddress " ) ]
2021-04-06 01:05:36 +00:00
alice_multiaddr : Multiaddr ,
2020-12-18 06:39:04 +00:00
2021-05-11 01:36:44 +00:00
#[ structopt(flatten) ]
2021-05-11 01:44:21 +00:00
bitcoin : Bitcoin ,
2021-03-15 01:02:42 +00:00
2021-03-05 05:00:52 +00:00
#[ structopt(flatten) ]
2021-05-11 01:44:21 +00:00
monero : Monero ,
2021-04-22 01:33:36 +00:00
#[ structopt(long = " tor-socks5-port " , help = " Your local Tor socks5 proxy port " , default_value = DEFAULT_TOR_SOCKS5_PORT) ]
tor_socks5_port : u16 ,
2020-11-06 00:10:22 +00:00
} ,
2021-03-05 05:16:18 +00:00
/// Try to cancel an ongoing swap (expert users only)
2021-02-26 03:44:48 +00:00
Cancel {
2021-03-05 05:16:18 +00:00
#[ structopt(
long = " swap-id " ,
help = " The swap id can be retrieved using the history subcommand "
) ]
2021-02-01 05:25:33 +00:00
swap_id : Uuid ,
2021-02-01 11:32:54 +00:00
#[ structopt(short, long) ]
force : bool ,
2021-03-15 01:02:42 +00:00
2021-05-11 01:36:44 +00:00
#[ structopt(flatten) ]
2021-05-11 01:44:21 +00:00
bitcoin : Bitcoin ,
2021-02-01 05:25:33 +00:00
} ,
2021-03-05 05:16:18 +00:00
/// Try to cancel a swap and refund my BTC (expert users only)
2021-02-26 03:44:48 +00:00
Refund {
2021-03-05 05:16:18 +00:00
#[ structopt(
long = " swap-id " ,
help = " The swap id can be retrieved using the history subcommand "
) ]
2021-02-01 05:10:43 +00:00
swap_id : Uuid ,
2021-02-01 11:32:54 +00:00
#[ structopt(short, long) ]
force : bool ,
2021-03-15 01:02:42 +00:00
2021-05-11 01:36:44 +00:00
#[ structopt(flatten) ]
2021-05-11 01:44:21 +00:00
bitcoin : Bitcoin ,
2021-02-01 05:10:43 +00:00
} ,
}
2021-02-28 23:53:43 +00:00
2021-03-05 05:00:52 +00:00
#[ derive(structopt::StructOpt, Debug) ]
2021-05-11 01:44:21 +00:00
pub struct Monero {
2021-03-05 05:16:18 +00:00
#[ structopt(long = " receive-address " ,
help = " Provide the monero address where you would like to receive monero " ,
parse ( try_from_str = parse_monero_address )
) ]
2021-03-05 05:00:52 +00:00
pub receive_monero_address : monero ::Address ,
2021-03-05 05:10:45 +00:00
#[ structopt(
2021-03-05 05:16:18 +00:00
long = " monero-daemon-host " ,
help = " Specify to connect to a monero daemon of your choice " ,
default_value = DEFAULT_STAGENET_MONERO_DAEMON_HOST
2021-03-05 05:10:45 +00:00
) ]
pub monero_daemon_host : String ,
2021-03-05 05:00:52 +00:00
}
2021-05-11 01:36:44 +00:00
#[ derive(structopt::StructOpt, Debug) ]
2021-05-11 01:44:21 +00:00
pub struct Bitcoin {
2021-05-11 01:36:44 +00:00
#[ structopt(long = " electrum-rpc " ,
help = " Provide the Bitcoin Electrum RPC URL " ,
default_value = DEFAULT_ELECTRUM_RPC_URL
) ]
pub electrum_rpc_url : Url ,
#[ structopt(long = " bitcoin-target-block " , help = " Within how many blocks should the Bitcoin transactions be confirmed. " , default_value = DEFAULT_BITCOIN_CONFIRMATION_TARGET) ]
pub bitcoin_target_block : usize ,
}
2021-03-15 01:02:42 +00:00
#[ derive(Clone, Debug) ]
pub struct Data ( pub PathBuf ) ;
2021-04-29 08:50:49 +00:00
/// Default location for storing data for the CLI
2021-04-30 01:01:30 +00:00
// Takes the default system data-dir and adds a `/cli`
2021-03-15 01:02:42 +00:00
impl Default for Data {
fn default ( ) -> Self {
2021-04-29 08:50:49 +00:00
Data (
2021-04-30 01:01:30 +00:00
system_data_dir ( )
. map ( | proj_dir | Path ::join ( & proj_dir , " cli " ) )
2021-04-29 08:50:49 +00:00
. expect ( " computed valid path for data dir " ) ,
)
2021-03-15 01:02:42 +00:00
}
}
impl FromStr for Data {
type Err = core ::convert ::Infallible ;
fn from_str ( s : & str ) -> Result < Self , Self ::Err > {
Ok ( Data ( PathBuf ::from_str ( s ) ? ) )
}
}
impl ToString for Data {
fn to_string ( & self ) -> String {
self . 0
. clone ( )
. into_os_string ( )
. into_string ( )
. expect ( " default datadir to be convertible to string " )
}
}
2021-03-03 23:46:54 +00:00
fn parse_monero_address ( s : & str ) -> Result < monero ::Address > {
monero ::Address ::from_str ( s ) . with_context ( | | {
format! (
" Failed to parse {} as a monero address, please make sure it is a valid address " ,
s
)
} )
}