Browse Source

app/schema/wallet: fix balances, replace is_valid_address()

epiphany 2 months ago
parent
commit
fdf8e19071

+ 5 - 4
bin/app/src/app/schema/wallet/main.rs

@@ -16,6 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
+use darkfi::util::parse::encode_base10;
 use darkfi_serial::{Decodable, Encodable};
 
 use crate::{
@@ -391,14 +392,14 @@ pub async fn make_main_wallet_layer(
                 if let Some(drk_node) = sg_root2.lookup_node("/plugin/drk") {
                     if let Ok(Some(response_data)) = drk_node.call_method("get_balances", vec![]).await {
                         let mut cur = std::io::Cursor::new(response_data);
-                        if let Ok(balances) = Vec::<(String, darkfi_money_contract::model::TokenId, f32)>::decode(&mut cur) {
+                        if let Ok(balances) = Vec::<(String, darkfi_money_contract::model::TokenId, u64)>::decode(&mut cur) {
                             let token_rows: Vec<TokenRow> = balances
                                 .iter()
                                 .enumerate()
                                 .map(|(i, (symbol, token_id, balance))| TokenRow {
                                     id: *token_id,
                                     symbol: symbol.clone(),
-                                    balance: balance.to_string(),
+                                    balance: encode_base10(*balance, BALANCE_BASE10_DECIMALS),
                                 })
                                 .collect();
 
@@ -411,9 +412,9 @@ pub async fn make_main_wallet_layer(
 
                             // Update main wallet balance
                             use darkfi_money_contract::model::DARK_TOKEN_ID;
-                            if let Some(drk_balance) = balances.iter().find(|(_, token_id, _)| *token_id == *DARK_TOKEN_ID) {
+                            if let Some(drk_row) = token_rows.iter().find(|row| row.id == *DARK_TOKEN_ID) {
                                 if let Some(balance_node) = sg_root2.lookup_node("/window/content/wallet_main_layer/wallet_balance") {
-                                    balance_node.set_property_str(atom, Role::App, "text", format!("DRK {}", drk_balance.2)).unwrap();
+                                    balance_node.set_property_str(atom, Role::App, "text", format!("DRK {}", drk_row.balance)).unwrap();
                                 }
                             }
                         }

+ 1 - 1
bin/app/src/app/schema/wallet/send.rs

@@ -24,7 +24,7 @@ use crate::{
     app::App,
     gfx::gfxtag,
     mesh::COLOR_CYAN,
-    prop::{PropertyAtomicGuard, PropertyBool, PropertyFloat32, Role},
+    prop::{PropertyBool, PropertyFloat32, Role},
     scene::SceneNodePtr,
     util::i18n::I18nBabelFish,
 };

+ 5 - 5
bin/app/src/app/schema/wallet/send_step1.rs

@@ -18,6 +18,7 @@
 
 use std::sync::Arc;
 
+use darkfi::util::parse::encode_base10;
 use darkfi_money_contract::model::DARK_TOKEN_ID;
 use darkfi_serial::{Decodable, Encodable};
 
@@ -29,7 +30,6 @@ use crate::{
     },
     expr,
     gfx::gfxtag,
-    mesh::COLOR_CYAN,
     prop::{PropertyAtomicGuard, PropertyBool, PropertyFloat32, Role},
     scene::{SceneNodePtr, Slot},
     shape,
@@ -204,14 +204,14 @@ pub async fn make_send_step1_layer(
                 if let Some(drk_node) = sg_root2.lookup_node("/plugin/drk") {
                     if let Ok(Some(response_data)) = drk_node.call_method("get_balances", vec![]).await {
                         let mut cur = std::io::Cursor::new(response_data);
-                        if let Ok(balances) = Vec::<(String, darkfi_money_contract::model::TokenId, f32)>::decode(&mut cur) {
+                        if let Ok(balances) = Vec::<(String, darkfi_money_contract::model::TokenId, u64)>::decode(&mut cur) {
                             let token_rows: Vec<TokenRow> = balances
                                 .iter()
                                 .enumerate()
                                 .map(|(i, (symbol, token_id, balance))| TokenRow {
                                     id: *token_id,
                                     symbol: symbol.clone(),
-                                    balance: balance.to_string(),
+                                    balance: encode_base10(*balance, BALANCE_BASE10_DECIMALS),
                                 })
                                 .collect();
 
@@ -223,9 +223,9 @@ pub async fn make_send_step1_layer(
                             let _ = send_tokens_table2.call_method("set_tokens", data).await;
 
                             // Update main wallet balance
-                            if let Some(drk_balance) = balances.iter().find(|(_, token_id, _)| *token_id == *DARK_TOKEN_ID) {
+                            if let Some(drk_row) = token_rows.iter().find(|row| row.id == *DARK_TOKEN_ID) {
                                 if let Some(balance_node) = sg_root2.lookup_node("/window/content/wallet_main_layer/wallet_balance") {
-                                    balance_node.set_property_str(atom, Role::App, "text", format!("DRK {}", drk_balance.2)).unwrap();
+                                    balance_node.set_property_str(atom, Role::App, "text", format!("DRK {}", drk_row.balance)).unwrap();
                                 }
                             }
                         }

+ 7 - 7
bin/app/src/app/schema/wallet/send_step2.rs

@@ -17,6 +17,7 @@
  */
 
 use std::sync::Arc;
+use darkfi::util::parse::encode_base10;
 use darkfi_sdk::crypto::keypair::Address;
 
 use crate::{
@@ -29,7 +30,7 @@ use crate::{
     gfx::gfxtag,
     mesh::COLOR_CYAN,
     prop::{PropertyAtomicGuard, PropertyBool, PropertyFloat32, Role},
-    scene::{Pimpl, SceneNodePtr, Slot},
+    scene::{SceneNodePtr, Slot},
     shape,
     ui::{BaseEdit, BaseEditType, Button, Layer, Text, VectorArt, VectorShape},
     util::i18n::I18nBabelFish,
@@ -338,7 +339,7 @@ pub async fn make_send_step2_layer(
             } else {
                 text_color.set_f32(atom, Role::App, 3, 0.).unwrap();
                 // Cyan color for valid
-                if is_valid_address(&addr) {
+                if addr.clone().parse::<Address>().is_ok() {
                     label_text_color.set_f32(atom, Role::App, 0, COLOR_CYAN[0]).unwrap();
                     label_text_color.set_f32(atom, Role::App, 1, COLOR_CYAN[1]).unwrap();
                     label_text_color.set_f32(atom, Role::App, 2, COLOR_CYAN[2]).unwrap();
@@ -370,17 +371,16 @@ pub async fn make_send_step2_layer(
         while let Ok(_) = recvr.recv().await {
             let text = recipient_input2.get_property_str("text").unwrap();
             // Only proceed if address is valid
-            if !is_valid_address(&text) {
+            let Ok(addr) = text.clone().parse::<Address>() else {
                 continue;
-            }
+            };
 
             let atom = &mut renderer.make_guard(gfxtag!("add recipient button"));
 
             let data = {
                 let mut tx_data = send_tx_data3.lock().unwrap();
                 tx_data.recipient_str = Some(text.clone());
-                // unwrap is okay here, recipient string is already verified by is_valid_address()
-                tx_data.recipient = Some(text.clone().parse::<Address>().unwrap());
+                tx_data.recipient = Some(addr);
                 tx_data.clone()
             };
 
@@ -394,7 +394,7 @@ pub async fn make_send_step2_layer(
                     amount_token_node.set_property_str(atom, Role::App, "text", token_symbol).unwrap();
 
                     // Update available balance
-                    let available_balance = get_balance(&sg_root, &data.token_id.unwrap()).await;
+                    let available_balance = encode_base10(get_balance(&sg_root, &data.token_id.unwrap()).await, BALANCE_BASE10_DECIMALS);
                     if let Some(available_balance_node) = sg_root.lookup_node("/window/content/wallet_send_step3_layer/send_available_balance") {
                         available_balance_node.set_property_str(atom, Role::App, "text", format!("{available_balance} available")).unwrap();
                     }

+ 6 - 6
bin/app/src/app/schema/wallet/send_step3.rs

@@ -18,8 +18,8 @@
 
 use std::sync::Arc;
 
-use darkfi_money_contract::model::TokenId;
-use darkfi_serial::{Decodable, Encodable};
+use darkfi::util::parse::decode_base10;
+use darkfi_serial::Encodable;
 
 use crate::{
     app::{
@@ -536,8 +536,8 @@ pub async fn make_send_step3_layer(
                 let is_valid = if sanitized_amount == "0" {
                     false
                 } else {
-                    match sanitized_amount.parse::<f32>() {
-                        Ok(v) if v > 0. && v <= available_balance => true,
+                    match decode_base10(&sanitized_amount, BALANCE_BASE10_DECIMALS, false) {
+                        Ok(v) if v > 0 && v <= available_balance => true, // TODO: fees
                         _ => false,
                     }
                 };
@@ -579,8 +579,8 @@ pub async fn make_send_step3_layer(
             let is_valid = if text.is_empty() {
                 false
             } else {
-                match text.parse::<f32>() {
-                    Ok(v) if v > 0. && v <= available_balance => true,
+                match decode_base10(&text, BALANCE_BASE10_DECIMALS, false) {
+                    Ok(v) if v > 0 && v <= available_balance => true,
                     _ => false,
                 }
             };

+ 0 - 3
bin/app/src/app/schema/wallet/send_step4.rs

@@ -19,8 +19,6 @@
 use std::sync::Arc;
 
 use darkfi_serial::{Decodable, Encodable};
-use darkfi::util::parse::encode_base10;
-use darkfi::tx::Transaction;
 
 use crate::{
     app::{
@@ -30,7 +28,6 @@ use crate::{
     },
     expr,
     gfx::gfxtag,
-    mesh::COLOR_CYAN,
     prop::{PropertyAtomicGuard, PropertyBool, PropertyFloat32, Role},
     scene::{SceneNodePtr, Slot},
     shape,

+ 4 - 6
bin/app/src/app/schema/wallet/tx_status.rs

@@ -18,22 +18,20 @@
 
 use std::sync::Arc;
 
-use darkfi_serial::{Decodable, Encodable};
+use darkfi_serial::Decodable;
 use darkfi::tx::Transaction;
 
 use crate::{
     app::{
         App,
-        node::{create_button, create_layer, create_text, create_vector_art},
+        node::{create_layer, create_text},
         schema::COLOR_SCHEME,
     },
     expr,
     gfx::gfxtag,
-    mesh::COLOR_CYAN,
-    prop::{Property, PropertyAtomicGuard, PropertyBool, PropertyFloat32, PropertyStr, PropertySubType, PropertyType, Role},
+    prop::{Property, PropertyAtomicGuard, PropertyBool, PropertyFloat32, PropertySubType, PropertyType, Role},
     scene::{SceneNodePtr, Slot},
-    shape,
-    ui::{Button, Layer, Text, VectorArt},
+    ui::{Layer, Text},
     util::i18n::I18nBabelFish,
 };
 

+ 8 - 11
bin/app/src/app/schema/wallet/util.rs

@@ -16,6 +16,7 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
+use darkfi::util::parse::encode_base10;
 use darkfi_money_contract::model::TokenId;
 use darkfi_serial::Decodable;
 
@@ -35,27 +36,23 @@ use crate::{
 
 use super::{super::ColorScheme, data::*};
 
-pub fn is_valid_address(address: &str) -> bool {
-    address.len() > 3 // TODO
-}
-
-pub async fn get_balance(sg_root: &SceneNodePtr, token_id: &TokenId) -> f32 {
+pub async fn get_balance(sg_root: &SceneNodePtr, token_id: &TokenId) -> u64 {
     let Some(drk_node) = sg_root.lookup_node("/plugin/drk") else {
-        return 0.
+        return 0
     };
     let Ok(Some(response_data)) = drk_node.call_method("get_balances", vec![]).await else {
-        return 0.
+        return 0
     };
     let mut cur = std::io::Cursor::new(response_data);
-    let Ok(balances) = Vec::<(String, TokenId, f32)>::decode(&mut cur) else {
-        return 0.
+    let Ok(balances) = Vec::<(String, TokenId, u64)>::decode(&mut cur) else {
+        return 0
     };
 
     balances
         .iter()
         .find(|(_, tid, _)| *tid == *token_id)
         .map(|(_, _, balance)| *balance)
-        .unwrap_or(0.)
+        .unwrap_or(0)
 }
 
 /// Update positions for amount input wrapper and token symbol to center them together.
@@ -102,7 +99,7 @@ pub async fn update_amount_screen(
 
     // Set available balance
     if let Some(available_balance_node) = available_balance_node {
-        let available_balance = get_balance(sg_root, token_id).await;
+        let available_balance = encode_base10(get_balance(sg_root, token_id).await, BALANCE_BASE10_DECIMALS);
         available_balance_node.set_property_str(atom, Role::App, "text", format!("{available_balance} available")).unwrap();
     }
 }

+ 5 - 4
bin/app/src/main.rs

@@ -23,6 +23,7 @@
 use clap::Parser;
 use darkfi::system::CondVar;
 use darkfi::tx::Transaction;
+use darkfi::util::parse::encode_base10;
 use darkfi_money_contract::model::DARK_TOKEN_ID;
 use darkfi_serial::{Decodable, Encodable, deserialize};
 use std::sync::{Arc, OnceLock};
@@ -474,7 +475,7 @@ async fn load_plugins(
                 let atom = &mut renderer2.make_guard(gfxtag!("wallet - refresh tokens"));
 
                 let mut cur = std::io::Cursor::new(response_data);
-                if let Ok(balances) = Vec::<(String, TokenId, f32)>::decode(&mut cur) {
+                if let Ok(balances) = Vec::<(String, TokenId, u64)>::decode(&mut cur) {
                     let token_rows: Vec<TokenRow> = balances
                         .iter()
                         .enumerate()
@@ -482,7 +483,7 @@ async fn load_plugins(
                             TokenRow {
                                 id: *token_id,
                                 symbol: symbol.clone(),
-                                balance: balance.to_string(),
+                                balance: encode_base10(*balance, 8),
                             }
                         })
                         .collect();
@@ -501,9 +502,9 @@ async fn load_plugins(
                     }
 
                     // Update main wallet balance
-                    if let Some(drk_balance) = balances.iter().find(|(_, token_id, _)| *token_id == *DARK_TOKEN_ID) {
+                    if let Some(drk_row) = token_rows.iter().find(|row| row.id == *DARK_TOKEN_ID) {
                         if let Some(balance_node) = sg_root2.lookup_node("/window/content/wallet_main_layer/wallet_balance") {
-                            balance_node.set_property_str(atom, Role::App, "text", format!("DRK {}", drk_balance.2)).unwrap();
+                            balance_node.set_property_str(atom, Role::App, "text", format!("DRK {}", drk_row.balance)).unwrap();
                         }
                     }
 

+ 20 - 14
bin/app/src/plugin/drk.rs

@@ -117,9 +117,9 @@ impl TxStatus {
 struct TxState {
     id: Option<String>,
     status: TxStatus,
-    amount: String,
-    token_symbol: String,
-    recipient: Address,
+    amount: Option<String>,
+    token_symbol: Option<String>,
+    recipient: Option<Address>,
 }
 
 pub type DrkPluginPtr = Arc<DrkPlugin>;
@@ -294,7 +294,7 @@ impl DrkPlugin {
         Ok(address.to_string())
     }
 
-    pub async fn get_balances(&self) -> Result<Vec<(String, TokenId, f32)>> {
+    pub async fn get_balances(&self) -> Result<Vec<(String, TokenId, u64)>> {
         let drk = self.drk.read().await;
 
         let balances = drk.money_balance().await.map_err(|e| {
@@ -307,14 +307,13 @@ impl DrkPlugin {
             Error::ServiceFailed
         })?;
 
-        let mut result: Vec<(String, TokenId, f32)> = Vec::new();
+        let mut result: Vec<(String, TokenId, u64)> = Vec::new();
         for (token_id_str, balance) in balances {
             let encoded = encode_base10(balance, BALANCE_BASE10_DECIMALS);
-            let float_balance: f32 = encoded.parse().unwrap_or(0.0);
             let alias = aliases.get(&token_id_str).cloned().unwrap_or_else(|| "UNKN".to_string());
             let token_id = token_id_str.parse::<TokenId>().unwrap();
 
-            result.push((alias, token_id, float_balance));
+            result.push((alias, token_id, balance));
         }
 
         // Sort by balance
@@ -336,9 +335,9 @@ impl DrkPlugin {
             let mut data = vec![];
             state.id.clone().encode(&mut data).unwrap();
             Some(state.status.text()).encode(&mut data).unwrap();
-            Some(state.amount.to_string()).encode(&mut data).unwrap();
-            Some(state.token_symbol.clone()).encode(&mut data).unwrap();
-            Some(state.recipient.to_string()).encode(&mut data).unwrap();
+            state.amount.encode(&mut data).unwrap();
+            state.token_symbol.clone().encode(&mut data).unwrap();
+            state.recipient.map(|r| r.to_string()).encode(&mut data).unwrap();
             let _ = node.trigger("tx_updated", data).await;
         }
     }
@@ -467,7 +466,7 @@ impl DrkPlugin {
             return false
         };
 
-        t!("method called: get_tx_history()");
+        t!("method called: get_tx_status()");
 
         fn decode_data(data: &[u8]) -> std::io::Result<String> {
             let mut cur = Cursor::new(&data);
@@ -476,12 +475,12 @@ impl DrkPlugin {
         }
 
         let Ok(tx_id) = decode_data(&method_call.data) else {
-            d!("get_tx_history() method invalid arg data");
+            d!("get_tx_status() method invalid arg data");
             return true
         };
 
         let Some(self_) = me.upgrade() else {
-            e!("drk plugin destroyed before get_tx_history task was stopped!");
+            e!("drk plugin destroyed before get_tx_status task was stopped!");
             if let Some(send_res) = method_call.send_res {
                 let _ = send_res.send(vec![]).await;
             }
@@ -613,7 +612,14 @@ impl DrkPlugin {
 
         match result {
             Ok(tx_id) => {
-                self_.emit_tx_status_updated(&TxStatus::Confirming).await;
+                let state = TxState {
+                    id: Some(tx_id),
+                    status: TxStatus::Confirming,
+                    amount: None,
+                    token_symbol: None,
+                    recipient: None,
+                };
+                self_.emit_tx_updated(&state).await;
             }
             Err(_) => {
                 e!("Failed to broadcast transaction");