diff --git a/lib/apps/wallet/models.dart b/lib/apps/wallet/models.dart index 9d1a3c5..78163f4 100644 --- a/lib/apps/wallet/models.dart +++ b/lib/apps/wallet/models.dart @@ -19,6 +19,17 @@ extension ChainTokenExtension on ChainToken { } } + String get symbol { + switch (this) { + case ChainToken.ETH: + case ChainToken.ERC20: + case ChainToken.ERC721: + return 'ETH'; + case ChainToken.BTC: + return 'BTC'; + } + } + int toInt() { switch (this) { case ChainToken.ETH: @@ -126,7 +137,7 @@ class Address { String name = ''; String address = ''; bool isGen = true; - String balanceString = ''; + Map balances = {}; String icon() { return this.address.substring(2, 4); @@ -161,14 +172,31 @@ class Address { } } - String get balance { - switch (this.chain) { - case ChainToken.ETH: - case ChainToken.ERC20: - case ChainToken.ERC721: - return unit_balance(this.balanceString, 18, 4); - case ChainToken.BTC: - return unit_balance(this.balanceString, 8, 4); + String balance(Network network) { + if (this.balances.containsKey(network)) { + final s = this.balances[network]!; + switch (this.chain) { + case ChainToken.ETH: + case ChainToken.ERC20: + case ChainToken.ERC721: + return unit_balance(s, 18, 4); + case ChainToken.BTC: + return unit_balance(s, 8, 4); + } + } else { + return '0.0'; + } + } + + split_balance(String s) { + if (s.length > 0) { + Map balances = {}; + s.split(",").forEach((ss) { + final sss = ss.split(":"); + balances[NetworkExtension.fromInt(int.parse(sss[0]))] = sss[1]; + }); + + this.balances = balances; } } @@ -179,7 +207,7 @@ class Address { this.name = params[3]; this.address = params[4]; this.isGen = params[5]; - this.balanceString = params[6]; + this.split_balance(params[6]); } } diff --git a/lib/apps/wallet/page.dart b/lib/apps/wallet/page.dart index c9f5097..ecbbd06 100644 --- a/lib/apps/wallet/page.dart +++ b/lib/apps/wallet/page.dart @@ -85,6 +85,7 @@ class _WalletDetailState extends State with SingleTickerProviderSt if (res.isOk) { this._addresses.clear(); res.params.forEach((param) { + print(param); this._addresses.add(Address.fromList(param)); }); if (this._addresses.length == 0) { @@ -409,15 +410,15 @@ class _WalletDetailState extends State with SingleTickerProviderSt ), ); } -} -PopupMenuEntry _menuItem(int value, Address address, ColorScheme color, bool selected) { - return PopupMenuItem( - value: value, - child: ListTile( - leading: Icon(Icons.check, color: selected ? color.onSurface : Colors.transparent), - title: Text(address.name), - subtitle: Text(address.balance), - ), - ); + PopupMenuEntry _menuItem(int value, Address address, ColorScheme color, bool selected) { + return PopupMenuItem( + value: value, + child: ListTile( + leading: Icon(Icons.check, color: selected ? color.onSurface : Colors.transparent), + title: Text(address.name), + subtitle: Text(address.balance(this._selectedNetwork!) + ' ' + address.chain.symbol), + ), + ); + } } diff --git a/src/apps/wallet/models.rs b/src/apps/wallet/models.rs index e669546..dbba020 100644 --- a/src/apps/wallet/models.rs +++ b/src/apps/wallet/models.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; +use std::ops::AddAssign; use tdn::types::{ primitive::Result, rpc::{json, RpcParam}, @@ -128,6 +130,47 @@ impl Address { self.secret.len() == 0 } + fn merge_balance(old: &str, network: &Network, add: &str) -> String { + let mut balances: HashMap = old + .split(",") + .flat_map(|s| { + if s.len() > 2 { + let mut ss = s.split(":"); + Some(( + ss.next().and_then(|s| s.parse().ok()).unwrap_or(0), + ss.next().unwrap_or(""), + )) + } else { + None + } + }) + .collect(); + balances + .entry(network.to_i64()) + .and_modify(|old| *old = add) + .or_insert(add); + + let mut last: Vec = vec![]; + for (key, balance) in balances { + last.push(format!("{}:{}", key, balance)); + } + last.join(",") + } + + fn _get_balance(network: &Network, balance: &str) -> String { + let balances: HashMap = balance + .split(",") + .map(|s| { + let mut ss = s.split(":"); + ( + ss.next().and_then(|s| s.parse().ok()).unwrap_or(0), + ss.next().unwrap_or(""), + ) + }) + .collect(); + balances.get(&network.to_i64()).unwrap_or(&"").to_string() + } + pub fn new(chain: ChainToken, index: i64, address: String) -> Self { Self { chain, @@ -204,12 +247,28 @@ impl Address { } } - pub fn update_balance(db: &DStorage, address: &str, balance: &str) -> Result<()> { - let sql = format!( - "UPDATE addresses SET balance = '{}' WHERE address = {}", - balance, address - ); - db.update(&sql)?; + pub fn update_balance( + db: &DStorage, + address: &str, + network: &Network, + balance: &str, + ) -> Result<()> { + let mut matrix = db.query(&format!( + "SELECT balance FROM addresses where address = '{}'", + address + ))?; + if matrix.len() > 0 { + let mut values = matrix.pop().unwrap(); // safe unwrap() + let old = values.pop().unwrap(); // safe unwrap() + let new_b = Address::merge_balance(old.as_str(), network, balance); + + let sql = format!( + "UPDATE addresses SET balance = '{}' WHERE address = '{}'", + new_b, address + ); + db.update(&sql)?; + } + Ok(()) } diff --git a/src/apps/wallet/rpc.rs b/src/apps/wallet/rpc.rs index 1e7924d..a4d7407 100644 --- a/src/apps/wallet/rpc.rs +++ b/src/apps/wallet/rpc.rs @@ -61,7 +61,7 @@ async fn loop_token( .await .unwrap(); let balance = balance.to_string(); - let _ = Address::update_balance(&db, &address, &balance); + let _ = Address::update_balance(&db, &address, &network, &balance); let res = res_balance(gid, &address, &network, "", &balance); sender.send(SendMessage::Rpc(0, res, true)).await?;