diff --git a/locales/en.yml b/locales/en.yml index b525f7b..3e0efce 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -77,8 +77,8 @@ wallets: parse_s1_slatepack_desc: 'To receive %{amount} ツ send this message to the sender:' parse_s2_slatepack_desc: 'Finalize transaction to send %{amount} ツ' parse_s3_slatepack_desc: 'Post transaction to finalize sending of %{amount} ツ' - response_slatepack_err: 'An error occurred during creation of the response, check input data:' - response_exists_err: 'Such transaction already exists:' + resp_slatepack_err: 'An error occurred during creation of the response, check input data:' + resp_exists_err: 'Such transaction already exists.' create_request_desc: 'Create request to send or receive the funds:' send_request_desc: 'You have created a request to send %{amount} ツ. Send this message to the receiver of funds:' send_slatepack_err: An error occurred during creation of request to send funds, check input data. diff --git a/locales/ru.yml b/locales/ru.yml index 69fb776..7390f30 100644 --- a/locales/ru.yml +++ b/locales/ru.yml @@ -77,8 +77,8 @@ wallets: parse_s1_slatepack_desc: 'Для получения %{amount} ツ отправьте это сообщение отправителю:' parse_s2_slatepack_desc: 'Завершите транзакцию для отправки %{amount} ツ' parse_s3_slatepack_desc: 'Опубликуйте транзакцию для завершения отправки %{amount} ツ' - response_slatepack_err: 'Во время создания ответа произошла ошибка, проверьте входные данные:' - response_exists_err: 'Такая транзакция уже существует:' + resp_slatepack_err: 'Во время создания ответа произошла ошибка, проверьте входные данные:' + resp_exists_err: 'Такая транзакция уже существует.' create_request_desc: 'Cоздать запрос на получение или отправку средств:' send_request_desc: 'Вы создали запрос на отправку %{amount} ツ. Отправьте это сообщение получателю средств:' send_slatepack_err: Во время создания запроса на отправку средств произошла ошибка, проверьте входные данные. diff --git a/src/gui/views/wallets/wallet/messages.rs b/src/gui/views/wallets/wallet/messages.rs index 98302d0..80e9e42 100644 --- a/src/gui/views/wallets/wallet/messages.rs +++ b/src/gui/views/wallets/wallet/messages.rs @@ -191,10 +191,10 @@ impl WalletMessages { if let Some(err) = &self.message_error { ui.label(RichText::new(err.text()).size(16.0).color(Colors::RED)); } else { - let desc_text = if response_empty && self.message_slate.is_none() { + let desc_text = if self.message_slate.is_none() { t!("wallets.input_slatepack_desc") } else { - let slate = self.message_slate.as_ref().unwrap(); + let mut slate = self.message_slate.clone().unwrap(); let amount = amount_to_hr_string(slate.amount, true); match slate.state { SlateState::Standard1 => { @@ -386,51 +386,8 @@ impl WalletMessages { } if let Ok(mut slate) = wallet.parse_slatepack(self.message_edit.clone()) { println!("parse_message: {}", slate); - // Make operation based on incoming state status. - match slate.state { - SlateState::Standard1 => { - if let Ok(resp) = wallet.receive(self.message_edit.clone()) { - self.response_edit = resp; - } else { - // Check if tx with same slate id already exists. - let exists_tx = wallet.tx_by_slate(&slate).is_some(); - if exists_tx { - return; - } - // Set default response error message. - self.message_error = Some( - MessageError::Response(t!("wallets.response_slatepack_err")) - ); - } - } - SlateState::Invoice1 => { - match wallet.pay(self.message_edit.clone()) { - Ok(resp) => { - self.response_edit = resp; - } - Err(err) => { - match err { - grin_wallet_libwallet::Error::NotEnoughFunds {..} => { - let amount = amount_to_hr_string(slate.amount, true); - let a_t = t!("wallets.pay_balance_error", "amount" => amount); - self.message_error = Some(MessageError::Other(a_t)); - } - _ => { - self.message_error = Some( - MessageError::Response(t!("wallets.response_slatepack_err")) - ); - } - } - } - } - } - _ => { - self.response_edit = "".to_string(); - } - } - - // Try to get amount from transaction by id. + // Try to setup empty amount from transaction by id. if slate.amount == 0 { let _ = wallet.get_data().unwrap().txs.clone().iter().map(|tx| { if tx.data.tx_slate_id == Some(slate.id) { @@ -441,10 +398,91 @@ impl WalletMessages { tx }).collect::>(); } - self.message_slate = Some(slate.clone()); + + if slate.amount == 0 { + self.message_error = Some( + MessageError::Response(t!("wallets.resp_slatepack_err")) + ); + return; + } + + // Make operation based on incoming state status. + match slate.state { + SlateState::Standard1 | SlateState::Invoice1 => { + let resp = if slate.state == SlateState::Standard1 { + wallet.receive(self.message_edit.clone()) + } else { + wallet.pay(self.message_edit.clone()) + }; + if resp.is_ok() { + self.response_edit = resp.unwrap(); + } else { + // Check if tx with same slate id already exists. + let exists_tx = wallet.tx_by_slate(&slate).is_some(); + if exists_tx { + let mut sl = slate.clone(); + sl.state = if sl.state == SlateState::Standard1 { + SlateState::Standard2 + } else { + SlateState::Invoice2 + }; + match wallet.read_slatepack(&sl) { + None => { + self.message_error = Some( + MessageError::Response(t!("wallets.resp_slatepack_err")) + ); + } + Some(sp) => { + self.message_slate = Some(slate); + self.response_edit = sp; + } + } + return; + } + + // Set default response error message. + self.message_error = Some( + MessageError::Response(t!("wallets.resp_slatepack_err")) + ); + } + } + SlateState::Standard2 | SlateState::Invoice2 => { + // Check if slatepack with same id and state already exists. + let mut sl = slate.clone(); + sl.state = if sl.state == SlateState::Standard2 { + SlateState::Standard1 + } else { + SlateState::Invoice1 + }; + match wallet.read_slatepack(&sl) { + None => { + match wallet.read_slatepack(&slate) { + None => { + self.message_error = Some( + MessageError::Response(t!("wallets.resp_slatepack_err")) + ); + } + Some(sp) => { + self.message_slate = Some(sl); + self.response_edit = sp; + return; + } + } + } + Some(_) => { + self.message_slate = Some(slate.clone()); + return; + } + } + } + _ => { + self.response_edit = "".to_string(); + } + } + self.message_slate = Some(slate); } else { self.message_slate = None; - self.message_error = Some(MessageError::Parse(t!("wallets.response_slatepack_err"))); + self.message_error = Some(MessageError::Parse(t!("wallets.resp_slatepack_err"))); } } diff --git a/src/gui/views/wallets/wallet/txs.rs b/src/gui/views/wallets/wallet/txs.rs index 93128cf..5c16c78 100644 --- a/src/gui/views/wallets/wallet/txs.rs +++ b/src/gui/views/wallets/wallet/txs.rs @@ -230,8 +230,9 @@ fn tx_item_ui(ui: &mut egui::Ui, || tx.data.tx_type == TxLogEntryType::TxReceivedCancelled; if is_canceled { format!("{} {}", X_CIRCLE, t!("wallets.tx_canceled")) - } else if tx.data.kernel_excess.is_some() && - tx.data.tx_type == TxLogEntryType::TxReceived { + } else if tx.posting || (tx.data.kernel_excess.is_some() && + (tx.data.tx_type == TxLogEntryType::TxReceived || + tx.data.tx_type == TxLogEntryType::TxSent)) { format!("{} {}", DOTS_THREE_CIRCLE, t!("wallets.tx_finalizing")) } else { match tx.data.tx_type { @@ -253,7 +254,7 @@ fn tx_item_ui(ui: &mut egui::Ui, format!("{} {}", CHECK_CIRCLE, t!("wallets.tx_confirmed")) }, TxLogEntryType::TxSent | TxLogEntryType::TxReceived => { - if data.info.last_confirmed_height - tx_height > min_conf { + if data.info.last_confirmed_height - tx_height > min_conf + 1 { let text = if tx.data.tx_type == TxLogEntryType::TxSent { t!("wallets.tx_sent") } else { diff --git a/src/wallet/config.rs b/src/wallet/config.rs index ce1d80f..7d5686e 100644 --- a/src/wallet/config.rs +++ b/src/wallet/config.rs @@ -17,7 +17,7 @@ use std::path::PathBuf; use std::string::ToString; use grin_core::global::ChainTypes; -use grin_wallet_libwallet::{SlateState}; +use grin_wallet_libwallet::{Slate}; use serde_derive::{Deserialize, Serialize}; use crate::{AppConfig, Settings}; @@ -122,13 +122,13 @@ impl WalletConfig { } /// Get Slatepacks data path for current wallet. - pub fn get_slatepack_path(&self, id: String, state: &SlateState) -> PathBuf { + pub fn get_slatepack_path(&self, slate: &Slate) -> PathBuf { let mut slatepack_dir = PathBuf::from(self.get_data_path()); slatepack_dir.push(SLATEPACKS_DIR_NAME); if !slatepack_dir.exists() { let _ = fs::create_dir_all(slatepack_dir.clone()); } - let slatepack_file_name = format!("{}.{}.slatepack", id, state); + let slatepack_file_name = format!("{}.{}.slatepack", slate.id, slate.state); slatepack_dir.push(slatepack_file_name); slatepack_dir } diff --git a/src/wallet/wallet.rs b/src/wallet/wallet.rs index 25d5aec..ad72e01 100644 --- a/src/wallet/wallet.rs +++ b/src/wallet/wallet.rs @@ -479,13 +479,22 @@ impl Wallet { })?; // Save slatepack. - let slatepack_dir = self.get_config().get_slatepack_path(slate.id.to_string(), &slate.state); + let slatepack_dir = self.get_config().get_slatepack_path(&slate); let mut output = File::create(slatepack_dir)?; output.write_all(message.as_bytes())?; output.sync_all()?; Ok(message) } + /// Read slatepack from file. + pub fn read_slatepack(&self, slate: &Slate) -> Option { + let slatepack_path = self.get_config().get_slatepack_path(slate); + match fs::read_to_string(slatepack_path) { + Ok(s) => Some(s), + Err(_) => None + } + } + /// Get transaction by slate id. pub fn tx_by_slate(&self, slate: &Slate) -> Option { if let Some(data) = self.get_data() { @@ -956,17 +965,17 @@ fn sync_wallet_data(wallet: &Wallet) { tx.amount_credited - tx.amount_debited }; - // Setup transaction broadcasting flag based on slate state. + // Setup transaction posting flag based on slate state. let posting = if (tx.tx_type == TxLogEntryType::TxSent || tx.tx_type == TxLogEntryType::TxReceived) && !tx.confirmed && tx.tx_slate_id.is_some() { - let sl_id = tx.tx_slate_id.unwrap().to_string(); - let state = match tx.tx_type { + let mut slate = Slate::blank(1, false); + slate.id = tx.tx_slate_id.unwrap(); + slate.state = match tx.tx_type { TxLogEntryType::TxReceived => SlateState::Invoice3, _ => SlateState::Standard3 }; - let slatepack_path = config.get_slatepack_path(sl_id, &state); - fs::read_to_string(slatepack_path).is_ok() + wallet.read_slatepack(&slate).is_some() } else { false };