Prechádzať zdrojové kódy

darkfid: Update to new RPC dependencies.

parazyd 3 rokov pred
rodič
commit
db607de661

+ 1 - 1
bin/darkfid/Cargo.toml

@@ -16,8 +16,8 @@ darkfi = {path = "../../", features = ["blockchain", "wallet", "rpc", "net", "zk
 darkfi-sdk = {path = "../../src/sdk"}
 darkfi-serial = {path = "../../src/serial"}
 log = "0.4.20"
-serde_json = "1.0.105"
 sled = "0.34.7"
+tinyjson = "2.5.1"
 url = "2.4.0"
 
 # Daemon

+ 3 - 5
bin/darkfid/src/error.rs

@@ -16,8 +16,6 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-use serde_json::Value;
-
 use darkfi::rpc::jsonrpc::{ErrorCode::ServerError, JsonError, JsonResult};
 
 /// Custom RPC errors available for darkfid.
@@ -48,7 +46,7 @@ pub enum RpcError {
     ContractZkasDbNotFound = -32200,
 }
 
-fn to_tuple(e: RpcError) -> (i64, String) {
+fn to_tuple(e: RpcError) -> (i32, String) {
     let msg = match e {
         /*
         // Wallet/Key-related errors
@@ -72,10 +70,10 @@ fn to_tuple(e: RpcError) -> (i64, String) {
         RpcError::ContractZkasDbNotFound => "zkas database not found for given contract",
     };
 
-    (e as i64, msg.to_string())
+    (e as i32, msg.to_string())
 }
 
-pub fn server_error(e: RpcError, id: Value, msg: Option<&str>) -> JsonResult {
+pub fn server_error(e: RpcError, id: u16, msg: Option<&str>) -> JsonResult {
     let (code, default_msg) = to_tuple(e);
 
     if let Some(message) = msg {

+ 24 - 37
bin/darkfid/src/main.rs

@@ -45,10 +45,7 @@ use darkfi::{
     net::P2pPtr,
     rpc::{
         clock_sync::check_clock,
-        jsonrpc::{
-            ErrorCode::{InvalidParams, MethodNotFound},
-            JsonError, JsonRequest, JsonResult,
-        },
+        jsonrpc::{ErrorCode::MethodNotFound, JsonError, JsonRequest, JsonResult},
         server::{listen_and_serve, RequestHandler},
     },
     util::path::expand_path,
@@ -203,66 +200,56 @@ mod rpc_wallet;
 #[async_trait]
 impl RequestHandler for Darkfid {
     async fn handle_request(&self, req: JsonRequest) -> JsonResult {
-        if !req.params.is_array() {
-            return JsonError::new(InvalidParams, None, req.id).into()
-        }
-
-        let params = req.params.as_array().unwrap();
-
         match req.method.as_str() {
             // =====================
             // Miscellaneous methods
             // =====================
-            Some("ping") => return self.misc_pong(req.id, params).await,
-            Some("clock") => return self.misc_clock(req.id, params).await,
-            Some("sync_dnet_switch") => return self.misc_sync_dnet_switch(req.id, params).await,
-            Some("sync_dnet_info") => return self.misc_sync_dnet_info(req.id, params).await,
-            Some("consensus_dnet_switch") => {
-                return self.misc_consensus_dnet_switch(req.id, params).await
-            }
-            Some("consensus_dnet_info") => {
-                return self.misc_consensus_dnet_info(req.id, params).await
+            "ping" => return self.pong(req.id, req.params).await,
+            "clock" => return self.misc_clock(req.id, req.params).await,
+            "sync_dnet_switch" => return self.misc_sync_dnet_switch(req.id, req.params).await,
+            "consensus_dnet_switch" => {
+                return self.misc_consensus_dnet_switch(req.id, req.params).await
             }
 
             // ==================
             // Blockchain methods
             // ==================
-            Some("blockchain.get_slot") => return self.blockchain_get_slot(req.id, params).await,
-            Some("blockchain.get_tx") => return self.blockchain_get_tx(req.id, params).await,
-            Some("blockchain.last_known_slot") => {
-                return self.blockchain_last_known_slot(req.id, params).await
+            "blockchain.get_slot" => return self.blockchain_get_slot(req.id, req.params).await,
+            "blockchain.get_tx" => return self.blockchain_get_tx(req.id, req.params).await,
+            "blockchain.last_known_slot" => {
+                return self.blockchain_last_known_slot(req.id, req.params).await
             }
-            Some("blockchain.subscribe_blocks") => {
-                return self.blockchain_subscribe_blocks(req.id, params).await
+            "blockchain.subscribe_blocks" => {
+                return self.blockchain_subscribe_blocks(req.id, req.params).await
             }
-            Some("blockchain.subscribe_err_txs") => {
-                return self.blockchain_subscribe_err_txs(req.id, params).await
+            "blockchain.subscribe_err_txs" => {
+                return self.blockchain_subscribe_err_txs(req.id, req.params).await
             }
-            Some("blockchain.lookup_zkas") => {
-                return self.blockchain_lookup_zkas(req.id, params).await
+            "blockchain.lookup_zkas" => {
+                return self.blockchain_lookup_zkas(req.id, req.params).await
             }
 
             // ===================
             // Transaction methods
             // ===================
-            Some("tx.simulate") => return self.tx_simulate(req.id, params).await,
-            Some("tx.broadcast") => return self.tx_broadcast(req.id, params).await,
+            "tx.simulate" => return self.tx_simulate(req.id, req.params).await,
+            "tx.broadcast" => return self.tx_broadcast(req.id, req.params).await,
 
             // ==============
             // Wallet methods
             // ==============
-            Some("wallet.exec_sql") => return self.wallet_exec_sql(req.id, params).await,
-            Some("wallet.query_row_single") => {
-                return self.wallet_query_row_single(req.id, params).await
+            "wallet.exec_sql" => return self.wallet_exec_sql(req.id, req.params).await,
+            "wallet.query_row_single" => {
+                return self.wallet_query_row_single(req.id, req.params).await
             }
-            Some("wallet.query_row_multi") => {
-                return self.wallet_query_row_multi(req.id, params).await
+            "wallet.query_row_multi" => {
+                return self.wallet_query_row_multi(req.id, req.params).await
             }
 
             // ==============
             // Invalid method
             // ==============
-            Some(_) | None => return JsonError::new(MethodNotFound, None, req.id).into(),
+            _ => return JsonError::new(MethodNotFound, None, req.id).into(),
         }
     }
 }

+ 51 - 50
bin/darkfid/src/rpc_blockchain.rs

@@ -21,14 +21,15 @@ use std::str::FromStr;
 use darkfi_sdk::crypto::ContractId;
 use darkfi_serial::{deserialize, serialize};
 use log::{debug, error};
-use serde_json::{json, Value};
+use tinyjson::JsonValue;
 
 use darkfi::{
     rpc::jsonrpc::{
         ErrorCode::{InternalError, InvalidParams, ParseError},
-        JsonError, JsonResponse, JsonResult, JsonSubscriber,
+        JsonError, JsonResponse, JsonResult,
     },
     runtime::vm_runtime::SMART_CONTRACT_ZKAS_DB_NAME,
+    util::encoding::base64,
 };
 
 use super::Darkfid;
@@ -40,20 +41,25 @@ impl Darkfid {
     // Returns a readable block upon success.
     //
     // **Params:**
-    // * `array[0]`: `u64` slot ID
+    // * `array[0]`: `u64` slot ID (as string)
     //
     // **Returns:**
     // * [`BlockInfo`](https://darkrenaissance.github.io/darkfi/development/darkfi/consensus/block/struct.BlockInfo.html)
-    //   struct as a JSON object
+    //   struct serialized into base64.
     //
-    // --> {"jsonrpc": "2.0", "method": "blockchain.get_slot", "params": [0], "id": 1}
-    // <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
-    pub async fn blockchain_get_slot(&self, id: Value, params: &[Value]) -> JsonResult {
-        if params.len() != 1 || !params[0].is_u64() {
+    // --> {"jsonrpc": "2.0", "method": "blockchain.get_slot", "params": ["0"], "id": 1}
+    // <-- {"jsonrpc": "2.0", "result": "ABCD...", "id": 1}
+    pub async fn blockchain_get_slot(&self, id: u16, params: JsonValue) -> JsonResult {
+        let params = params.get::<Vec<JsonValue>>().unwrap();
+        if params.len() != 1 || !params[0].is_string() {
             return JsonError::new(InvalidParams, None, id).into()
         }
 
-        let slot = params[0].as_u64().unwrap();
+        let slot = match u64::from_str_radix(params[0].get::<String>().unwrap(), 10) {
+            Ok(v) => v,
+            Err(_) => return JsonError::new(ParseError, None, id).into(),
+        };
+
         let validator_state = self.validator_state.read().await;
 
         let blocks = match validator_state.blockchain.get_blocks_by_slot(&[slot]) {
@@ -71,7 +77,8 @@ impl Darkfid {
             return server_error(RpcError::UnknownSlot, id, None)
         }
 
-        JsonResponse::new(json!(serialize(&blocks[0])), id).into()
+        let block = base64::encode(&serialize(&blocks[0]));
+        JsonResponse::new(JsonValue::String(block), id).into()
     }
 
     // RPCAPI:
@@ -87,21 +94,16 @@ impl Darkfid {
     //
     // --> {"jsonrpc": "2.0", "method": "blockchain.get_tx", "params": ["TxHash"], "id": 1}
     // <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
-    pub async fn blockchain_get_tx(&self, id: Value, params: &[Value]) -> JsonResult {
-        if params.len() != 1 {
+    pub async fn blockchain_get_tx(&self, id: u16, params: JsonValue) -> JsonResult {
+        let params = params.get::<Vec<JsonValue>>().unwrap();
+        if params.len() != 1 || !params[0].is_string() {
             return JsonError::new(InvalidParams, None, id).into()
         }
 
-        let tx_hash_str = if let Some(tx_hash_str) = params[0].as_str() {
-            tx_hash_str
-        } else {
-            return JsonError::new(InvalidParams, None, id).into()
-        };
-
-        let tx_hash = if let Ok(tx_hash) = blake3::Hash::from_hex(tx_hash_str) {
-            tx_hash
-        } else {
-            return JsonError::new(ParseError, None, id).into()
+        let tx_hash = params[0].get::<String>().unwrap();
+        let tx_hash = match blake3::Hash::from_hex(tx_hash) {
+            Ok(v) => v,
+            Err(_) => return JsonError::new(ParseError, None, id).into(),
         };
 
         let validator_state = self.validator_state.read().await;
@@ -116,12 +118,14 @@ impl Darkfid {
                 return JsonError::new(InternalError, None, id).into()
             }
         };
+
         // This would be an logic error somewhere
         assert_eq!(txs.len(), 1);
         // and strict was used during .get()
         let tx = txs[0].as_ref().unwrap();
 
-        JsonResponse::new(json!(serialize(tx)), id).into()
+        let tx_enc = base64::encode(&serialize(tx));
+        JsonResponse::new(JsonValue::String(tx_enc), id).into()
     }
 
     // RPCAPI:
@@ -131,11 +135,12 @@ impl Darkfid {
     // * `None`
     //
     // **Returns:**
-    // * `u64` ID of the last known slot
+    // * `u64` ID of the last known slot, as string
     //
     // --> {"jsonrpc": "2.0", "method": "blockchain.last_known_slot", "params": [], "id": 1}
-    // <-- {"jsonrpc": "2.0", "result": 1234, "id": 1}
-    pub async fn blockchain_last_known_slot(&self, id: Value, params: &[Value]) -> JsonResult {
+    // <-- {"jsonrpc": "2.0", "result": "1234", "id": 1}
+    pub async fn blockchain_last_known_slot(&self, id: u16, params: JsonValue) -> JsonResult {
+        let params = params.get::<Vec<JsonValue>>().unwrap();
         if !params.is_empty() {
             return JsonError::new(InvalidParams, None, id).into()
         }
@@ -145,7 +150,7 @@ impl Darkfid {
             return JsonError::new(InternalError, None, id).into()
         };
 
-        JsonResponse::new(json!(last_slot.0), id).into()
+        JsonResponse::new(JsonValue::String(last_slot.0.to_string()), id).into()
     }
 
     // RPCAPI:
@@ -155,15 +160,13 @@ impl Darkfid {
     //
     // --> {"jsonrpc": "2.0", "method": "blockchain.subscribe_blocks", "params": [], "id": 1}
     // <-- {"jsonrpc": "2.0", "method": "blockchain.subscribe_blocks", "params": [`blockinfo`]}
-    pub async fn blockchain_subscribe_blocks(&self, id: Value, params: &[Value]) -> JsonResult {
+    pub async fn blockchain_subscribe_blocks(&self, id: u16, params: JsonValue) -> JsonResult {
+        let params = params.get::<Vec<JsonValue>>().unwrap();
         if !params.is_empty() {
             return JsonError::new(InvalidParams, None, id).into()
         }
 
-        let blocks_subscriber =
-            self.validator_state.read().await.subscribers.get("blocks").unwrap().clone();
-
-        JsonSubscriber::new(blocks_subscriber).into()
+        self.validator_state.read().await.subscribers.get("blocks").unwrap().clone().into()
     }
 
     // RPCAPI:
@@ -173,15 +176,13 @@ impl Darkfid {
     //
     // --> {"jsonrpc": "2.0", "method": "blockchain.subscribe_err_txs", "params": [], "id": 1}
     // <-- {"jsonrpc": "2.0", "method": "blockchain.subscribe_err_txs", "params": [`tx_hash`]}
-    pub async fn blockchain_subscribe_err_txs(&self, id: Value, params: &[Value]) -> JsonResult {
+    pub async fn blockchain_subscribe_err_txs(&self, id: u16, params: JsonValue) -> JsonResult {
+        let params = params.get::<Vec<JsonValue>>().unwrap();
         if !params.is_empty() {
             return JsonError::new(InvalidParams, None, id).into()
         }
 
-        let err_txs_subscriber =
-            self.validator_state.read().await.subscribers.get("err_txs").unwrap().clone();
-
-        JsonSubscriber::new(err_txs_subscriber).into()
+        self.validator_state.read().await.subscribers.get("err_txs").unwrap().clone().into()
     }
 
     // RPCAPI:
@@ -192,18 +193,20 @@ impl Darkfid {
     // * `array[0]`: base58-encoded contract ID string
     //
     // **Returns:**
-    // * `array[n]`: Pairs of: `zkas_namespace` string, serialized
+    // * `array[n]`: Pairs of: `zkas_namespace` string, serialized and base64-encoded
     //   [`ZkBinary`](https://darkrenaissance.github.io/darkfi/development/darkfi/zkas/decoder/struct.ZkBinary.html)
     //   object
     //
     // --> {"jsonrpc": "2.0", "method": "blockchain.lookup_zkas", "params": ["6Ef42L1KLZXBoxBuCDto7coi9DA2D2SRtegNqNU4sd74"], "id": 1}
-    // <-- {"jsonrpc": "2.0", "result": [["Foo", [...]], ["Bar", [...]]], "id": 1}
-    pub async fn blockchain_lookup_zkas(&self, id: Value, params: &[Value]) -> JsonResult {
+    // <-- {"jsonrpc": "2.0", "result": [["Foo", "ABCD..."], ["Bar", "EFGH..."]], "id": 1}
+    pub async fn blockchain_lookup_zkas(&self, id: u16, params: JsonValue) -> JsonResult {
+        let params = params.get::<Vec<JsonValue>>().unwrap();
         if params.len() != 1 || !params[0].is_string() {
             return JsonError::new(InvalidParams, None, id).into()
         }
 
-        let contract_id = match ContractId::from_str(params[0].as_str().unwrap()) {
+        let contract_id = params[0].get::<String>().unwrap();
+        let contract_id = match ContractId::from_str(contract_id) {
             Ok(v) => v,
             Err(e) => {
                 error!("[RPC] blockchain.lookup_zkas: Error decoding string to ContractId: {}", e);
@@ -225,7 +228,7 @@ impl Darkfid {
             return server_error(RpcError::ContractZkasDbNotFound, id, None)
         };
 
-        let mut ret: Vec<(String, Vec<u8>)> = vec![];
+        let mut ret = vec![];
 
         for i in zkas_db.iter() {
             debug!("Iterating over zkas db");
@@ -238,15 +241,13 @@ impl Darkfid {
                 return JsonError::new(InternalError, None, id).into()
             };
 
-            let Ok((zkas_bincode, _)): Result<(Vec<u8>, Vec<u8>), std::io::Error> =
-                deserialize(&zkas_bytes)
-            else {
-                return JsonError::new(InternalError, None, id).into()
-            };
-
-            ret.push((zkas_ns, zkas_bincode.to_vec()));
+            let zkas_bincode = base64::encode(&zkas_bytes);
+            ret.push(JsonValue::Array(vec![
+                JsonValue::String(zkas_ns),
+                JsonValue::String(zkas_bincode),
+            ]));
         }
 
-        JsonResponse::new(json!(ret), id).into()
+        JsonResponse::new(JsonValue::Array(ret), id).into()
     }
 }

+ 17 - 51
bin/darkfid/src/rpc_misc.rs

@@ -16,10 +16,9 @@
  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  */
 
-use serde_json::{json, Value};
+use tinyjson::JsonValue;
 
 use darkfi::{
-    net::P2p,
     rpc::jsonrpc::{ErrorCode, JsonError, JsonResponse, JsonResult},
     util::time::Timestamp,
 };
@@ -28,21 +27,12 @@ use super::Darkfid;
 
 impl Darkfid {
     // RPCAPI:
-    // Returns a `pong` to the `ping` request.
-    //
-    // --> {"jsonrpc": "2.0", "method": "ping", "params": [], "id": 1}
-    // <-- {"jsonrpc": "2.0", "result": "pong", "id": 1}
-    pub async fn misc_pong(&self, id: Value, _params: &[Value]) -> JsonResult {
-        JsonResponse::new(json!("pong"), id).into()
-    }
-
-    // RPCAPI:
-    // Returns current system clock in `Timestamp` format.
+    // Returns current system clock as u64 (string) timestamp
     //
     // --> {"jsonrpc": "2.0", "method": "clock", "params": [], "id": 1}
-    // <-- {"jsonrpc": "2.0", "result": {...}, "id": 1}
-    pub async fn misc_clock(&self, id: Value, _params: &[Value]) -> JsonResult {
-        JsonResponse::new(json!(Timestamp::current_time()), id).into()
+    // <-- {"jsonrpc": "2.0", "result": "1234"}, "id": 1}
+    pub async fn misc_clock(&self, id: u16, _params: JsonValue) -> JsonResult {
+        JsonResponse::new(JsonValue::String(Timestamp::current_time().0.to_string()), id).into()
     }
 
     // RPCAPI:
@@ -52,33 +42,21 @@ impl Darkfid {
     //
     // --> {"jsonrpc": "2.0", "method": "sync_dnet_switch", "params": [true], "id": 42}
     // <-- {"jsonrpc": "2.0", "result": true, "id": 42}
-    pub async fn misc_sync_dnet_switch(&self, id: Value, params: &[Value]) -> JsonResult {
-        if params.len() != 1 && params[0].as_bool().is_none() {
+    pub async fn misc_sync_dnet_switch(&self, id: u16, params: JsonValue) -> JsonResult {
+        let params = params.get::<Vec<JsonValue>>().unwrap();
+        if params.len() != 1 || !params[0].is_bool() {
             return JsonError::new(ErrorCode::InvalidParams, None, id).into()
         }
 
-        // FIXME: Unwrapping here because lazy
+        let switch = params[0].get::<bool>().unwrap();
 
-        if params[0].as_bool().unwrap() {
+        if *switch {
             self.sync_p2p.as_ref().unwrap().dnet_enable().await;
         } else {
             self.sync_p2p.as_ref().unwrap().dnet_disable().await;
         }
 
-        JsonResponse::new(json!(true), id).into()
-    }
-
-    // RPCAPI:
-    // Returns sync P2P network information.
-    //
-    // --> {"jsonrpc": "2.0", "method": "sync_dnet_info", "params": [], "id": 42}
-    // <-- {"jsonrpc": "2.0", result": {"nodeID": [], "nodeinfo": [], "id": 42}
-    pub async fn misc_sync_dnet_info(&self, id: Value, _params: &[Value]) -> JsonResult {
-        let resp = match &self.sync_p2p {
-            Some(p2p) => P2p::map_dnet_info(p2p.dnet_info().await),
-            None => json!([]),
-        };
-        JsonResponse::new(resp, id).into()
+        JsonResponse::new(JsonValue::Boolean(true), id).into()
     }
 
     // RPCAPI:
@@ -88,32 +66,20 @@ impl Darkfid {
     //
     // --> {"jsonrpc": "2.0", "method": "consensus_dnet_switch", "params": [true], "id": 42}
     // <-- {"jsonrpc": "2.0", "result": true, "id": 42}
-    pub async fn misc_consensus_dnet_switch(&self, id: Value, params: &[Value]) -> JsonResult {
-        if params.len() != 1 && params[0].as_bool().is_none() {
+    pub async fn misc_consensus_dnet_switch(&self, id: u16, params: JsonValue) -> JsonResult {
+        let params = params.get::<Vec<JsonValue>>().unwrap();
+        if params.len() != 1 || !params[0].is_bool() {
             return JsonError::new(ErrorCode::InvalidParams, None, id).into()
         }
 
-        // FIXME: Unwrapping here because lazy
+        let switch = params[0].get::<bool>().unwrap();
 
-        if params[0].as_bool().unwrap() {
+        if *switch {
             self.consensus_p2p.as_ref().unwrap().dnet_enable().await;
         } else {
             self.consensus_p2p.as_ref().unwrap().dnet_disable().await;
         }
 
-        JsonResponse::new(json!(true), id).into()
-    }
-
-    // RPCAPI:
-    // Returns consensus P2P network information.
-    //
-    // --> {"jsonrpc": "2.0", "method": "consensus_dnet_info", "params": [], "id": 42}
-    // <-- {"jsonrpc": "2.0", result": {"nodeID": [], "nodeinfo": [], "id": 42}
-    pub async fn misc_consensus_dnet_info(&self, id: Value, _params: &[Value]) -> JsonResult {
-        let resp = match &self.consensus_p2p {
-            Some(p2p) => P2p::map_dnet_info(p2p.dnet_info().await),
-            None => json!([]),
-        };
-        JsonResponse::new(resp, id).into()
+        JsonResponse::new(JsonValue::Boolean(true), id).into()
     }
 }

+ 18 - 13
bin/darkfid/src/rpc_tx.rs

@@ -18,11 +18,12 @@
 
 use darkfi_serial::deserialize;
 use log::{error, warn};
-use serde_json::{json, Value};
+use tinyjson::JsonValue;
 
 use darkfi::{
     rpc::jsonrpc::{ErrorCode::InvalidParams, JsonError, JsonResponse, JsonResult},
     tx::Transaction,
+    util::encoding::base64,
 };
 
 use super::Darkfid;
@@ -36,7 +37,8 @@ impl Darkfid {
     //
     // --> {"jsonrpc": "2.0", "method": "tx.simulate", "params": ["base58encodedTX"], "id": 1}
     // <-- {"jsonrpc": "2.0", "result": true, "id": 1}
-    pub async fn tx_simulate(&self, id: Value, params: &[Value]) -> JsonResult {
+    pub async fn tx_simulate(&self, id: u16, params: JsonValue) -> JsonResult {
+        let params = params.get::<Vec<JsonValue>>().unwrap();
         if params.len() != 1 || !params[0].is_string() {
             return JsonError::new(InvalidParams, None, id).into()
         }
@@ -47,10 +49,11 @@ impl Darkfid {
         }
 
         // Try to deserialize the transaction
-        let tx_bytes = match bs58::decode(params[0].as_str().unwrap().trim()).into_vec() {
-            Ok(v) => v,
-            Err(e) => {
-                error!("[RPC] tx.simulate: Failed decoding base58 transaction: {}", e);
+        let tx_enc = params[0].get::<String>().unwrap();
+        let tx_bytes = match base64::decode(&tx_enc.trim()) {
+            Some(v) => v,
+            None => {
+                error!("[RPC] tx.simulate: Failed decoding base64 transaction");
                 return server_error(RpcError::ParseError, id, None)
             }
         };
@@ -79,7 +82,7 @@ impl Darkfid {
             }
         };
 
-        JsonResponse::new(json!(true), id).into()
+        JsonResponse::new(JsonValue::Boolean(true), id).into()
     }
 
     // RPCAPI:
@@ -90,7 +93,8 @@ impl Darkfid {
     //
     // --> {"jsonrpc": "2.0", "method": "tx.broadcast", "params": ["base58encodedTX"], "id": 1}
     // <-- {"jsonrpc": "2.0", "result": "txID...", "id": 1}
-    pub async fn tx_broadcast(&self, id: Value, params: &[Value]) -> JsonResult {
+    pub async fn tx_broadcast(&self, id: u16, params: JsonValue) -> JsonResult {
+        let params = params.get::<Vec<JsonValue>>().unwrap();
         if params.len() != 1 || !params[0].is_string() {
             return JsonError::new(InvalidParams, None, id).into()
         }
@@ -101,10 +105,11 @@ impl Darkfid {
         }
 
         // Try to deserialize the transaction
-        let tx_bytes = match bs58::decode(params[0].as_str().unwrap().trim()).into_vec() {
-            Ok(v) => v,
-            Err(e) => {
-                error!("[RPC] tx.broadcast: Failed decoding base58 transaction: {}", e);
+        let tx_enc = params[0].get::<String>().unwrap();
+        let tx_bytes = match base64::decode(&tx_enc.trim()) {
+            Some(v) => v,
+            None => {
+                error!("[RPC] tx.broadcast: Failed decoding base64 transaction");
                 return server_error(RpcError::ParseError, id, None)
             }
         };
@@ -154,6 +159,6 @@ impl Darkfid {
         }
 
         let tx_hash = tx.hash().to_string();
-        JsonResponse::new(json!(tx_hash), id).into()
+        JsonResponse::new(JsonValue::String(tx_hash), id).into()
     }
 }

+ 6 - 5
bin/darkfid/src/rpc_wallet.rs

@@ -30,9 +30,10 @@ use darkfi::{
 
 use super::{error::RpcError, server_error, Darkfid};
 */
-use super::Darkfid;
 use darkfi::rpc::jsonrpc::JsonResult;
-use serde_json::Value;
+use tinyjson::JsonValue;
+
+use super::Darkfid;
 
 impl Darkfid {
     // RPCAPI:
@@ -54,7 +55,7 @@ impl Darkfid {
     //
     // --> {"jsonrpc": "2.0", "method": "wallet.query_row_single", "params": [...], "id": 1}
     // <-- {"jsonrpc": "2.0", "result": ["va", "lu", "es", ...], "id": 1}
-    pub async fn wallet_query_row_single(&self, _id: Value, _params: &[Value]) -> JsonResult {
+    pub async fn wallet_query_row_single(&self, _id: u16, _params: JsonValue) -> JsonResult {
         todo!();
         /* TODO: This will be abstracted away
         // We need at least 3 params for something we want to fetch, and we want them in pairs.
@@ -207,7 +208,7 @@ impl Darkfid {
     //
     // --> {"jsonrpc": "2.0", "method": "wallet.query_row_multi", "params": [...], "id": 1}
     // <-- {"jsonrpc": "2.0", "result": [["va", "lu"], ["es", "es"], ...], "id": 1}
-    pub async fn wallet_query_row_multi(&self, _id: Value, _params: &[Value]) -> JsonResult {
+    pub async fn wallet_query_row_multi(&self, _id: u16, _params: JsonValue) -> JsonResult {
         todo!();
         /* TODO: This will be abstracted away
         // We need at least 3 params for something we want to fetch, and we want them in pairs.
@@ -331,7 +332,7 @@ impl Darkfid {
     //
     // --> {"jsonrpc": "2.0", "method": "wallet.exec_sql", "params": ["CREATE TABLE ..."], "id": 1}
     // <-- {"jsonrpc": "2.0", "result": true, "id": 1}
-    pub async fn wallet_exec_sql(&self, _id: Value, _params: &[Value]) -> JsonResult {
+    pub async fn wallet_exec_sql(&self, _id: u16, _params: JsonValue) -> JsonResult {
         todo!();
         /* TODO: This will be abstracted away
         if params.is_empty() || !params[0].is_string() {