瀏覽代碼

app/schema/wallet: remove all mock values, add get_balance() util

epiphany 2 月之前
父節點
當前提交
99830a6a66

+ 0 - 28
bin/app/src/app/schema/wallet/data.rs

@@ -20,8 +20,6 @@ use darkfi::tx::Transaction;
 use darkfi_money_contract::model::TokenId;
 use darkfi_sdk::crypto::keypair::Address;
 
-use super::super::ColorScheme;
-
 #[cfg(any(target_os = "android", feature = "emulate-android"))]
 mod android_ui_consts {
     pub const BACKARROW_SCALE: f32 = 30.;
@@ -97,32 +95,6 @@ pub use ui_consts::*;
 
 pub const BALANCE_BASE10_DECIMALS: usize = 8;
 
-pub const MOCK_TOKENS: &[(&str, &str, f32)] = &[
-    ("DRK", "Dark", 100.24),
-    ("wXMR", "wrapped Monero", 5.56487),
-    ("wBTC", "wrapped Bitcoin", 0.78956413),
-    ("RNDM", "Random", 0.78956413),
-    ("OTHER", "Other token", 0.78956413),
-    ("OTHER", "Other token", 0.78956413),
-    ("OTHER", "Other token", 0.78956413),
-    ("OTHER", "Other token", 0.78956413),
-];
-
-pub const MOCK_RECEIVE_ADDRESS: &str = "8siycy4q5rsf3rwxa9ptw5v7syfj1m1ov27tt78rj7kprth1ux41lqpvut6cht7w";
-pub const MOCK_TX_FEE: &str = "0.001 DRK";
-
-pub fn is_valid_address(address: &str) -> bool {
-    address.len() > 3 // TODO
-}
-
-pub fn get_balance(token_symbol: &str) -> f32 {
-    MOCK_TOKENS
-        .iter()
-        .find(|(symbol, _, _)| *symbol == token_symbol)
-        .map(|(_, _, balance)| *balance)
-        .unwrap_or(0.0)
-}
-
 // Send transaction data shared across all send pages
 #[derive(Debug, Clone)]
 pub struct SendTxData {

+ 0 - 9
bin/app/src/app/schema/wallet/main.rs

@@ -206,21 +206,12 @@ pub async fn make_main_wallet_layer(
                         }
                     } else {
                         e!("Failed to decode default address response");
-                        if let Some(receive_address_node) = receive_layer.lookup_node("/receive_address") {
-                            receive_address_node.set_property_str(atom, Role::App, "text", MOCK_RECEIVE_ADDRESS).unwrap();
-                        }
                     }
                 } else {
                     e!("Failed to call get_default_address method");
-                    if let Some(receive_address_node) = receive_layer.lookup_node("/receive_address") {
-                        receive_address_node.set_property_str(atom, Role::App, "text", MOCK_RECEIVE_ADDRESS).unwrap();
-                    }
                 }
             } else {
                 e!("Failed to lookup drk plugin node");
-                if let Some(receive_address_node) = receive_layer.lookup_node("/receive_address") {
-                    receive_address_node.set_property_str(atom, Role::App, "text", MOCK_RECEIVE_ADDRESS).unwrap();
-                }
             }
         }
     });

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

