浏览代码

darkfid: Add get_balances function and token lists.

parazyd 4 年之前
父节点
当前提交
cf0fd46b07
共有 6 个文件被更改,包括 81 次插入3 次删除
  1. 2 0
      Cargo.lock
  2. 2 2
      Cargo.toml
  3. 2 0
      bin/darkfid2/Cargo.toml
  4. 19 0
      bin/darkfid2/src/main.rs
  5. 4 1
      bin/darkfid2/src/rpc_misc.rs
  6. 52 0
      bin/darkfid2/src/rpc_wallet.rs

+ 2 - 0
Cargo.lock

@@ -1582,8 +1582,10 @@ dependencies = [
  "darkfi",
  "darkfi",
  "easy-parallel",
  "easy-parallel",
  "futures-lite",
  "futures-lite",
+ "fxhash",
  "lazy-init",
  "lazy-init",
  "log",
  "log",
+ "num-bigint",
  "rand 0.8.5",
  "rand 0.8.5",
  "serde",
  "serde",
  "serde_derive",
  "serde_derive",

+ 2 - 2
Cargo.toml

@@ -12,7 +12,7 @@ edition = "2021"
 name = "darkfi"
 name = "darkfi"
 
 
 [profile.release]
 [profile.release]
-debug = true
+#debug = true
 lto = "fat"
 lto = "fat"
 codegen-units = 1
 codegen-units = 1
 
 
@@ -71,7 +71,7 @@ bs58 = {version = "0.4.0", optional = true}
 toml = {version = "0.5.9", optional = true}
 toml = {version = "0.5.9", optional = true}
 bytes = {version = "1.1.0", optional = true}
 bytes = {version = "1.1.0", optional = true}
 bincode = {version = "1.3.3", optional = true}
 bincode = {version = "1.3.3", optional = true}
-num-bigint = {version = "0.4.3", optional = true}
+num-bigint = {version = "0.4.3", features = ["serde"], optional = true}
 serde_json = {version = "1.0.79", optional = true}
 serde_json = {version = "1.0.79", optional = true}
 serde = {version = "1.0.136", features = ["derive"], optional = true}
 serde = {version = "1.0.136", features = ["derive"], optional = true}
 
 

+ 2 - 0
bin/darkfid2/Cargo.toml

@@ -18,8 +18,10 @@ ctrlc-async = {version = "3.2.2", default-features = false, features = ["async-s
 darkfi = {path = "../../", features = ["blockchain", "wallet", "rpc", "net", "node"]}
 darkfi = {path = "../../", features = ["blockchain", "wallet", "rpc", "net", "node"]}
 easy-parallel = "3.2.0"
 easy-parallel = "3.2.0"
 futures-lite = "1.12.0"
 futures-lite = "1.12.0"
+fxhash = "0.2.1"
 lazy-init = "0.5.0"
 lazy-init = "0.5.0"
 log = "0.4.16"
 log = "0.4.16"
+num-bigint = {version = "0.4.3", features = ["serde"]}
 rand = "0.8.5"
 rand = "0.8.5"
 serde_json = "1.0.79"
 serde_json = "1.0.79"
 simplelog = "0.12.0"
 simplelog = "0.12.0"

+ 19 - 0
bin/darkfid2/src/main.rs

@@ -28,6 +28,7 @@ use darkfi::{
         util::Timestamp,
         util::Timestamp,
         ValidatorState, MAINNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_HASH_BYTES,
         ValidatorState, MAINNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_HASH_BYTES,
     },
     },
+    crypto::token_list::{DrkTokenList, TokenList},
     net,
     net,
     net::P2pPtr,
     net::P2pPtr,
     node::{Client, State},
     node::{Client, State},
@@ -142,6 +143,10 @@ pub struct Darkfid {
     sync_p2p: Option<P2pPtr>,
     sync_p2p: Option<P2pPtr>,
     validator_state: ValidatorStatePtr,
     validator_state: ValidatorStatePtr,
     state: Arc<Mutex<State>>,
     state: Arc<Mutex<State>>,
+    drk_tokenlist: DrkTokenList,
+    btc_tokenlist: TokenList,
+    eth_tokenlist: TokenList,
+    sol_tokenlist: TokenList,
 }
 }
 
 
 // JSON-RPC methods
 // JSON-RPC methods
@@ -168,6 +173,7 @@ impl RequestHandler for Darkfid {
             Some("wallet.set_default_address") => {
             Some("wallet.set_default_address") => {
                 return self.set_default_address(req.id, params).await
                 return self.set_default_address(req.id, params).await
             }
             }
+            Some("wallet.get_balances") => return self.get_balances(req.id, params).await,
             Some(_) | None => return jsonrpc::error(MethodNotFound, None, req.id).into(),
             Some(_) | None => return jsonrpc::error(MethodNotFound, None, req.id).into(),
         }
         }
     }
     }
