Update to LDK 0.0.121
[ldk-sample] / src / convert.rs
index c92a92682013966b441b24141fc78a00673e59ef..686761fffdc97b138361c5b251298e1e628f2596 100644 (file)
-use bitcoin::BlockHash;
-use bitcoin::hashes::hex::FromHex;
+use bitcoin::{Address, BlockHash, Txid};
 use lightning_block_sync::http::JsonResponse;
 use std::convert::TryInto;
+use std::str::FromStr;
 
 pub struct FundedTx {
-    pub changepos: i64,
-    pub hex: String,
+       pub changepos: i64,
+       pub hex: String,
 }
 
 impl TryInto<FundedTx> for JsonResponse {
-    type Error = std::io::Error;
-    fn try_into(self) -> std::io::Result<FundedTx> {
-        Ok(FundedTx {
-            changepos: self.0["changepos"].as_i64().unwrap(),
-            hex: self.0["hex"].as_str().unwrap().to_string(),
-        })
-    }
+       type Error = std::io::Error;
+       fn try_into(self) -> std::io::Result<FundedTx> {
+               Ok(FundedTx {
+                       changepos: self.0["changepos"].as_i64().unwrap(),
+                       hex: self.0["hex"].as_str().unwrap().to_string(),
+               })
+       }
 }
 
 pub struct RawTx(pub String);
 
 impl TryInto<RawTx> for JsonResponse {
-    type Error = std::io::Error;
-    fn try_into(self) -> std::io::Result<RawTx> {
-        Ok(RawTx(self.0.as_str().unwrap().to_string()))
-    }
+       type Error = std::io::Error;
+       fn try_into(self) -> std::io::Result<RawTx> {
+               Ok(RawTx(self.0.as_str().unwrap().to_string()))
+       }
 }
 
 pub struct SignedTx {
-    pub complete: bool,
-    pub hex: String,
+       pub complete: bool,
+       pub hex: String,
 }
 
 impl TryInto<SignedTx> for JsonResponse {
-    type Error = std::io::Error;
-    fn try_into(self) -> std::io::Result<SignedTx> {
-        Ok(SignedTx {
-            hex: self.0["hex"].as_str().unwrap().to_string(),
-            complete: self.0["complete"].as_bool().unwrap(),
-        })
-    }
+       type Error = std::io::Error;
+       fn try_into(self) -> std::io::Result<SignedTx> {
+               Ok(SignedTx {
+                       hex: self.0["hex"].as_str().unwrap().to_string(),
+                       complete: self.0["complete"].as_bool().unwrap(),
+               })
+       }
 }
 
 pub struct NewAddress(pub String);
 impl TryInto<NewAddress> for JsonResponse {
-    type Error = std::io::Error;
-    fn try_into(self) -> std::io::Result<NewAddress> {
-        Ok(NewAddress(self.0.as_str().unwrap().to_string()))
-    }
+       type Error = std::io::Error;
+       fn try_into(self) -> std::io::Result<NewAddress> {
+               Ok(NewAddress(self.0.as_str().unwrap().to_string()))
+       }
 }
 
 pub struct FeeResponse {
-    pub feerate: Option<u32>,
-    pub errored: bool,
+       pub feerate_sat_per_kw: Option<u32>,
+       pub errored: bool,
 }
 
 impl TryInto<FeeResponse> for JsonResponse {
-    type Error = std::io::Error;
-    fn try_into(self) -> std::io::Result<FeeResponse> {
-        let errored = !self.0["errors"].is_null();
-        Ok(FeeResponse {
-            errored,
-            feerate: match errored {
-                true => None,
-                // The feerate from bitcoind is in BTC/kb, and we want satoshis/kb.
-                false => Some((self.0["feerate"].as_f64().unwrap() * 100_000_000.0).round() as u32)
-            }
-        })
-    }
+       type Error = std::io::Error;
+       fn try_into(self) -> std::io::Result<FeeResponse> {
+               let errored = !self.0["errors"].is_null();
+               Ok(FeeResponse {
+                       errored,
+                       feerate_sat_per_kw: match self.0["feerate"].as_f64() {
+                               // Bitcoin Core gives us a feerate in BTC/KvB, which we need to convert to
+                               // satoshis/KW. Thus, we first multiply by 10^8 to get satoshis, then divide by 4
+                               // to convert virtual-bytes into weight units.
+                               Some(feerate_btc_per_kvbyte) => {
+                                       Some((feerate_btc_per_kvbyte * 100_000_000.0 / 4.0).round() as u32)
+                               }
+                               None => None,
+                       },
+               })
+       }
+}
+
+pub struct MempoolMinFeeResponse {
+       pub feerate_sat_per_kw: Option<u32>,
+       pub errored: bool,
+}
+
+impl TryInto<MempoolMinFeeResponse> for JsonResponse {
+       type Error = std::io::Error;
+       fn try_into(self) -> std::io::Result<MempoolMinFeeResponse> {
+               let errored = !self.0["errors"].is_null();
+               assert_eq!(self.0["maxmempool"].as_u64(), Some(300000000));
+               Ok(MempoolMinFeeResponse {
+                       errored,
+                       feerate_sat_per_kw: match self.0["mempoolminfee"].as_f64() {
+                               // Bitcoin Core gives us a feerate in BTC/KvB, which we need to convert to
+                               // satoshis/KW. Thus, we first multiply by 10^8 to get satoshis, then divide by 4
+                               // to convert virtual-bytes into weight units.
+                               Some(feerate_btc_per_kvbyte) => {
+                                       Some((feerate_btc_per_kvbyte * 100_000_000.0 / 4.0).round() as u32)
+                               }
+                               None => None,
+                       },
+               })
+       }
 }
 
 pub struct BlockchainInfo {
-    pub latest_height: usize,
-    pub latest_blockhash: BlockHash,
+       pub latest_height: usize,
+       pub latest_blockhash: BlockHash,
+       pub chain: String,
 }
 
 impl TryInto<BlockchainInfo> for JsonResponse {
-    type Error = std::io::Error;
-    fn try_into(self) -> std::io::Result<BlockchainInfo> {
-        Ok(BlockchainInfo {
-            latest_height: self.0["blocks"].as_u64().unwrap() as usize,
-            latest_blockhash: BlockHash::from_hex(self.0["bestblockhash"].as_str().unwrap()).unwrap(),
-        })
-    }
+       type Error = std::io::Error;
+       fn try_into(self) -> std::io::Result<BlockchainInfo> {
+               Ok(BlockchainInfo {
+                       latest_height: self.0["blocks"].as_u64().unwrap() as usize,
+                       latest_blockhash: BlockHash::from_str(self.0["bestblockhash"].as_str().unwrap())
+                               .unwrap(),
+                       chain: self.0["chain"].as_str().unwrap().to_string(),
+               })
+       }
+}
+
+pub struct ListUnspentUtxo {
+       pub txid: Txid,
+       pub vout: u32,
+       pub amount: u64,
+       pub address: Address,
+}
+
+pub struct ListUnspentResponse(pub Vec<ListUnspentUtxo>);
+
+impl TryInto<ListUnspentResponse> for JsonResponse {
+       type Error = std::io::Error;
+       fn try_into(self) -> Result<ListUnspentResponse, Self::Error> {
+               let utxos = self
+                       .0
+                       .as_array()
+                       .unwrap()
+                       .iter()
+                       .map(|utxo| ListUnspentUtxo {
+                               txid: Txid::from_str(&utxo["txid"].as_str().unwrap().to_string()).unwrap(),
+                               vout: utxo["vout"].as_u64().unwrap() as u32,
+                               amount: bitcoin::Amount::from_btc(utxo["amount"].as_f64().unwrap())
+                                       .unwrap()
+                                       .to_sat(),
+                               address: Address::from_str(&utxo["address"].as_str().unwrap().to_string())
+                                       .unwrap()
+                                       .assume_checked(), // the expected network is not known at this point
+                       })
+                       .collect();
+               Ok(ListUnspentResponse(utxos))
+       }
 }