7f1bf108828753df82a0a754e82c22bc332a8664
[ldk-sample] / src / convert.rs
1 use bitcoin::hashes::hex::FromHex;
2 use bitcoin::{Address, BlockHash, Txid};
3 use lightning_block_sync::http::JsonResponse;
4 use std::convert::TryInto;
5 use std::str::FromStr;
6
7 pub struct FundedTx {
8         pub changepos: i64,
9         pub hex: String,
10 }
11
12 impl TryInto<FundedTx> for JsonResponse {
13         type Error = std::io::Error;
14         fn try_into(self) -> std::io::Result<FundedTx> {
15                 Ok(FundedTx {
16                         changepos: self.0["changepos"].as_i64().unwrap(),
17                         hex: self.0["hex"].as_str().unwrap().to_string(),
18                 })
19         }
20 }
21
22 pub struct RawTx(pub String);
23
24 impl TryInto<RawTx> for JsonResponse {
25         type Error = std::io::Error;
26         fn try_into(self) -> std::io::Result<RawTx> {
27                 Ok(RawTx(self.0.as_str().unwrap().to_string()))
28         }
29 }
30
31 pub struct SignedTx {
32         pub complete: bool,
33         pub hex: String,
34 }
35
36 impl TryInto<SignedTx> for JsonResponse {
37         type Error = std::io::Error;
38         fn try_into(self) -> std::io::Result<SignedTx> {
39                 Ok(SignedTx {
40                         hex: self.0["hex"].as_str().unwrap().to_string(),
41                         complete: self.0["complete"].as_bool().unwrap(),
42                 })
43         }
44 }
45
46 pub struct NewAddress(pub String);
47 impl TryInto<NewAddress> for JsonResponse {
48         type Error = std::io::Error;
49         fn try_into(self) -> std::io::Result<NewAddress> {
50                 Ok(NewAddress(self.0.as_str().unwrap().to_string()))
51         }
52 }
53
54 pub struct FeeResponse {
55         pub feerate_sat_per_kw: Option<u32>,
56         pub errored: bool,
57 }
58
59 impl TryInto<FeeResponse> for JsonResponse {
60         type Error = std::io::Error;
61         fn try_into(self) -> std::io::Result<FeeResponse> {
62                 let errored = !self.0["errors"].is_null();
63                 Ok(FeeResponse {
64                         errored,
65                         feerate_sat_per_kw: match self.0["feerate"].as_f64() {
66                                 // Bitcoin Core gives us a feerate in BTC/KvB, which we need to convert to
67                                 // satoshis/KW. Thus, we first multiply by 10^8 to get satoshis, then divide by 4
68                                 // to convert virtual-bytes into weight units.
69                                 Some(feerate_btc_per_kvbyte) => {
70                                         Some((feerate_btc_per_kvbyte * 100_000_000.0 / 4.0).round() as u32)
71                                 }
72                                 None => None,
73                         },
74                 })
75         }
76 }
77
78 pub struct MempoolMinFeeResponse {
79         pub feerate_sat_per_kw: Option<u32>,
80         pub errored: bool,
81 }
82
83 impl TryInto<MempoolMinFeeResponse> for JsonResponse {
84         type Error = std::io::Error;
85         fn try_into(self) -> std::io::Result<MempoolMinFeeResponse> {
86                 let errored = !self.0["errors"].is_null();
87                 assert_eq!(self.0["maxmempool"].as_u64(), Some(300000000));
88                 Ok(MempoolMinFeeResponse {
89                         errored,
90                         feerate_sat_per_kw: match self.0["mempoolminfee"].as_f64() {
91                                 // Bitcoin Core gives us a feerate in BTC/KvB, which we need to convert to
92                                 // satoshis/KW. Thus, we first multiply by 10^8 to get satoshis, then divide by 4
93                                 // to convert virtual-bytes into weight units.
94                                 Some(feerate_btc_per_kvbyte) => {
95                                         Some((feerate_btc_per_kvbyte * 100_000_000.0 / 4.0).round() as u32)
96                                 }
97                                 None => None,
98                         },
99                 })
100         }
101 }
102
103 pub struct BlockchainInfo {
104         pub latest_height: usize,
105         pub latest_blockhash: BlockHash,
106         pub chain: String,
107 }
108
109 impl TryInto<BlockchainInfo> for JsonResponse {
110         type Error = std::io::Error;
111         fn try_into(self) -> std::io::Result<BlockchainInfo> {
112                 Ok(BlockchainInfo {
113                         latest_height: self.0["blocks"].as_u64().unwrap() as usize,
114                         latest_blockhash: BlockHash::from_hex(self.0["bestblockhash"].as_str().unwrap())
115                                 .unwrap(),
116                         chain: self.0["chain"].as_str().unwrap().to_string(),
117                 })
118         }
119 }
120
121 pub struct ListUnspentUtxo {
122         pub txid: Txid,
123         pub vout: u32,
124         pub amount: u64,
125         pub address: Address,
126 }
127
128 pub struct ListUnspentResponse(pub Vec<ListUnspentUtxo>);
129
130 impl TryInto<ListUnspentResponse> for JsonResponse {
131         type Error = std::io::Error;
132         fn try_into(self) -> Result<ListUnspentResponse, Self::Error> {
133                 let utxos = self
134                         .0
135                         .as_array()
136                         .unwrap()
137                         .iter()
138                         .map(|utxo| ListUnspentUtxo {
139                                 txid: Txid::from_str(&utxo["txid"].as_str().unwrap().to_string()).unwrap(),
140                                 vout: utxo["vout"].as_u64().unwrap() as u32,
141                                 amount: bitcoin::Amount::from_btc(utxo["amount"].as_f64().unwrap())
142                                         .unwrap()
143                                         .to_sat(),
144                                 address: Address::from_str(&utxo["address"].as_str().unwrap().to_string()).unwrap(),
145                         })
146                         .collect();
147                 Ok(ListUnspentResponse(utxos))
148         }
149 }