@@ -181,6 +187,15 @@ impl Darkfid {
         consensus_p2p: Option<P2pPtr>,
         consensus_p2p: Option<P2pPtr>,
         sync_p2p: Option<P2pPtr>,
         sync_p2p: Option<P2pPtr>,
     ) -> Result<Self> {
     ) -> Result<Self> {
+        // Parse token lists
+        let btc_tokenlist =
+            TokenList::new(include_bytes!("../../../contrib/token/bitcoin_token_list.min.json"))?;
+        let eth_tokenlist =
+            TokenList::new(include_bytes!("../../../contrib/token/erc20_token_list.min.json"))?;
+        let sol_tokenlist =
+            TokenList::new(include_bytes!("../../../contrib/token/solana_token_list.min.json"))?;
+        let drk_tokenlist = DrkTokenList::new(&sol_tokenlist, &eth_tokenlist, &btc_tokenlist)?;
+
         // Initialize Client
         // Initialize Client
         let client = Client::new(wallet).await?;
         let client = Client::new(wallet).await?;
         let tree = client.get_tree().await?;
         let tree = client.get_tree().await?;
@@ -205,6 +220,10 @@ impl Darkfid {
             sync_p2p,
             sync_p2p,
             validator_state,
             validator_state,
             state,
             state,
+            drk_tokenlist,
+            btc_tokenlist,
+            eth_tokenlist,
+            sol_tokenlist,
         })
         })
     }
     }
 }
 }

+ 4 - 1
bin/darkfid2/src/rpc_misc.rs

@@ -1,6 +1,9 @@
 use serde_json::{json, Value};
 use serde_json::{json, Value};
 
 
-use darkfi::rpc::{jsonrpc, jsonrpc::JsonResult};
+use darkfi::{
+    rpc::{jsonrpc, jsonrpc::JsonResult},
+    Result,
+};
 
 
 use super::Darkfid;
 use super::Darkfid;
 
 

+ 52 - 0
bin/darkfid2/src/rpc_wallet.rs

@@ -1,4 +1,6 @@
+use fxhash::FxHashMap;
 use log::error;
 use log::error;
+use num_bigint::BigUint;
 use serde_json::{json, Value};
 use serde_json::{json, Value};
 
 
 use darkfi::{
 use darkfi::{
@@ -13,6 +15,8 @@ use darkfi::{
             JsonResult,
             JsonResult,
         },
         },
     },
     },
+    util::{decode_base10, encode_base10},
+    Result,
 };
 };
 
 
 use super::Darkfid;
 use super::Darkfid;
@@ -188,4 +192,52 @@ impl Darkfid {
 
 
         jsonrpc::response(json!(true), id).into()
         jsonrpc::response(json!(true), id).into()
     }
     }
+
+    // RPCAPI:
+    // Queries the wallet for known balances.
+    // Returns a map of balances, indexed by `network`, and token ID.
+    // --> {"jsonrpc": "2.0", "method": "wallet.get_balances", "params": [], "id": 1}
+    // <-- {"jsonrpc": "2.0", "result": [{"btc": [100, "Bitcoin"]}, {...}], "id": 1}
+    pub async fn get_balances(&self, id: Value, _params: &[Value]) -> JsonResult {
+        let result: Result<FxHashMap<String, (String, String)>> = async {
+            let balances = self.client.get_balances().await?;
+            let mut symbols: FxHashMap<String, (String, String)> = FxHashMap::default();
+
+            for b in balances.list.iter() {
+                let network: String;
+                let symbol: String;
+
+                let mut amount = BigUint::from(b.value);
+
+                if let Some((net, sym)) = self.drk_tokenlist.symbol_from_id(&b.token_id)? {
+                    network = net.to_string();
+                    symbol = sym;
+                } else {
+                    // TODO: SQL needs to have the mint address for show, not the internal hash.
+                    // TODO: SQL needs to have the network name
+                    network = String::from("UNKNOWN");
+                    symbol = format!("{:?}", b.token_id);
+                }
+
+                if let Some(prev) = symbols.get(&symbol) {
+                    let prev_amnt = decode_base10(&prev.0, 8, true)?;
+                    amount += prev_amnt;
+                }
+
+                let amount = encode_base10(amount, 8);
+                symbols.insert(symbol, (amount, network));
+            }
+
+            Ok(symbols)
+        }
+        .await;
+
+        match result {
+            Ok(res) => jsonrpc::response(json!(res), id).into(),
+            Err(e) => {
+                error!("Failed fetching balances from wallet: {}", e);
+                return jsonrpc::error(InternalError, None, id).into()
+            }
+        }
+    }
 }
 }