@@ -118,7 +118,7 @@ pub async fn make_receive_layer(
     prop.set_expr(atom, Role::App, 2, code).unwrap();
     prop.set_f32(atom, Role::App, 3, BASE_FONTSIZE * 2.).unwrap();
     node.set_property_f32(atom, Role::App, "font_size", BUTTON_FONTSIZE).unwrap();
-    node.set_property_str(atom, Role::App, "text", MOCK_RECEIVE_ADDRESS).unwrap();
+    node.set_property_str(atom, Role::App, "text", "").unwrap();
     node.set_property_enum(atom, Role::App, "overflow_wrap", "anywhere").unwrap();
     let prop = node.get_property("text_color").unwrap();
     if COLOR_SCHEME == ColorScheme::DarkMode {

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

@@ -174,7 +174,7 @@ pub async fn make_send_step1_layer(
             if let Ok(row) = TokenRow::decode(&mut cur) {
                 let mut data = send_tx_data2.lock().unwrap();
                 data.token_symbol = Some(row.symbol.clone());
-                data.token_id = Some(row.id.clone());
+                data.token_id = Some(row.id);
                 drop(data);
 
                 let atom = &mut renderer.make_guard(gfxtag!("token selection"));

+ 9 - 10
bin/app/src/app/schema/wallet/send_step2.rs

@@ -18,7 +18,6 @@
 
 use std::sync::Arc;
 use darkfi_sdk::crypto::keypair::Address;
-use darkfi_serial::{Decodable, Encodable};
 
 use crate::{
     app::{
@@ -377,15 +376,15 @@ pub async fn make_send_step2_layer(
 
             let atom = &mut renderer.make_guard(gfxtag!("add recipient button"));
 
-            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());
-            drop(tx_data);
-
-            // Update step3 display with token and recipient
-            let data = send_tx_data3.lock().unwrap().clone();
+            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.clone()
+            };
 
+            // Update step3
             if let Some(token_symbol) = &data.token_symbol {
                 let token_symbol_node = sg_root.lookup_node("/window/content/wallet_send_step3_layer/send_selected_token_symbol3").unwrap();
                 token_symbol_node.set_property_str(atom, Role::App, "text", token_symbol).unwrap();
@@ -395,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(token_symbol);
+                    let available_balance = get_balance(&sg_root, &data.token_id.unwrap()).await;
                     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();
                     }

+ 67 - 64
bin/app/src/app/schema/wallet/send_step3.rs

@@ -412,17 +412,6 @@ pub async fn make_send_step3_layer(
         .await;
     send_step3_layer.link(token_symbol_node.clone());
 
-    let token_symbol_initial = send_tx_data.lock().unwrap().token_symbol.clone().unwrap_or_else(|| "".to_string());
-    update_amount_screen(
-        atom,
-        "0",
-        &token_symbol_initial,
-        &amount_wrapper,
-        &input_node,
-        &token_symbol_node,
-        Some(&available_balance_node),
-    );
-
     y += PADDING_Y * 2. + BUTTON_HEIGHT + 10.;
 
     // Add amount button with states
@@ -447,6 +436,7 @@ pub async fn make_send_step3_layer(
     let amount_text = amount_input2.get_property("text").unwrap();
     let amount_text_sub = amount_text.subscribe_modify();
     let renderer = app.renderer.clone();
+    let sg_root = app.sg_root.clone();
     let btn_bg_valid_clone = btn_bg_valid.clone();
     let btn_bg_invalid_clone = btn_bg_invalid.clone();
     let add_amount_label_node_for_validation = add_amount_label_node.clone();
@@ -511,29 +501,6 @@ pub async fn make_send_step3_layer(
                 }
             }
 
-            old_amount_text = sanitized_amount.clone();
-
-            // Update positions to center amount and token symbol
-            let token_symbol = send_tx_data5.lock().unwrap().token_symbol.clone().unwrap_or_else(|| "".to_string());
-            update_amount_screen(
-                atom,
-                &sanitized_amount,
-                &token_symbol,
-                &amount_wrapper2,
-                &amount_input2,
-                &token_symbol_node2,
-                Some(&available_balance_node2),
-            );
-            let available_balance = get_balance(&token_symbol);
-            let is_valid = if sanitized_amount == "0" {
-                false
-            } else {
-                match sanitized_amount.parse::<f32>() {
-                    Ok(v) if v > 0. && v <= available_balance => true,
-                    _ => false,
-                }
-            };
-
             // Set amount input text color: grey if "0", white otherwise
             if sanitized_amount == "0" {
                 amount_input_text_color.set_f32(atom, Role::App, 0, 0.5).unwrap();
@@ -547,20 +514,49 @@ pub async fn make_send_step3_layer(
                 amount_input_text_color.set_f32(atom, Role::App, 3, 1.).unwrap();
             }
 
-            if is_valid {
-                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();
-                label_text_color.set_f32(atom, Role::App, 3, COLOR_CYAN[3]).unwrap();
-                btn_bg_valid_visible.set_bool(atom, Role::App, 0, true).unwrap();
-                btn_bg_invalid_visible.set_bool(atom, Role::App, 0, false).unwrap();
-            } else {
-                label_text_color.set_f32(atom, Role::App, 0, 0.5).unwrap();
-                label_text_color.set_f32(atom, Role::App, 1, 0.5).unwrap();
-                label_text_color.set_f32(atom, Role::App, 2, 0.5).unwrap();
-                label_text_color.set_f32(atom, Role::App, 3, 1.).unwrap();
-                btn_bg_valid_visible.set_bool(atom, Role::App, 0, false).unwrap();
-                btn_bg_invalid_visible.set_bool(atom, Role::App, 0, true).unwrap();
+            old_amount_text = sanitized_amount.clone();
+
+            let (token_id, token_symbol) = {
+                let data = send_tx_data5.lock().unwrap();
+                (data.token_id, data.token_symbol.clone().unwrap_or_default())
+            };
+            if let Some(token_id) = token_id {
+                update_amount_screen(
+                    atom,
+                    &sg_root,
+                    &sanitized_amount,
+                    &token_id,
+                    &token_symbol,
+                    &amount_wrapper2,
+                    &amount_input2,
+                    &token_symbol_node2,
+                    Some(&available_balance_node2),
+                ).await;
+                let available_balance = get_balance(&sg_root, &token_id).await;
+                let is_valid = if sanitized_amount == "0" {
+                    false
+                } else {
+                    match sanitized_amount.parse::<f32>() {
+                        Ok(v) if v > 0. && v <= available_balance => true,
+                        _ => false,
+                    }
+                };
+
+                if is_valid {
+                    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();
+                    label_text_color.set_f32(atom, Role::App, 3, COLOR_CYAN[3]).unwrap();
+                    btn_bg_valid_visible.set_bool(atom, Role::App, 0, true).unwrap();
+                    btn_bg_invalid_visible.set_bool(atom, Role::App, 0, false).unwrap();
+                } else {
+                    label_text_color.set_f32(atom, Role::App, 0, 0.5).unwrap();
+                    label_text_color.set_f32(atom, Role::App, 1, 0.5).unwrap();
+                    label_text_color.set_f32(atom, Role::App, 2, 0.5).unwrap();
+                    label_text_color.set_f32(atom, Role::App, 3, 1.).unwrap();
+                    btn_bg_valid_visible.set_bool(atom, Role::App, 0, false).unwrap();
+                    btn_bg_invalid_visible.set_bool(atom, Role::App, 0, true).unwrap();
+                }
             }
         }
     });
@@ -578,8 +574,8 @@ pub async fn make_send_step3_layer(
     let listen_click = app.ex.spawn(async move {
         while let Ok(_) = recvr.recv().await {
             let text = amount_input2.get_property_str("text").unwrap();
-            let token_symbol = send_tx_data4.lock().unwrap().token_symbol.clone().unwrap_or_else(|| "".to_string());
-            let available_balance = get_balance(&token_symbol);
+            let token_id = send_tx_data4.lock().unwrap().token_id.clone().unwrap();
+            let available_balance = get_balance(&sg_root, &token_id).await;
             let is_valid = if text.is_empty() {
                 false
             } else {
@@ -651,6 +647,7 @@ pub async fn make_send_step3_layer(
     // Add listener for step3 visibility to focus/unfocus amount input
     let step3_is_visible_clone = step3_is_visible.clone();
     let renderer_clone = app.renderer.clone();
+    let sg_root = app.sg_root.clone();
     let amount_wrapper_clone = amount_wrapper.clone();
     let input_node_clone = input_node.clone();
     let token_symbol_node_clone = token_symbol_node.clone();
@@ -670,20 +667,26 @@ pub async fn make_send_step3_layer(
                 // Focus the amount input
                 input_node_clone.call_method("focus", vec![]).await.unwrap();
 
-                // Get the current token symbol and update positions
-                let token_symbol = send_tx_data_clone.lock().unwrap().token_symbol.clone().unwrap_or_default();
-                if !token_symbol.is_empty() {
-                    let atom = &mut renderer_clone.make_guard(gfxtag!("update amount positions on visible"));
-                    let current_amount = input_node_clone.get_property_str("text").unwrap();
-                    update_amount_screen(
-                        atom,
-                        &current_amount,
-                        &token_symbol,
-                        &amount_wrapper_clone,
-                        &input_node_clone,
-                        &token_symbol_node_clone,
-                        Some(&available_balance_node),
-                    );
+                let (token_id, token_symbol) = {
+                    let data = send_tx_data_clone.lock().unwrap();
+                    (data.token_id.clone(), data.token_symbol.clone().unwrap_or_else(|| "".to_string()))
+                };
+                if let Some(token_id) = token_id {
+                    if !token_symbol.is_empty() {
+                        let atom = &mut renderer_clone.make_guard(gfxtag!("update amount positions on visible"));
+                        let current_amount = input_node_clone.get_property_str("text").unwrap();
+                        update_amount_screen(
+                            atom,
+                            &sg_root,
+                            &current_amount,
+                            &token_id,
+                            &token_symbol,
+                            &amount_wrapper_clone,
+                            &input_node_clone,
+                            &token_symbol_node_clone,
+                            Some(&available_balance_node),
+                        ).await;
+                    }
                 }
             } else {
                 // Unfocus when becoming hidden

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

@@ -361,7 +361,7 @@ pub async fn make_send_step4_layer(
     prop.set_expr(atom, Role::App, 2, code).unwrap();
     prop.set_f32(atom, Role::App, 3, BASE_FONTSIZE).unwrap();
     tx_fee_value_node.set_property_f32(atom, Role::App, "font_size", BASE_FONTSIZE).unwrap();
-    tx_fee_value_node.set_property_str(atom, Role::App, "text", MOCK_TX_FEE).unwrap();
+    tx_fee_value_node.set_property_str(atom, Role::App, "text", "0 DRK").unwrap();
     tx_fee_value_node.set_property_enum(atom, Role::App, "text_align", "end").unwrap();
     tx_fee_value_node.set_property_u32(atom, Role::App, "z_index", 2).unwrap();
     let prop = tx_fee_value_node.get_property("text_color").unwrap();
@@ -451,7 +451,7 @@ pub async fn make_send_step4_layer(
     let amount_text_node_clone = amount_text_node.clone();
     let token_symbol_node_clone = token_symbol_node.clone();
     let send_tx_data_clone2 = send_tx_data.clone();
-    let sg_root_clone_for_visibility = app.sg_root.clone();
+    let sg_root = app.sg_root.clone();
     let step4_is_visible_sub = step4_is_visible.prop().subscribe_modify();
     let listen_step4_visible = app.ex.spawn(async move {
         while let Ok(_) = step4_is_visible_sub.receive().await {
@@ -469,32 +469,35 @@ pub async fn make_send_step4_layer(
 
                 let amount_text = data.amount.unwrap_or_else(|| "0".to_string());
                 let token_symbol = data.token_symbol.unwrap_or_else(|| "".to_string());
+                let token_id = data.token_id.unwrap();
 
                 // Update positions to center amount and token symbol
                 update_amount_screen(
                     atom,
+                    &sg_root,
                     &amount_text,
+                    &token_id,
                     &token_symbol,
                     &amount_wrapper_clone,
                     &amount_text_node_clone,
                     &token_symbol_node_clone,
                     None,
-                );
+                ).await;
 
                 if data.tx_built {
                     // Set send button label
-                    if let Some(send_label_node) = sg_root_clone_for_visibility.lookup_node("/window/content/wallet_send_step4_layer/send_send_btn_label") {
+                    if let Some(send_label_node) = sg_root.lookup_node("/window/content/wallet_send_step4_layer/send_send_btn_label") {
                         send_label_node.set_property_str(atom, Role::App, "text", "send").unwrap();
                     }
                     // Show transaction fee
-                    if let Some(tx_fee_label) = sg_root_clone_for_visibility.lookup_node("/window/content/wallet_send_step4_layer/send_fee_label") {
+                    if let Some(tx_fee_label) = sg_root.lookup_node("/window/content/wallet_send_step4_layer/send_fee_label") {
                         let prop = tx_fee_label.get_property("text_color").unwrap();
                         prop.set_f32(atom, Role::App, 0, 1.).unwrap();
                         prop.set_f32(atom, Role::App, 1, 1.).unwrap();
                         prop.set_f32(atom, Role::App, 2, 1.).unwrap();
                         prop.set_f32(atom, Role::App, 3, 1.).unwrap();
                     }
-                    if let Some(tx_fee_value) = sg_root_clone_for_visibility.lookup_node("/window/content/wallet_send_step4_layer/send_fee_value") {
+                    if let Some(tx_fee_value) = sg_root.lookup_node("/window/content/wallet_send_step4_layer/send_fee_value") {
                         let prop = tx_fee_value.get_property("text_color").unwrap();
                         prop.set_f32(atom, Role::App, 0, 1.).unwrap();
                         prop.set_f32(atom, Role::App, 1, 1.).unwrap();
@@ -503,14 +506,14 @@ pub async fn make_send_step4_layer(
                     }
                 } else {
                     // Hide transaction fee
-                    if let Some(tx_fee_label) = sg_root_clone_for_visibility.lookup_node("/window/content/wallet_send_step4_layer/send_fee_label") {
+                    if let Some(tx_fee_label) = sg_root.lookup_node("/window/content/wallet_send_step4_layer/send_fee_label") {
                         let prop = tx_fee_label.get_property("text_color").unwrap();
                         prop.set_f32(atom, Role::App, 0, 0.).unwrap();
                         prop.set_f32(atom, Role::App, 1, 0.).unwrap();
                         prop.set_f32(atom, Role::App, 2, 0.).unwrap();
                         prop.set_f32(atom, Role::App, 3, 0.).unwrap();
                     }
-                    if let Some(tx_fee_value) = sg_root_clone_for_visibility.lookup_node("/window/content/wallet_send_step4_layer/send_fee_value") {
+                    if let Some(tx_fee_value) = sg_root.lookup_node("/window/content/wallet_send_step4_layer/send_fee_value") {
                         let prop = tx_fee_value.get_property("text_color").unwrap();
                         prop.set_f32(atom, Role::App, 0, 0.).unwrap();
                         prop.set_f32(atom, Role::App, 1, 0.).unwrap();

+ 30 - 2
bin/app/src/app/schema/wallet/util.rs

@@ -16,6 +16,9 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
+use darkfi_money_contract::model::TokenId;
+use darkfi_serial::Decodable;
+
 use crate::{
     app::App,
     app::node::{create_button, create_text, create_vector_art},
@@ -32,10 +35,35 @@ 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 {
+    let Some(drk_node) = sg_root.lookup_node("/plugin/drk") else {
+        return 0.
+    };
+    let Ok(Some(response_data)) = drk_node.call_method("get_balances", vec![]).await else {
+        return 0.
+    };
+    let mut cur = std::io::Cursor::new(response_data);
+    let Ok(balances) = Vec::<(String, TokenId, f32)>::decode(&mut cur) else {
+        return 0.
+    };
+
+    balances
+        .iter()
+        .find(|(_, tid, _)| *tid == *token_id)
+        .map(|(_, _, balance)| *balance)
+        .unwrap_or(0.)
+}
+
 /// Update positions for amount input wrapper and token symbol to center them together.
-pub fn update_amount_screen(
+pub async fn update_amount_screen(
     atom: &mut PropertyAtomicGuard,
+    sg_root: &SceneNodePtr,
     amount_text: &str,
+    token_id: &TokenId,
     token_symbol: &str,
     amount_wrapper_node: &SceneNodePtr,
     amount_input_node: &SceneNodePtr,
@@ -74,7 +102,7 @@ pub fn update_amount_screen(
 
     // Set available balance
     if let Some(available_balance_node) = available_balance_node {
-        let available_balance = get_balance(token_symbol);
+        let available_balance = get_balance(sg_root, token_id).await;
         available_balance_node.set_property_str(atom, Role::App, "text", format!("{available_balance} available")).unwrap();
     }
 }