From c139bb7c5d785142b7b8c653eecd025d78ce58f2 Mon Sep 17 00:00:00 2001 From: Sun Date: Wed, 8 Dec 2021 22:31:37 +0800 Subject: [PATCH] Wallet: add balance rpc --- lib/apps/wallet/models.dart | 44 ++++++++++++++++++++ lib/apps/wallet/page.dart | 15 +++++-- src/apps/wallet/models.rs | 39 +++++++++++++++++- src/apps/wallet/rpc.rs | 82 ++++++++++++++++++++++++++----------- 4 files changed, 153 insertions(+), 27 deletions(-) diff --git a/lib/apps/wallet/models.dart b/lib/apps/wallet/models.dart index b2ed899..c40878c 100644 --- a/lib/apps/wallet/models.dart +++ b/lib/apps/wallet/models.dart @@ -41,6 +41,7 @@ enum Network { EthMain, EthTestRopsten, EthTestRinkeby, + EthTestKovan, EthLocal, BtcMain, BtcLocal, @@ -55,6 +56,8 @@ extension NetworkExtension on Network { return ['Ropsten Test Network', Colors.orange]; case Network.EthTestRinkeby: return ['Rinkeby Test Network', Colors.orange]; + case Network.EthTestKovan: + return ['Rinkeby Test Network', Colors.orange]; case Network.EthLocal: return ['Localhost 8545', Color(0xFF6174FF)]; case Network.BtcMain: @@ -63,6 +66,46 @@ extension NetworkExtension on Network { return ['Localhost 8333', Color(0xFF6174FF)]; } } + + int toInt() { + switch (this) { + case Network.EthMain: + return 1; + case Network.EthTestRopsten: + return 2; + case Network.EthTestRinkeby: + return 3; + case Network.EthTestKovan: + return 4; + case Network.EthLocal: + return 5; + case Network.BtcMain: + return 6; + case Network.BtcLocal: + return 7; + } + } + + static Network fromInt(int a) { + switch (a) { + case 1: + return Network.EthMain; + case 2: + return Network.EthTestRopsten; + case 3: + return Network.EthTestRinkeby; + case 4: + return Network.EthTestKovan; + case 5: + return Network.EthLocal; + case 6: + return Network.BtcMain; + case 7: + return Network.BtcLocal; + default: + return Network.EthMain; + } + } } class Address { @@ -86,6 +129,7 @@ class Address { Network.EthMain, Network.EthTestRopsten, Network.EthTestRinkeby, + Network.EthTestKovan, Network.EthLocal, ]; case ChainToken.BTC: diff --git a/lib/apps/wallet/page.dart b/lib/apps/wallet/page.dart index bf50ab8..82dc924 100644 --- a/lib/apps/wallet/page.dart +++ b/lib/apps/wallet/page.dart @@ -62,7 +62,8 @@ class _WalletDetailState extends State with SingleTickerProviderSt } _walletBalance(List params) { - // + // TODO + print(params); } _load() async { @@ -86,10 +87,18 @@ class _WalletDetailState extends State with SingleTickerProviderSt this._selectedAddress = address; this._networks = address.networks(); if (!this._networks.contains(this._selectedNetwork)) { - this._selectedNetwork = this._networks[0]; + _changeNetwork(this._networks[0]); } } + _changeNetwork(Network network) { + this._selectedNetwork = network; + rpc.send('wallet-balance', [ + this._selectedNetwork!.toInt(), this._selectedAddress!.address + ]); + print('sended balances'); + } + @override Widget build(BuildContext context) { final color = Theme.of(context).colorScheme; @@ -140,7 +149,7 @@ class _WalletDetailState extends State with SingleTickerProviderSt onChanged: (Network? value) { if (value != null) { setState(() { - this._selectedNetwork = value; + _changeNetwork(value); }); } }, diff --git a/src/apps/wallet/models.rs b/src/apps/wallet/models.rs index bf0e3fc..a9f1379 100644 --- a/src/apps/wallet/models.rs +++ b/src/apps/wallet/models.rs @@ -13,7 +13,7 @@ pub(crate) enum ChainToken { } impl ChainToken { - fn to_i64(&self) -> i64 { + pub fn to_i64(&self) -> i64 { match self { ChainToken::ETH => 1, ChainToken::ERC20 => 2, @@ -33,6 +33,43 @@ impl ChainToken { } } +pub(crate) enum Network { + EthMain, + EthTestRopsten, + EthTestRinkeby, + EthTestKovan, + EthLocal, + BtcMain, + BtcLocal, +} + +impl Network { + pub fn to_i64(&self) -> i64 { + match self { + Network::EthMain => 1, + Network::EthTestRopsten => 2, + Network::EthTestRinkeby => 3, + Network::EthTestKovan => 4, + Network::EthLocal => 5, + Network::BtcMain => 6, + Network::BtcLocal => 7, + } + } + + pub fn from_i64(i: i64) -> Self { + match i { + 1 => Network::EthMain, + 2 => Network::EthTestRopsten, + 3 => Network::EthTestRinkeby, + 4 => Network::EthTestKovan, + 5 => Network::EthLocal, + 6 => Network::BtcMain, + 7 => Network::BtcLocal, + _ => Network::EthMain, + } + } +} + pub(crate) struct Token { pub id: i64, pub chain: ChainToken, diff --git a/src/apps/wallet/rpc.rs b/src/apps/wallet/rpc.rs index eaf6cae..653c98a 100644 --- a/src/apps/wallet/rpc.rs +++ b/src/apps/wallet/rpc.rs @@ -1,16 +1,19 @@ use std::sync::Arc; use tdn::types::{ group::GroupId, + message::SendMessage, primitive::HandleResult, - rpc::{json, RpcError, RpcHandler, RpcParam}, + rpc::{json, rpc_response, RpcError, RpcHandler, RpcParam}, }; use tdn_did::{generate_btc_account, generate_eth_account}; +use tdn_storage::local::DStorage; +use tokio::sync::mpsc::{error::SendError, Sender}; use web3::signing::Key; use crate::{rpc::RpcState, storage::wallet_db}; use super::{ - models::{Address, ChainToken}, + models::{Address, ChainToken, Network}, ETH_NODE, }; @@ -23,6 +26,48 @@ fn wallet_list(devices: Vec
) -> RpcParam { json!(results) } +async fn loop_token( + sender: Sender, + _db: DStorage, + gid: GroupId, + network: Network, + address: String, +) -> std::result::Result<(), SendError> { + // loop get balance of all tokens. + + match network { + Network::EthMain => { + // + } + Network::EthTestRopsten => {} + Network::EthTestRinkeby => {} + Network::EthTestKovan => {} + Network::EthLocal => {} + Network::BtcMain => {} + Network::BtcLocal => {} + } + + let transport = web3::transports::Http::new(ETH_NODE).unwrap(); + let web3 = web3::Web3::new(transport); + + let balance = web3 + .eth() + .balance(address.parse().unwrap(), None) + .await + .unwrap(); + println!("Balance of {:?}: {}", address, balance); + + let res = rpc_response( + 0, + "wallet-balance", + json!([address, network.to_i64(), balance]), + gid, + ); + sender.send(SendMessage::Rpc(0, res, true)).await?; + + Ok(()) +} + pub(crate) fn new_rpc_handler(handler: &mut RpcHandler) { handler.add_method("wallet-echo", |_, params, _| async move { Ok(HandleResult::rpc(json!(params))) @@ -78,28 +123,19 @@ pub(crate) fn new_rpc_handler(handler: &mut RpcHandler) { handler.add_method( "wallet-balance", - |_gid: GroupId, params: Vec, _state: Arc| async move { - let ctoken = ChainToken::from_i64(params[0].as_i64().ok_or(RpcError::ParseError)?); - let address = params[0].as_str().ok_or(RpcError::ParseError)?; - - match ctoken { - ChainToken::ETH => { - let transport = web3::transports::Http::new(ETH_NODE).unwrap(); - let web3 = web3::Web3::new(transport); - - let balance = web3 - .eth() - .balance(address.parse().unwrap(), None) - .await - .unwrap(); - println!("Balance of {:?}: {}", address, balance); - } - ChainToken::ERC20 => {} - ChainToken::ERC721 => {} - _ => {} - } + |gid: GroupId, params: Vec, state: Arc| async move { + let network = Network::from_i64(params[0].as_i64().ok_or(RpcError::ParseError)?); + let address = params[1].as_str().ok_or(RpcError::ParseError)?.to_owned(); + println!("start wallet balances"); + + let group_lock = state.group.read().await; + let db = wallet_db(group_lock.base(), &gid)?; + let sender = group_lock.sender(); + drop(group_lock); + + tokio::spawn(loop_token(sender, db, gid, network, address)); - Ok(HandleResult::rpc(json!(params))) + Ok(HandleResult::new()) }, ); }