diff --git a/src/bin/wallet.rs b/src/bin/wallet.rs index 55f63ec9c1..a7b617a992 100644 --- a/src/bin/wallet.rs +++ b/src/bin/wallet.rs @@ -115,47 +115,114 @@ fn main() -> Result<(), Box> { .value_name("URL") .help("Address of TLS proxy") .conflicts_with("rpc-port") - ).subcommand( + ).subcommand(SubCommand::with_name("address").about("Get your public key")) + .subcommand( SubCommand::with_name("airdrop") .about("Request a batch of tokens") .arg( Arg::with_name("tokens") - .long("tokens") + .index(1) .value_name("NUM") .takes_value(true) .required(true) .help("The number of tokens to request"), ), + ).subcommand(SubCommand::with_name("balance").about("Get your balance")) + .subcommand( + SubCommand::with_name("cancel") + .about("Cancel a transfer") + .arg( + Arg::with_name("process-id") + .index(1) + .value_name("PROCESS_ID") + .takes_value(true) + .required(true) + .help("The process id of the transfer to cancel"), + ), + ).subcommand( + SubCommand::with_name("confirm") + .about("Confirm transaction by signature") + .arg( + Arg::with_name("signature") + .index(1) + .value_name("SIGNATURE") + .takes_value(true) + .required(true) + .help("The transaction signature to confirm"), + ), ).subcommand( SubCommand::with_name("pay") .about("Send a payment") .arg( + Arg::with_name("to") + .index(1) + .value_name("PUBKEY") + .takes_value(true) + .required(true) + .help("The pubkey of recipient"), + ).arg( Arg::with_name("tokens") - .long("tokens") + .index(2) .value_name("NUM") .takes_value(true) .required(true) .help("The number of tokens to send"), ).arg( - Arg::with_name("to") - .long("to") + Arg::with_name("timestamp") + .long("after") + .value_name("DATETIME") + .takes_value(true) + .help("A timestamp after which transaction will execute"), + ).arg( + Arg::with_name("timestamp-pubkey") + .long("require-timestamp-from") .value_name("PUBKEY") .takes_value(true) - .help("The pubkey of recipient"), + .requires("timestamp") + .help("Require timestamp from this third party"), + ).arg( + Arg::with_name("witness") + .long("require-signature-from") + .value_name("PUBKEY") + .takes_value(true) + .multiple(true) + .use_delimiter(true) + .help("Any third party signatures required to unlock the tokens"), + ).arg( + Arg::with_name("cancellable") + .long("cancellable") + .takes_value(false) + .requires("witness"), ), ).subcommand( - SubCommand::with_name("confirm") - .about("Confirm your payment by signature") + SubCommand::with_name("send-signature") + .about("Send a signature to authorize a transfer") .arg( - Arg::with_name("signature") + Arg::with_name("process-id") .index(1) - .value_name("SIGNATURE") + .value_name("PROCESS_ID") + .takes_value(true) .required(true) - .help("The transaction signature to confirm"), - ), - ).subcommand(SubCommand::with_name("balance").about("Get your balance")) - .subcommand(SubCommand::with_name("address").about("Get your public key")) - .get_matches(); + .help("The process id of the transfer to authorize") + ) + ).subcommand( + SubCommand::with_name("send-timestamp") + .about("Send a timestamp to unlock a transfer") + .arg( + Arg::with_name("process-id") + .index(1) + .value_name("PROCESS_ID") + .takes_value(true) + .required(true) + .help("The process id of the transfer to unlock") + ).arg( + Arg::with_name("datetime") + .long("date") + .value_name("DATETIME") + .takes_value(true) + .help("Optional arbitrary timestamp to apply") + ) + ).get_matches(); let config = parse_args(&matches)?; let result = process_command(&config)?; diff --git a/src/wallet.rs b/src/wallet.rs index abe225808e..33d348c9b0 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -1,5 +1,6 @@ use bincode::{deserialize, serialize}; use bs58; +use chrono::prelude::{DateTime, Utc}; use clap::ArgMatches; use crdt::NodeInfo; use drone::DroneRequest; @@ -25,10 +26,21 @@ use transaction::Transaction; #[derive(Debug, PartialEq)] pub enum WalletCommand { Address, - Balance, AirDrop(i64), - Pay(i64, Pubkey), + Balance, + Cancel(Pubkey), Confirm(Signature), + // Pay(to, tokens, timestamp, timestamp_pubkey, witness, cancellable) + Pay( + i64, + Pubkey, + Option>, + Option, + Option, + Option, + ), + TimeElapsed(Pubkey, DateTime), + Witness(Pubkey), } #[derive(Debug, Clone)] @@ -87,6 +99,9 @@ pub fn parse_command( Ok(WalletCommand::AirDrop(tokens)) } ("balance", Some(_balance_matches)) => Ok(WalletCommand::Balance), + ("cancel", Some(cancel_matches)) => Err(WalletError::BadParameter( + "Cancel not built yet".to_string(), + )), ("confirm", Some(confirm_matches)) => { let signatures = bs58::decode(confirm_matches.value_of("signature").unwrap()) .into_vec() @@ -117,8 +132,14 @@ pub fn parse_command( let tokens = pay_matches.value_of("tokens").unwrap().parse()?; - Ok(WalletCommand::Pay(tokens, to)) + Ok(WalletCommand::Pay(tokens, to, None, None, None, None)) } + ("send-signature", Some(sig_matches)) => Err(WalletError::BadParameter( + "Send-signature not handled yet".to_string(), + )), + ("send-timestamp", Some(timestamp_matches)) => Err(WalletError::BadParameter( + "Send-timestamp not handled yet".to_string(), + )), ("", None) => { println!("{}", matches.usage()); Err(WalletError::CommandNotRecognized( @@ -173,6 +194,7 @@ pub fn process_command(config: &WalletConfig) -> Result { println!("Balance requested..."); let params = json!(format!("{}", config.id.pubkey())); @@ -187,6 +209,10 @@ pub fn process_command(config: &WalletConfig) -> Result Err(WalletError::BadParameter( + "Cancel not built yet".to_string(), + ))?, // Confirm the last client transaction by signature WalletCommand::Confirm(signature) => { let params = json!(format!("{}", signature)); @@ -207,7 +233,7 @@ pub fn process_command(config: &WalletConfig) -> Result { + WalletCommand::Pay(tokens, to, _, _, _, _) => { let result = WalletRpcRequest::GetLastId.make_rpc_request(&config.rpc_addr, 1, None)?; if result.as_str().is_none() { Err(WalletError::RpcRequestError( @@ -237,6 +263,14 @@ pub fn process_command(config: &WalletConfig) -> Result Err(WalletError::BadParameter( + "TimeElapsed not built yet".to_string(), + ))?, + // Apply witness signature to contract + WalletCommand::Witness(pubkey) => Err(WalletError::BadParameter( + "Witness not built yet".to_string(), + ))?, } }