1use std::collections::HashMap;
12use std::fs::File;
13use std::iter::FromIterator;
14use std::path::PathBuf;
15use std::{fmt, result};
16use serde_json::value::RawValue;
17
18use bitcoincore_rpc_json_async::bitcoin;
19use bitcoincore_rpc_json_async as json;
20use jsonrpc_async as jsonrpc;
21use serde::*;
22use serde_json;
23
24use bitcoin::hashes::hex::{FromHex, ToHex};
25use bitcoin::secp256k1::Signature;
26use bitcoin::{
27 Address, Amount, Block, BlockHeader, OutPoint, PrivateKey, PublicKey, Script, Transaction,
28};
29use log::Level::{Debug, Trace, Warn};
30use log::{log_enabled, debug, trace};
31use async_trait::async_trait;
32
33use crate::error::*;
34use crate::queryable;
35
36pub type Result<T> = result::Result<T, Error>;
39
40#[derive(Clone, Debug, Serialize, Deserialize)]
41struct JsonOutPoint {
42 pub txid: bitcoin::Txid,
43 pub vout: u32,
44}
45
46impl From<OutPoint> for JsonOutPoint {
47 fn from(o: OutPoint) -> JsonOutPoint {
48 JsonOutPoint {
49 txid: o.txid,
50 vout: o.vout,
51 }
52 }
53}
54
55impl Into<OutPoint> for JsonOutPoint {
56 fn into(self) -> OutPoint {
57 OutPoint {
58 txid: self.txid,
59 vout: self.vout,
60 }
61 }
62}
63
64fn into_json<T>(val: T) -> Result<serde_json::Value>
66where
67 T: serde::ser::Serialize,
68{
69 Ok(serde_json::to_value(val)?)
70}
71
72fn opt_into_json<T>(opt: Option<T>) -> Result<serde_json::Value>
74where
75 T: serde::ser::Serialize,
76{
77 match opt {
78 Some(val) => Ok(into_json(val)?),
79 None => Ok(serde_json::Value::Null),
80 }
81}
82
83fn null() -> serde_json::Value {
85 serde_json::Value::Null
86}
87
88fn empty_arr() -> serde_json::Value {
90 serde_json::Value::Array(vec![])
91}
92
93fn empty_obj() -> serde_json::Value {
95 serde_json::Value::Object(Default::default())
96}
97
98fn handle_defaults<'a, 'b>(
114 args: &'a mut [serde_json::Value],
115 defaults: &'b [serde_json::Value],
116) -> &'a [serde_json::Value] {
117 assert!(args.len() >= defaults.len());
118
119 let mut first_non_null_optional_idx = None;
122 for i in 0..defaults.len() {
123 let args_i = args.len() - 1 - i;
124 let defaults_i = defaults.len() - 1 - i;
125 if args[args_i] == serde_json::Value::Null {
126 if first_non_null_optional_idx.is_some() {
127 if defaults[defaults_i] == serde_json::Value::Null {
128 panic!("Missing `default` for argument idx {}", args_i);
129 }
130 args[args_i] = defaults[defaults_i].clone();
131 }
132 } else if first_non_null_optional_idx.is_none() {
133 first_non_null_optional_idx = Some(args_i);
134 }
135 }
136
137 let required_num = args.len() - defaults.len();
138
139 if let Some(i) = first_non_null_optional_idx {
140 &args[..i + 1]
141 } else {
142 &args[..required_num]
143 }
144}
145
146fn opt_result<T: for<'a> serde::de::Deserialize<'a>>(
148 result: serde_json::Value,
149) -> Result<Option<T>> {
150 if result == serde_json::Value::Null {
151 Ok(None)
152 } else {
153 Ok(serde_json::from_value(result)?)
154 }
155}
156
157pub trait RawTx: Sized + Clone {
159 fn raw_hex(self) -> String;
160}
161
162impl<'a> RawTx for &'a Transaction {
163 fn raw_hex(self) -> String {
164 bitcoin::consensus::encode::serialize(self).to_hex()
165 }
166}
167
168impl<'a> RawTx for &'a [u8] {
169 fn raw_hex(self) -> String {
170 self.to_hex()
171 }
172}
173
174impl<'a> RawTx for &'a Vec<u8> {
175 fn raw_hex(self) -> String {
176 self.to_hex()
177 }
178}
179
180impl<'a> RawTx for &'a str {
181 fn raw_hex(self) -> String {
182 self.to_owned()
183 }
184}
185
186impl RawTx for String {
187 fn raw_hex(self) -> String {
188 self
189 }
190}
191
192#[derive(Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
194pub enum Auth {
195 None,
196 UserPass(String, String),
197 CookieFile(PathBuf),
198}
199
200impl Auth {
201 fn get_user_pass(self) -> Result<Option<(String, String)>> {
203 use std::io::Read;
204 match self {
205 Auth::None => Ok(None),
206 Auth::UserPass(u, p) => Ok(Some((u,p))),
207 Auth::CookieFile(path) => {
208 let mut file = File::open(path)?;
209 let mut contents = String::new();
210 file.read_to_string(&mut contents)?;
211 let mut split = contents.splitn(2, ":");
212 let u = split.next().ok_or(Error::InvalidCookieFile)?.into();
213 let p = split.next().ok_or(Error::InvalidCookieFile)?.into();
214 Ok(Some((u, p)))
215 }
216 }
217 }
218}
219
220#[async_trait]
221pub trait RpcApi: Sized {
222 async fn call<T: for<'a> serde::de::Deserialize<'a>>(
224 &self,
225 cmd: &str,
226 args: &[serde_json::Value],
227 ) -> Result<T>;
228
229 async fn get_by_id<T: queryable::Queryable<Self>>(
231 &self,
232 id: &<T as queryable::Queryable<Self>>::Id,
233 ) -> Result<T>
234 where T: Sync + Send ,
235 <T as queryable::Queryable<Self>>::Id : Sync + Send
236 {
237 T::query(&self, &id).await
238 }
239
240 async fn get_network_info(&self) -> Result<json::GetNetworkInfoResult> {
241 self.call("getnetworkinfo", &[]).await
242 }
243
244 async fn version(&self) -> Result<usize> {
245 #[derive(Deserialize)]
246 struct Response {
247 pub version: usize,
248 }
249 let res: Response = self.call("getnetworkinfo", &[]).await?;
250 Ok(res.version)
251 }
252
253 async fn add_multisig_address(
254 &self,
255 nrequired: usize,
256 keys: &[json::PubKeyOrAddress<'_>],
257 label: Option<&str>,
258 address_type: Option<json::AddressType>,
259 ) -> Result<json::AddMultiSigAddressResult> {
260 let mut args = [
261 into_json(nrequired)?,
262 into_json(keys)?,
263 opt_into_json(label)?,
264 opt_into_json(address_type)?,
265 ];
266 self.call("addmultisigaddress", handle_defaults(&mut args, &[into_json("")?, null()])).await
267 }
268
269 async fn load_wallet(&self, wallet: &str) -> Result<json::LoadWalletResult> {
270 self.call("loadwallet", &[wallet.into()]).await
271 }
272
273 async fn unload_wallet(&self, wallet: Option<&str>) -> Result<()> {
274 let mut args = [opt_into_json(wallet)?];
275 self.call("unloadwallet", handle_defaults(&mut args, &[null()])).await
276 }
277
278 async fn create_wallet(
279 &self,
280 wallet: &str,
281 disable_private_keys: Option<bool>,
282 blank: Option<bool>,
283 passphrase: Option<&str>,
284 avoid_reuse: Option<bool>,
285 ) -> Result<json::LoadWalletResult> {
286 let mut args = [
287 wallet.into(),
288 opt_into_json(disable_private_keys)?,
289 opt_into_json(blank)?,
290 opt_into_json(passphrase)?,
291 opt_into_json(avoid_reuse)?,
292 ];
293 self.call(
294 "createwallet",
295 handle_defaults(&mut args, &[false.into(), false.into(), into_json("")?, false.into()]),
296 ).await
297 }
298
299 async fn list_wallets(&self) -> Result<Vec<String>> {
300 self.call("listwallets", &[]).await
301 }
302
303 async fn get_wallet_info(&self) -> Result<json::GetWalletInfoResult> {
304 self.call("getwalletinfo", &[]).await
305 }
306
307 async fn backup_wallet(&self, destination: Option<&str>) -> Result<()> {
308 let mut args = [opt_into_json(destination)?];
309 self.call("backupwallet", handle_defaults(&mut args, &[null()])).await
310 }
311
312 async fn dump_private_key(&self, address: &Address) -> Result<PrivateKey> {
313 self.call("dumpprivkey", &[address.to_string().into()]).await
314 }
315
316 async fn encrypt_wallet(&self, passphrase: &str) -> Result<()> {
317 self.call("encryptwallet", &[into_json(passphrase)?]).await
318 }
319
320 async fn get_difficulty(&self) -> Result<f64> {
321 self.call("getdifficulty", &[]).await
322 }
323
324 async fn get_connection_count(&self) -> Result<usize> {
325 self.call("getconnectioncount", &[]).await
326 }
327
328 async fn get_block(&self, hash: &bitcoin::BlockHash) -> Result<Block> {
329 let hex: String = self.call("getblock", &[into_json(hash)?, 0.into()]).await?;
330 let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
331 Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
332 }
333
334 async fn get_block_hex(&self, hash: &bitcoin::BlockHash) -> Result<String> {
335 self.call("getblock", &[into_json(hash)?, 0.into()]).await
336 }
337
338 async fn get_block_info(&self, hash: &bitcoin::BlockHash) -> Result<json::GetBlockResult> {
339 self.call("getblock", &[into_json(hash)?, 1.into()]).await
340 }
341 async fn get_block_header(&self, hash: &bitcoin::BlockHash) -> Result<BlockHeader> {
344 let hex: String = self.call("getblockheader", &[into_json(hash)?, false.into()]).await?;
345 let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
346 Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
347 }
348
349 async fn get_block_header_info(
350 &self,
351 hash: &bitcoin::BlockHash,
352 ) -> Result<json::GetBlockHeaderResult> {
353 self.call("getblockheader", &[into_json(hash)?, true.into()]).await
354 }
355
356 async fn get_mining_info(&self) -> Result<json::GetMiningInfoResult> {
357 self.call("getmininginfo", &[]).await
358 }
359
360 async fn get_blockchain_info(&self) -> Result<json::GetBlockchainInfoResult> {
363 let mut raw: serde_json::Value = self.call("getblockchaininfo", &[]).await?;
364 Ok(if self.version().await? < 190000 {
368 use Error::UnexpectedStructure as err;
369
370 let (bip9_softforks, old_softforks) = {
373 let map = raw.as_object_mut().ok_or(err)?;
374 let bip9_softforks = map.remove("bip9_softforks").ok_or(err)?;
375 let old_softforks = map.remove("softforks").ok_or(err)?;
376 map.insert("softforks".into(), serde_json::Map::new().into());
378 (bip9_softforks, old_softforks)
379 };
380 let mut ret: json::GetBlockchainInfoResult = serde_json::from_value(raw)?;
381
382 for sf in old_softforks.as_array().ok_or(err)?.iter() {
384 let json = sf.as_object().ok_or(err)?;
385 let id = json.get("id").ok_or(err)?.as_str().ok_or(err)?;
386 let reject = json.get("reject").ok_or(err)?.as_object().ok_or(err)?;
387 let active = reject.get("status").ok_or(err)?.as_bool().ok_or(err)?;
388 ret.softforks.insert(
389 id.into(),
390 json::Softfork {
391 type_: json::SoftforkType::Buried,
392 bip9: None,
393 height: None,
394 active: active,
395 },
396 );
397 }
398 for (id, sf) in bip9_softforks.as_object().ok_or(err)?.iter() {
399 #[derive(Deserialize)]
400 struct OldBip9SoftFork {
401 pub status: json::Bip9SoftforkStatus,
402 pub bit: Option<u8>,
403 #[serde(rename = "startTime")]
404 pub start_time: i64,
405 pub timeout: u64,
406 pub since: u32,
407 pub statistics: Option<json::Bip9SoftforkStatistics>,
408 }
409 let sf: OldBip9SoftFork = serde_json::from_value(sf.clone())?;
410 ret.softforks.insert(
411 id.clone(),
412 json::Softfork {
413 type_: json::SoftforkType::Bip9,
414 bip9: Some(json::Bip9SoftforkInfo {
415 status: sf.status,
416 bit: sf.bit,
417 start_time: sf.start_time,
418 timeout: sf.timeout,
419 since: sf.since,
420 statistics: sf.statistics,
421 }),
422 height: None,
423 active: sf.status == json::Bip9SoftforkStatus::Active,
424 },
425 );
426 }
427 ret
428 } else {
429 serde_json::from_value(raw)?
430 })
431 }
432
433 async fn get_block_count(&self) -> Result<u64> {
435 self.call("getblockcount", &[]).await
436 }
437
438 async fn get_best_block_hash(&self) -> Result<bitcoin::BlockHash> {
440 self.call("getbestblockhash", &[]).await
441 }
442
443 async fn get_block_hash(&self, height: u64) -> Result<bitcoin::BlockHash> {
445 self.call("getblockhash", &[height.into()]).await
446 }
447
448 async fn get_raw_transaction(
449 &self,
450 txid: &bitcoin::Txid,
451 block_hash: Option<&bitcoin::BlockHash>,
452 ) -> Result<Transaction> {
453 let mut args = [into_json(txid)?, into_json(false)?, opt_into_json(block_hash)?];
454 let hex: String = self.call("getrawtransaction", handle_defaults(&mut args, &[null()])).await?;
455 let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
456 Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
457 }
458
459 async fn get_raw_transaction_hex(
460 &self,
461 txid: &bitcoin::Txid,
462 block_hash: Option<&bitcoin::BlockHash>,
463 ) -> Result<String> {
464 let mut args = [into_json(txid)?, into_json(false)?, opt_into_json(block_hash)?];
465 self.call("getrawtransaction", handle_defaults(&mut args, &[null()])).await
466 }
467
468 async fn get_raw_transaction_info(
469 &self,
470 txid: &bitcoin::Txid,
471 block_hash: Option<&bitcoin::BlockHash>,
472 ) -> Result<json::GetRawTransactionResult> {
473 let mut args = [into_json(txid)?, into_json(true)?, opt_into_json(block_hash)?];
474 self.call("getrawtransaction", handle_defaults(&mut args, &[null()])).await
475 }
476
477 async fn get_block_filter(
478 &self,
479 block_hash: &bitcoin::BlockHash,
480 ) -> Result<json::GetBlockFilterResult> {
481 self.call("getblockfilter", &[into_json(block_hash)?]).await
482 }
483
484 async fn get_balance(
485 &self,
486 minconf: Option<usize>,
487 include_watchonly: Option<bool>,
488 ) -> Result<Amount> {
489 let mut args = ["*".into(), opt_into_json(minconf)?, opt_into_json(include_watchonly)?];
490 Ok(Amount::from_btc(
491 self.call("getbalance", handle_defaults(&mut args, &[0.into(), null()])).await?,
492 )?)
493 }
494
495 async fn get_balances(&self) -> Result<json::GetBalancesResult> {
496 Ok(self.call("getbalances", &[]).await?)
497 }
498
499 async fn get_received_by_address(&self, address: &Address, minconf: Option<u32>) -> Result<Amount> {
500 let mut args = [address.to_string().into(), opt_into_json(minconf)?];
501 Ok(Amount::from_btc(
502 self.call("getreceivedbyaddress", handle_defaults(&mut args, &[null()])).await?,
503 )?)
504 }
505
506 async fn get_transaction(
507 &self,
508 txid: &bitcoin::Txid,
509 include_watchonly: Option<bool>,
510 ) -> Result<json::GetTransactionResult> {
511 let mut args = [into_json(txid)?, opt_into_json(include_watchonly)?];
512 self.call("gettransaction", handle_defaults(&mut args, &[null()])).await
513 }
514
515 async fn list_transactions(
516 &self,
517 label: Option<&str>,
518 count: Option<usize>,
519 skip: Option<usize>,
520 include_watchonly: Option<bool>,
521 ) -> Result<Vec<json::ListTransactionResult>> {
522 let mut args = [
523 label.unwrap_or("*").into(),
524 opt_into_json(count)?,
525 opt_into_json(skip)?,
526 opt_into_json(include_watchonly)?,
527 ];
528 self.call("listtransactions", handle_defaults(&mut args, &[10.into(), 0.into(), null()])).await
529 }
530
531 async fn list_since_block(
532 &self,
533 blockhash: Option<&bitcoin::BlockHash>,
534 target_confirmations: Option<usize>,
535 include_watchonly: Option<bool>,
536 include_removed: Option<bool>,
537 ) -> Result<json::ListSinceBlockResult> {
538 let mut args = [
539 opt_into_json(blockhash)?,
540 opt_into_json(target_confirmations)?,
541 opt_into_json(include_watchonly)?,
542 opt_into_json(include_removed)?,
543 ];
544 self.call("listsinceblock", handle_defaults(&mut args, &[null()])).await
545 }
546
547 async fn get_tx_out(
548 &self,
549 txid: &bitcoin::Txid,
550 vout: u32,
551 include_mempool: Option<bool>,
552 ) -> Result<Option<json::GetTxOutResult>> {
553 let mut args = [into_json(txid)?, into_json(vout)?, opt_into_json(include_mempool)?];
554 opt_result(self.call("gettxout", handle_defaults(&mut args, &[null()])).await?)
555 }
556
557 async fn get_tx_out_proof(
558 &self,
559 txids: &[bitcoin::Txid],
560 block_hash: Option<&bitcoin::BlockHash>,
561 ) -> Result<Vec<u8>> {
562 let mut args = [into_json(txids)?, opt_into_json(block_hash)?];
563 let hex: String = self.call("gettxoutproof", handle_defaults(&mut args, &[null()])).await?;
564 Ok(FromHex::from_hex(&hex)?)
565 }
566
567 async fn import_public_key(
568 &self,
569 pubkey: &PublicKey,
570 label: Option<&str>,
571 rescan: Option<bool>,
572 ) -> Result<()> {
573 let mut args = [pubkey.to_string().into(), opt_into_json(label)?, opt_into_json(rescan)?];
574 self.call("importpubkey", handle_defaults(&mut args, &[into_json("")?, null()])).await
575 }
576
577 async fn import_private_key(
578 &self,
579 privkey: &PrivateKey,
580 label: Option<&str>,
581 rescan: Option<bool>,
582 ) -> Result<()> {
583 let mut args = [privkey.to_string().into(), opt_into_json(label)?, opt_into_json(rescan)?];
584 self.call("importprivkey", handle_defaults(&mut args, &[into_json("")?, null()])).await
585 }
586
587 async fn import_address(
588 &self,
589 address: &Address,
590 label: Option<&str>,
591 rescan: Option<bool>,
592 ) -> Result<()> {
593 let mut args = [address.to_string().into(), opt_into_json(label)?, opt_into_json(rescan)?];
594 self.call("importaddress", handle_defaults(&mut args, &[into_json("")?, null()])).await
595 }
596
597 async fn import_address_script(
598 &self,
599 script: &Script,
600 label: Option<&str>,
601 rescan: Option<bool>,
602 p2sh: Option<bool>,
603 ) -> Result<()> {
604 let mut args = [
605 script.to_hex().into(),
606 opt_into_json(label)?,
607 opt_into_json(rescan)?,
608 opt_into_json(p2sh)?,
609 ];
610 self.call(
611 "importaddress",
612 handle_defaults(&mut args, &[into_json("")?, true.into(), null()]),
613 ).await
614 }
615
616 async fn import_multi(
617 &self,
618 requests: &[json::ImportMultiRequest<'_>],
619 options: Option<&json::ImportMultiOptions>,
620 ) -> Result<Vec<json::ImportMultiResult>> {
621 let mut json_requests = Vec::with_capacity(requests.len());
622 for req in requests {
623 json_requests.push(serde_json::to_value(req)?);
624 }
625 let mut args = [json_requests.into(), opt_into_json(options)?];
626 self.call("importmulti", handle_defaults(&mut args, &[null()])).await
627 }
628
629 async fn set_label(&self, address: &Address, label: &str) -> Result<()> {
630 self.call("setlabel", &[address.to_string().into(), label.into()]).await
631 }
632
633 async fn key_pool_refill(&self, new_size: Option<usize>) -> Result<()> {
634 let mut args = [opt_into_json(new_size)?];
635 self.call("keypoolrefill", handle_defaults(&mut args, &[null()])).await
636 }
637
638 async fn list_unspent(
639 &self,
640 minconf: Option<usize>,
641 maxconf: Option<usize>,
642 addresses: Option<&[&Address]>,
643 include_unsafe: Option<bool>,
644 query_options: Option<json::ListUnspentQueryOptions>,
645 ) -> Result<Vec<json::ListUnspentResultEntry>> {
646 let mut args = [
647 opt_into_json(minconf)?,
648 opt_into_json(maxconf)?,
649 opt_into_json(addresses)?,
650 opt_into_json(include_unsafe)?,
651 opt_into_json(query_options)?,
652 ];
653 let defaults = [into_json(0)?, into_json(9999999)?, empty_arr(), into_json(true)?, null()];
654 self.call("listunspent", handle_defaults(&mut args, &defaults)).await
655 }
656
657 async fn lock_unspent(&self, outputs: &[OutPoint]) -> Result<bool> {
659 let outputs: Vec<_> = outputs
660 .into_iter()
661 .map(|o| serde_json::to_value(JsonOutPoint::from(*o)).unwrap())
662 .collect();
663 self.call("lockunspent", &[false.into(), outputs.into()]).await
664 }
665
666 async fn unlock_unspent(&self, outputs: &[OutPoint]) -> Result<bool> {
667 let outputs: Vec<_> = outputs
668 .into_iter()
669 .map(|o| serde_json::to_value(JsonOutPoint::from(*o)).unwrap())
670 .collect();
671 self.call("lockunspent", &[true.into(), outputs.into()]).await
672 }
673
674 async fn list_received_by_address(
675 &self,
676 address_filter: Option<&Address>,
677 minconf: Option<u32>,
678 include_empty: Option<bool>,
679 include_watchonly: Option<bool>,
680 ) -> Result<Vec<json::ListReceivedByAddressResult>> {
681 let mut args = [
682 opt_into_json(minconf)?,
683 opt_into_json(include_empty)?,
684 opt_into_json(include_watchonly)?,
685 opt_into_json(address_filter)?,
686 ];
687 let defaults = [1.into(), false.into(), false.into(), null()];
688 self.call("listreceivedbyaddress", handle_defaults(&mut args, &defaults)).await
689 }
690
691 async fn create_raw_transaction_hex(
692 &self,
693 utxos: &[json::CreateRawTransactionInput],
694 outs: &HashMap<String, Amount>,
695 locktime: Option<i64>,
696 replaceable: Option<bool>,
697 ) -> Result<String> {
698 let outs_converted = serde_json::Map::from_iter(
699 outs.iter().map(|(k, v)| (k.clone(), serde_json::Value::from(v.as_btc()))),
700 );
701 let mut args = [
702 into_json(utxos)?,
703 into_json(outs_converted)?,
704 opt_into_json(locktime)?,
705 opt_into_json(replaceable)?,
706 ];
707 let defaults = [into_json(0i64)?, null()];
708 self.call("createrawtransaction", handle_defaults(&mut args, &defaults)).await
709 }
710
711 async fn create_raw_transaction(
712 &self,
713 utxos: &[json::CreateRawTransactionInput],
714 outs: &HashMap<String, Amount>,
715 locktime: Option<i64>,
716 replaceable: Option<bool>,
717 ) -> Result<Transaction> {
718 let hex: String = self.create_raw_transaction_hex(utxos, outs, locktime, replaceable).await?;
719 let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
720 Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
721 }
722
723 async fn fund_raw_transaction<R: RawTx>(
724 &self,
725 tx: R,
726 options: Option<&json::FundRawTransactionOptions>,
727 is_witness: Option<bool>,
728 ) -> Result<json::FundRawTransactionResult>
729 where R: Sync + Send
730 {
731 let mut args = [tx.raw_hex().into(), opt_into_json(options)?, opt_into_json(is_witness)?];
732 let defaults = [empty_obj(), null()];
733 self.call("fundrawtransaction", handle_defaults(&mut args, &defaults)).await
734 }
735
736 #[deprecated]
737 async fn sign_raw_transaction<R: RawTx>(
738 &self,
739 tx: R,
740 utxos: Option<&[json::SignRawTransactionInput]>,
741 private_keys: Option<&[PrivateKey]>,
742 sighash_type: Option<json::SigHashType>,
743 ) -> Result<json::SignRawTransactionResult>
744 where R: Sync + Send
745 {
746 let mut args = [
747 tx.raw_hex().into(),
748 opt_into_json(utxos)?,
749 opt_into_json(private_keys)?,
750 opt_into_json(sighash_type)?,
751 ];
752 let defaults = [empty_arr(), empty_arr(), null()];
753 self.call("signrawtransaction", handle_defaults(&mut args, &defaults)).await
754 }
755
756 async fn sign_raw_transaction_with_wallet<R: RawTx>(
757 &self,
758 tx: R,
759 utxos: Option<&[json::SignRawTransactionInput]>,
760 sighash_type: Option<json::SigHashType>,
761 ) -> Result<json::SignRawTransactionResult>
762 where R: Sync + Send
763 {
764 let mut args = [tx.raw_hex().into(), opt_into_json(utxos)?, opt_into_json(sighash_type)?];
765 let defaults = [empty_arr(), null()];
766 self.call("signrawtransactionwithwallet", handle_defaults(&mut args, &defaults)).await
767 }
768
769 async fn sign_raw_transaction_with_key<R: RawTx>(
770 &self,
771 tx: R,
772 privkeys: &[PrivateKey],
773 prevtxs: Option<&[json::SignRawTransactionInput]>,
774 sighash_type: Option<json::SigHashType>,
775 ) -> Result<json::SignRawTransactionResult>
776 where R: Sync + Send
777 {
778 let mut args = [
779 tx.raw_hex().into(),
780 into_json(privkeys)?,
781 opt_into_json(prevtxs)?,
782 opt_into_json(sighash_type)?,
783 ];
784 let defaults = [empty_arr(), null()];
785 self.call("signrawtransactionwithkey", handle_defaults(&mut args, &defaults)).await
786 }
787
788 async fn test_mempool_accept<R: RawTx>(
789 &self,
790 rawtxs: &[R],
791 ) -> Result<Vec<json::TestMempoolAcceptResult>>
792 where R: Sync + Send
793 {
794 let hexes: Vec<serde_json::Value> =
795 rawtxs.to_vec().into_iter().map(|r| r.raw_hex().into()).collect();
796 self.call("testmempoolaccept", &[hexes.into()]).await
797 }
798
799 async fn stop(&self) -> Result<String> {
800 self.call("stop", &[]).await
801 }
802
803 async fn verify_message(
804 &self,
805 address: &Address,
806 signature: &Signature,
807 message: &str,
808 ) -> Result<bool> {
809 let args = [address.to_string().into(), signature.to_string().into(), into_json(message)?];
810 self.call("verifymessage", &args).await
811 }
812
813 async fn get_new_address(
815 &self,
816 label: Option<&str>,
817 address_type: Option<json::AddressType>,
818 ) -> Result<Address> {
819 self.call("getnewaddress", &[opt_into_json(label)?, opt_into_json(address_type)?]).await
820 }
821
822 async fn get_address_info(&self, address: &Address) -> Result<json::GetAddressInfoResult> {
823 self.call("getaddressinfo", &[address.to_string().into()]).await
824 }
825
826 async fn generate_to_address(
830 &self,
831 block_num: u64,
832 address: &Address,
833 ) -> Result<Vec<bitcoin::BlockHash>> {
834 self.call("generatetoaddress", &[block_num.into(), address.to_string().into()]).await
835 }
836
837 async fn generate(&self, block_num: u64, maxtries: Option<u64>) -> Result<Vec<bitcoin::BlockHash>> {
840 self.call("generate", &[block_num.into(), opt_into_json(maxtries)?]).await
841 }
842
843 async fn invalidate_block(&self, block_hash: &bitcoin::BlockHash) -> Result<()> {
845 self.call("invalidateblock", &[into_json(block_hash)?]).await
846 }
847
848 async fn reconsider_block(&self, block_hash: &bitcoin::BlockHash) -> Result<()> {
850 self.call("reconsiderblock", &[into_json(block_hash)?]).await
851 }
852
853 async fn get_raw_mempool(&self) -> Result<Vec<bitcoin::Txid>> {
855 self.call("getrawmempool", &[]).await
856 }
857
858 async fn get_mempool_entry(&self, txid: &bitcoin::Txid) -> Result<json::GetMempoolEntryResult> {
860 self.call("getmempoolentry", &[into_json(txid)?]).await
861 }
862
863 async fn send_to_address(
864 &self,
865 address: &Address,
866 amount: Amount,
867 comment: Option<&str>,
868 comment_to: Option<&str>,
869 subtract_fee: Option<bool>,
870 replaceable: Option<bool>,
871 confirmation_target: Option<u32>,
872 estimate_mode: Option<json::EstimateMode>,
873 ) -> Result<bitcoin::Txid> {
874 let mut args = [
875 address.to_string().into(),
876 into_json(amount.as_btc())?,
877 opt_into_json(comment)?,
878 opt_into_json(comment_to)?,
879 opt_into_json(subtract_fee)?,
880 opt_into_json(replaceable)?,
881 opt_into_json(confirmation_target)?,
882 opt_into_json(estimate_mode)?,
883 ];
884 self.call(
885 "sendtoaddress",
886 handle_defaults(
887 &mut args,
888 &["".into(), "".into(), false.into(), false.into(), 6.into(), null()],
889 ),
890 ).await
891 }
892
893 async fn get_peer_info(&self) -> Result<Vec<json::GetPeerInfoResult>> {
898 self.call("getpeerinfo", &[]).await
899 }
900
901 async fn ping(&self) -> Result<()> {
910 self.call("ping", &[]).await
911 }
912
913 async fn send_raw_transaction<R: RawTx>(&self, tx: R) -> Result<bitcoin::Txid>
914 where R: Sync + Send
915 {
916 self.call("sendrawtransaction", &[tx.raw_hex().into()]).await
917 }
918
919 async fn estimate_smart_fee(
920 &self,
921 conf_target: u16,
922 estimate_mode: Option<json::EstimateMode>,
923 ) -> Result<json::EstimateSmartFeeResult> {
924 let mut args = [into_json(conf_target)?, opt_into_json(estimate_mode)?];
925 self.call("estimatesmartfee", handle_defaults(&mut args, &[null()])).await
926 }
927
928 async fn wait_for_new_block(&self, timeout: u64) -> Result<json::BlockRef> {
936 self.call("waitfornewblock", &[into_json(timeout)?]).await
937 }
938
939 async fn wait_for_block(
948 &self,
949 blockhash: &bitcoin::BlockHash,
950 timeout: u64,
951 ) -> Result<json::BlockRef> {
952 let args = [into_json(blockhash)?, into_json(timeout)?];
953 self.call("waitforblock", &args).await
954 }
955
956 async fn wallet_create_funded_psbt(
957 &self,
958 inputs: &[json::CreateRawTransactionInput],
959 outputs: &HashMap<String, Amount>,
960 locktime: Option<i64>,
961 options: Option<json::WalletCreateFundedPsbtOptions>,
962 bip32derivs: Option<bool>,
963 ) -> Result<json::WalletCreateFundedPsbtResult> {
964 let outputs_converted = serde_json::Map::from_iter(
965 outputs.iter().map(|(k, v)| (k.clone(), serde_json::Value::from(v.as_btc()))),
966 );
967 let mut args = [
968 into_json(inputs)?,
969 into_json(outputs_converted)?,
970 opt_into_json(locktime)?,
971 opt_into_json(options)?,
972 opt_into_json(bip32derivs)?,
973 ];
974 self.call(
975 "walletcreatefundedpsbt",
976 handle_defaults(&mut args, &[0.into(), serde_json::Map::new().into(), false.into()]),
977 ).await
978 }
979
980 async fn get_descriptor_info(&self, desc: &str) -> Result<json::GetDescriptorInfoResult> {
981 self.call("getdescriptorinfo", &[desc.to_string().into()]).await
982 }
983
984 async fn combine_psbt(&self, psbts: &[String]) -> Result<String> {
985 self.call("combinepsbt", &[into_json(psbts)?]).await
986 }
987
988 async fn finalize_psbt(&self, psbt: &str, extract: Option<bool>) -> Result<json::FinalizePsbtResult> {
989 let mut args = [into_json(psbt)?, opt_into_json(extract)?];
990 self.call("finalizepsbt", handle_defaults(&mut args, &[true.into()])).await
991 }
992
993 async fn derive_addresses(&self, descriptor: &str, range: Option<[u32; 2]>) -> Result<Vec<Address>> {
994 let mut args = [into_json(descriptor)?, opt_into_json(range)?];
995 self.call("deriveaddresses", handle_defaults(&mut args, &[null()])).await
996 }
997
998 async fn rescan_blockchain(
999 &self,
1000 start_from: Option<usize>,
1001 stop_height: Option<usize>,
1002 ) -> Result<(usize, Option<usize>)> {
1003 let mut args = [opt_into_json(start_from)?, opt_into_json(stop_height)?];
1004
1005 #[derive(Deserialize)]
1006 struct Response {
1007 pub start_height: usize,
1008 pub stop_height: Option<usize>,
1009 }
1010 let res: Response =
1011 self.call("rescanblockchain", handle_defaults(&mut args, &[0.into(), null()])).await?;
1012 Ok((res.start_height, res.stop_height))
1013 }
1014
1015 async fn get_tx_out_set_info(&self) -> Result<json::GetTxOutSetInfoResult> {
1018 self.call("gettxoutsetinfo", &[]).await
1019 }
1020
1021 async fn get_net_totals(&self) -> Result<json::GetNetTotalsResult> {
1024 self.call("getnettotals", &[]).await
1025 }
1026
1027 async fn get_network_hash_ps(&self, nblocks: Option<u64>, height: Option<u64>) -> Result<f64> {
1029 let mut args = [opt_into_json(nblocks)?, opt_into_json(height)?];
1030 self.call("getnetworkhashps", handle_defaults(&mut args, &[null(), null()])).await
1031 }
1032
1033 async fn uptime(&self) -> Result<u64> {
1035 self.call("uptime", &[]).await
1036 }
1037
1038 async fn scan_tx_out_set_blocking(
1039 &self,
1040 descriptors: &[json::ScanTxOutRequest],
1041 ) -> Result<json::ScanTxOutResult> {
1042 self.call("scantxoutset", &["start".into(), into_json(descriptors)?]).await
1043 }
1044}
1045
1046pub struct Client {
1048 client: jsonrpc::client::Client,
1049}
1050
1051impl fmt::Debug for Client {
1052 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1053 write!(
1054 f,
1055 "bitcoincore_rpc::Client(jsonrpc::client::Client(last_nonce=?))",
1056 )
1057 }
1058}
1059
1060impl Client {
1061 pub async fn new(url: String, auth: Auth) -> Result<Self> {
1065 let mut client = jsonrpc::simple_http::SimpleHttpTransport::builder().url(&url).await.map_err(|e|Error::JsonRpc(e.into()))?;
1066 if let Some((user, pass)) = auth.get_user_pass()? {
1067 client = client.auth(user, Some(pass));
1068 }
1069
1070 Ok(Client {
1071 client: jsonrpc::client::Client::with_transport(client.build())
1072 })
1073 }
1074
1075 pub fn from_jsonrpc(client: jsonrpc::client::Client) -> Client {
1077 Client {
1078 client: client,
1079 }
1080 }
1081
1082 pub fn get_jsonrpc_client(&self) -> &jsonrpc::client::Client {
1084 &self.client
1085 }
1086}
1087
1088#[async_trait]
1089impl RpcApi for Client {
1090 async fn call<T: for<'a> serde::de::Deserialize<'a>>(
1092 &self,
1093 cmd: &str,
1094 args: &[serde_json::Value],
1095 ) -> Result<T> {
1096 let v_args : Vec<_> = args.iter().map(serde_json::value::to_raw_value).collect::<std::result::Result<_,serde_json::Error>>()?;
1097 let req = self.client.build_request(cmd, &v_args[..]);
1098 if log_enabled!(Debug) {
1099 debug!(target: "bitcoincore_rpc", "JSON-RPC request: {} {}", cmd, serde_json::Value::from(args));
1100 }
1101
1102 let resp = self.client.send_request(req).await.map_err(Error::from);
1103 log_response(cmd, &resp);
1104 Ok(resp?.result()?)
1105
1106 }
1107}
1108
1109fn log_response(cmd: &str, resp: &Result<jsonrpc::Response>) {
1110 if log_enabled!(Warn) || log_enabled!(Debug) || log_enabled!(Trace) {
1111 match resp {
1112 Err(ref e) => {
1113 if log_enabled!(Debug) {
1114 debug!(target: "bitcoincore_rpc", "JSON-RPC failed parsing reply of {}: {:?}", cmd, e);
1115 }
1116 }
1117 Ok(ref resp) => {
1118 if let Some(ref e) = resp.error {
1119 if log_enabled!(Debug) {
1120 debug!(target: "bitcoincore_rpc", "JSON-RPC error for {}: {:?}", cmd, e);
1121 }
1122 } else if log_enabled!(Trace) {
1123 let rawnull = serde_json::value::to_raw_value(&serde_json::Value::Null).unwrap();
1124 let result = resp.result.as_ref().unwrap_or(&rawnull);
1125 trace!(target: "bitcoincore_rpc", "JSON-RPC response for {}: {}", cmd, result);
1126 }
1127 }
1128 }
1129 }
1130}
1131
1132#[cfg(test)]
1133mod tests {
1134 use super::*;
1135 use bitcoin;
1136 use serde_json;
1137 use tokio;
1138
1139 #[tokio::test]
1140 async fn test_raw_tx() {
1141 use bitcoin::consensus::encode;
1142 let client = Client::new("http://localhost/".into(), Auth::None).await.unwrap();
1143 let tx: bitcoin::Transaction = encode::deserialize(&Vec::<u8>::from_hex("0200000001586bd02815cf5faabfec986a4e50d25dbee089bd2758621e61c5fab06c334af0000000006b483045022100e85425f6d7c589972ee061413bcf08dc8c8e589ce37b217535a42af924f0e4d602205c9ba9cb14ef15513c9d946fa1c4b797883e748e8c32171bdf6166583946e35c012103dae30a4d7870cd87b45dd53e6012f71318fdd059c1c2623b8cc73f8af287bb2dfeffffff021dc4260c010000001976a914f602e88b2b5901d8aab15ebe4a97cf92ec6e03b388ac00e1f505000000001976a914687ffeffe8cf4e4c038da46a9b1d37db385a472d88acfd211500").unwrap()).unwrap();
1144
1145 assert!(client.send_raw_transaction(&tx).await.is_err());
1146 assert!(client.send_raw_transaction(&encode::serialize(&tx)).await.is_err());
1147 assert!(client.send_raw_transaction("deadbeef").await.is_err());
1148 assert!(client.send_raw_transaction("deadbeef".to_owned()).await.is_err());
1149 }
1150
1151 fn test_handle_defaults_inner() -> Result<()> {
1152 {
1153 let mut args = [into_json(0)?, null(), null()];
1154 let defaults = [into_json(1)?, into_json(2)?];
1155 let res = [into_json(0)?];
1156 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1157 }
1158 {
1159 let mut args = [into_json(0)?, into_json(1)?, null()];
1160 let defaults = [into_json(2)?];
1161 let res = [into_json(0)?, into_json(1)?];
1162 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1163 }
1164 {
1165 let mut args = [into_json(0)?, null(), into_json(5)?];
1166 let defaults = [into_json(2)?, into_json(3)?];
1167 let res = [into_json(0)?, into_json(2)?, into_json(5)?];
1168 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1169 }
1170 {
1171 let mut args = [into_json(0)?, null(), into_json(5)?, null()];
1172 let defaults = [into_json(2)?, into_json(3)?, into_json(4)?];
1173 let res = [into_json(0)?, into_json(2)?, into_json(5)?];
1174 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1175 }
1176 {
1177 let mut args = [null(), null()];
1178 let defaults = [into_json(2)?, into_json(3)?];
1179 let res: [serde_json::Value; 0] = [];
1180 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1181 }
1182 {
1183 let mut args = [null(), into_json(1)?];
1184 let defaults = [];
1185 let res = [null(), into_json(1)?];
1186 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1187 }
1188 {
1189 let mut args = [];
1190 let defaults = [];
1191 let res: [serde_json::Value; 0] = [];
1192 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1193 }
1194 {
1195 let mut args = [into_json(0)?];
1196 let defaults = [into_json(2)?];
1197 let res = [into_json(0)?];
1198 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1199 }
1200 Ok(())
1201 }
1202
1203 #[test]
1204 fn test_handle_defaults() {
1205 test_handle_defaults_inner().unwrap();
1206 }
1207}