From c07ebfbd573d76f39a35c7c62fba986ba49f49f9 Mon Sep 17 00:00:00 2001 From: "Nikita.m" Date: Thu, 21 May 2020 00:04:43 +0300 Subject: [PATCH] Add offline option for proposal cmds --- Cargo.toml | 2 +- src/main.rs | 31 ++++++++++++++++++--- src/voting.rs | 74 ++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 81 insertions(+), 26 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 580d9d0d..5aace310 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ readme = "README.md" license-file = "LICENSE.md" keywords = ["TON", "SDK", "smart contract", "tonlabs"] edition = "2018" -version = "0.1.5" +version = "0.1.6" [dependencies] base64 = "0.10.1" diff --git a/src/main.rs b/src/main.rs index 7ce8f47f..eb0bda1c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -236,12 +236,16 @@ fn main_internal() -> Result <(), String> { (@arg DEST: +required +takes_value "Address of proposal contract.") (@arg COMMENT: +required +takes_value "Proposal description (max symbols 382).") (@arg KEYS: +required +takes_value "Seed phrase or path to keypair file.") + (@arg OFFLINE: -f --offline "Prints signed message to terminal instead of sending it.") + (@arg LIFETIME: -l --lifetime +takes_value "Period of time in seconds while message is valid.") ) (@subcommand vote => (about: "Confirms proposal transaction in multisignature wallet.") (@arg ADDRESS: +required +takes_value "Address of multisignature wallet.") (@arg ID: +required +takes_value "Proposal transaction id.") (@arg KEYS: +required +takes_value "Seed phrase or path to keypair file.") + (@arg OFFLINE: -f --offline "Prints signed message to terminal instead of sending it.") + (@arg LIFETIME: -l --lifetime +takes_value "Period of time in seconds while message is valid.") ) (@subcommand decode => (about: "Prints comment string from proposal transaction.") @@ -547,17 +551,36 @@ fn proposal_create_command(matches: &ArgMatches, config: Config) -> Result<(), S let dest = matches.value_of("DEST"); let keys = matches.value_of("KEYS"); let comment = matches.value_of("COMMENT"); - print_args!(matches, address, comment, keys); - create_proposal(config, address.unwrap(), keys, dest.unwrap(), comment.unwrap()) + let lifetime = matches.value_of("LIFETIME"); + let offline = matches.is_present("OFFLINE"); + print_args!(matches, address, comment, keys, lifetime); + + let lifetime = lifetime.map(|val| { + u32::from_str_radix(val, 10) + .map_err(|e| format!("failed to parse lifetime: {}", e)) + }) + .transpose()? + .unwrap_or(config.timeout); + create_proposal(config, address.unwrap(), keys, dest.unwrap(), comment.unwrap(), lifetime, offline) } fn proposal_vote_command(matches: &ArgMatches, config: Config) -> Result<(), String> { let address = matches.value_of("ADDRESS"); let keys = matches.value_of("KEYS"); let id = matches.value_of("ID"); - print_args!(matches, address, id, keys); - vote(config, address.unwrap(), keys, id.unwrap()) + let lifetime = matches.value_of("LIFETIME"); + let offline = matches.is_present("OFFLINE"); + print_args!(matches, address, id, keys, lifetime); + + let lifetime = lifetime.map(|val| { + u32::from_str_radix(val, 10) + .map_err(|e| format!("failed to parse lifetime: {}", e)) + }) + .transpose()? + .unwrap_or(config.timeout); + + vote(config, address.unwrap(), keys, id.unwrap(), lifetime, offline) } fn proposal_decode_command(matches: &ArgMatches, config: Config) -> Result<(), String> { diff --git a/src/voting.rs b/src/voting.rs index 1237ad16..a0aaa163 100644 --- a/src/voting.rs +++ b/src/voting.rs @@ -167,6 +167,8 @@ pub fn create_proposal( keys: Option<&str>, dest: &str, text: &str, + lifetime: u32, + offline: bool, ) -> Result<(), String> { let msg_body: serde_json::Value = serde_json::from_str( @@ -184,17 +186,31 @@ pub fn create_proposal( "bounce": false, "allBalance": false, "payload": body_base64, - }); + }).to_string(); - call::call_contract( - conf, - addr, - MSIG_ABI.to_string(), - "submitTransaction", - &serde_json::to_string(¶ms).unwrap(), - keys.map(|s| s.to_owned()), - false - ) + let keys = keys.map(|s| s.to_owned()); + + if offline { + call::generate_message( + conf, + addr, + MSIG_ABI.to_string(), + "submitTransaction", + ¶ms, + keys, + lifetime) + } else { + + call::call_contract( + conf, + addr, + MSIG_ABI.to_string(), + "submitTransaction", + ¶ms, + keys, + false + ) + } } pub fn vote( @@ -202,21 +218,37 @@ pub fn vote( addr: &str, keys: Option<&str>, trid: &str, + lifetime: u32, + offline: bool, ) -> Result<(), String> { let params = json!({ "transactionId": trid, - }); + }).to_string(); - call::call_contract( - conf, - addr, - MSIG_ABI.to_string(), - "confirmTransaction", - &serde_json::to_string(¶ms).unwrap(), - keys.map(|s| s.to_owned()), - false - ) + let keys = keys.map(|s| s.to_owned()); + + if offline { + call::generate_message( + conf, + addr, + MSIG_ABI.to_string(), + "confirmTransaction", + ¶ms, + keys, + lifetime + ) + } else { + call::call_contract( + conf, + addr, + MSIG_ABI.to_string(), + "confirmTransaction", + ¶ms, + keys, + false + ) + } } pub fn decode_proposal( @@ -235,7 +267,7 @@ pub fn decode_proposal( true )?; - let txns = result["output"]["transactions"].as_array() + let txns = result["transactions"].as_array() .ok_or(format!(r#"failed to decode result: "transactions" array not found"#))?; for txn in txns {