1use serde_json::value::RawValue;
12use std::collections::HashMap;
13use std::fs::File;
14use std::iter::FromIterator;
15use std::path::PathBuf;
16use std::{fmt, result};
17
18use super::bitcoin;
19use bitcoincore_rpc_json as json;
20use jsonrpc_async as jsonrpc;
21use serde::*;
22use serde_json;
23
24use async_trait::async_trait;
25use bitcoin::hashes::hex::{FromHex, ToHex};
26use bitcoin::secp256k1::Signature;
27use bitcoin::{
28 Address, Amount, Block, BlockHeader, OutPoint, PrivateKey, PublicKey, Script, Transaction,
29};
30use log::Level::{Debug, Trace, Warn};
31use log::{debug, log_enabled, trace};
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
235 T: Sync + Send,
236 <T as queryable::Queryable<Self>>::Id: Sync + Send,
237 {
238 T::query(&self, &id).await
239 }
240
241 async fn get_network_info(&self) -> Result<json::GetNetworkInfoResult> {
242 self.call("getnetworkinfo", &[]).await
243 }
244
245 async fn version(&self) -> Result<usize> {
246 #[derive(Deserialize)]
247 struct Response {
248 pub version: usize,
249 }
250 let res: Response = self.call("getnetworkinfo", &[]).await?;
251 Ok(res.version)
252 }
253
254 async fn add_multisig_address(
255 &self,
256 nrequired: usize,
257 keys: &[json::PubKeyOrAddress<'_>],
258 label: Option<&str>,
259 address_type: Option<json::AddressType>,
260 ) -> Result<json::AddMultiSigAddressResult> {
261 let mut args = [
262 into_json(nrequired)?,
263 into_json(keys)?,
264 opt_into_json(label)?,
265 opt_into_json(address_type)?,
266 ];
267 self.call("addmultisigaddress", handle_defaults(&mut args, &[into_json("")?, null()])).await
268 }
269
270 async fn load_wallet(&self, wallet: &str) -> Result<json::LoadWalletResult> {
271 self.call("loadwallet", &[wallet.into()]).await
272 }
273
274 async fn unload_wallet(&self, wallet: Option<&str>) -> Result<()> {
275 let mut args = [opt_into_json(wallet)?];
276 self.call("unloadwallet", handle_defaults(&mut args, &[null()])).await
277 }
278
279 async fn create_wallet(
280 &self,
281 wallet: &str,
282 disable_private_keys: Option<bool>,
283 blank: Option<bool>,
284 passphrase: Option<&str>,
285 avoid_reuse: Option<bool>,
286 ) -> Result<json::LoadWalletResult> {
287 let mut args = [
288 wallet.into(),
289 opt_into_json(disable_private_keys)?,
290 opt_into_json(blank)?,
291 opt_into_json(passphrase)?,
292 opt_into_json(avoid_reuse)?,
293 ];
294 self.call(
295 "createwallet",
296 handle_defaults(&mut args, &[false.into(), false.into(), into_json("")?, false.into()]),
297 )
298 .await
299 }
300
301 async fn list_wallets(&self) -> Result<Vec<String>> {
302 self.call("listwallets", &[]).await
303 }
304
305 async fn get_wallet_info(&self) -> Result<json::GetWalletInfoResult> {
306 self.call("getwalletinfo", &[]).await
307 }
308
309 async fn backup_wallet(&self, destination: Option<&str>) -> Result<()> {
310 let mut args = [opt_into_json(destination)?];
311 self.call("backupwallet", handle_defaults(&mut args, &[null()])).await
312 }
313
314 async fn dump_private_key(&self, address: &Address) -> Result<PrivateKey> {
315 self.call("dumpprivkey", &[address.to_string().into()]).await
316 }
317
318 async fn encrypt_wallet(&self, passphrase: &str) -> Result<()> {
319 self.call("encryptwallet", &[into_json(passphrase)?]).await
320 }
321
322 async fn get_difficulty(&self) -> Result<f64> {
323 self.call("getdifficulty", &[]).await
324 }
325
326 async fn get_connection_count(&self) -> Result<usize> {
327 self.call("getconnectioncount", &[]).await
328 }
329
330 async fn get_block(&self, hash: &bitcoin::BlockHash) -> Result<Block> {
331 let hex: String = self.call("getblock", &[into_json(hash)?, 0.into()]).await?;
332 let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
333 Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
334 }
335
336 async fn get_block_hex(&self, hash: &bitcoin::BlockHash) -> Result<String> {
337 self.call("getblock", &[into_json(hash)?, 0.into()]).await
338 }
339
340 async fn get_block_info(&self, hash: &bitcoin::BlockHash) -> Result<json::GetBlockResult> {
341 self.call("getblock", &[into_json(hash)?, 1.into()]).await
342 }
343 async fn get_block_header(&self, hash: &bitcoin::BlockHash) -> Result<BlockHeader> {
346 let hex: String = self.call("getblockheader", &[into_json(hash)?, false.into()]).await?;
347 let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
348 Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
349 }
350
351 async fn get_block_header_info(
352 &self,
353 hash: &bitcoin::BlockHash,
354 ) -> Result<json::GetBlockHeaderResult> {
355 self.call("getblockheader", &[into_json(hash)?, true.into()]).await
356 }
357
358 async fn get_mining_info(&self) -> Result<json::GetMiningInfoResult> {
359 self.call("getmininginfo", &[]).await
360 }
361
362 async fn get_blockchain_info(&self) -> Result<json::GetBlockchainInfoResult> {
365 let mut raw: serde_json::Value = self.call("getblockchaininfo", &[]).await?;
366 Ok(if self.version().await? < 190000 {
370 use Error::UnexpectedStructure as err;
371
372 let (bip9_softforks, old_softforks) = {
375 let map = raw.as_object_mut().ok_or(err)?;
376 let bip9_softforks = map.remove("bip9_softforks").ok_or(err)?;
377 let old_softforks = map.remove("softforks").ok_or(err)?;
378 map.insert("softforks".into(), serde_json::Map::new().into());
380 (bip9_softforks, old_softforks)
381 };
382 let mut ret: json::GetBlockchainInfoResult = serde_json::from_value(raw)?;
383
384 for sf in old_softforks.as_array().ok_or(err)?.iter() {
386 let json = sf.as_object().ok_or(err)?;
387 let id = json.get("id").ok_or(err)?.as_str().ok_or(err)?;
388 let reject = json.get("reject").ok_or(err)?.as_object().ok_or(err)?;
389 let active = reject.get("status").ok_or(err)?.as_bool().ok_or(err)?;
390 ret.softforks.insert(
391 id.into(),
392 json::Softfork {
393 type_: json::SoftforkType::Buried,
394 bip9: None,
395 height: None,
396 active: active,
397 },
398 );
399 }
400 for (id, sf) in bip9_softforks.as_object().ok_or(err)?.iter() {
401 #[derive(Deserialize)]
402 struct OldBip9SoftFork {
403 pub status: json::Bip9SoftforkStatus,
404 pub bit: Option<u8>,
405 #[serde(rename = "startTime")]
406 pub start_time: i64,
407 pub timeout: u64,
408 pub since: u32,
409 pub statistics: Option<json::Bip9SoftforkStatistics>,
410 }
411 let sf: OldBip9SoftFork = serde_json::from_value(sf.clone())?;
412 ret.softforks.insert(
413 id.clone(),
414 json::Softfork {
415 type_: json::SoftforkType::Bip9,
416 bip9: Some(json::Bip9SoftforkInfo {
417 status: sf.status,
418 bit: sf.bit,
419 start_time: sf.start_time,
420 timeout: sf.timeout,
421 since: sf.since,
422 statistics: sf.statistics,
423 }),
424 height: None,
425 active: sf.status == json::Bip9SoftforkStatus::Active,
426 },
427 );
428 }
429 ret
430 } else {
431 serde_json::from_value(raw)?
432 })
433 }
434
435 async fn get_block_count(&self) -> Result<u64> {
437 self.call("getblockcount", &[]).await
438 }
439
440 async fn get_best_block_hash(&self) -> Result<bitcoin::BlockHash> {
442 self.call("getbestblockhash", &[]).await
443 }
444
445 async fn get_block_hash(&self, height: u64) -> Result<bitcoin::BlockHash> {
447 self.call("getblockhash", &[height.into()]).await
448 }
449
450 async fn get_raw_transaction(
451 &self,
452 txid: &bitcoin::Txid,
453 block_hash: Option<&bitcoin::BlockHash>,
454 ) -> Result<Transaction> {
455 let mut args = [into_json(txid)?, into_json(false)?, opt_into_json(block_hash)?];
456 let hex: String =
457 self.call("getrawtransaction", handle_defaults(&mut args, &[null()])).await?;
458 let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
459 Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
460 }
461
462 async fn get_raw_transaction_hex(
463 &self,
464 txid: &bitcoin::Txid,
465 block_hash: Option<&bitcoin::BlockHash>,
466 ) -> Result<String> {
467 let mut args = [into_json(txid)?, into_json(false)?, opt_into_json(block_hash)?];
468 self.call("getrawtransaction", handle_defaults(&mut args, &[null()])).await
469 }
470
471 async fn get_raw_transaction_info(
472 &self,
473 txid: &bitcoin::Txid,
474 block_hash: Option<&bitcoin::BlockHash>,
475 ) -> Result<json::GetRawTransactionResult> {
476 let mut args = [into_json(txid)?, into_json(true)?, opt_into_json(block_hash)?];
477 self.call("getrawtransaction", handle_defaults(&mut args, &[null()])).await
478 }
479
480 async fn get_block_filter(
481 &self,
482 block_hash: &bitcoin::BlockHash,
483 ) -> Result<json::GetBlockFilterResult> {
484 self.call("getblockfilter", &[into_json(block_hash)?]).await
485 }
486
487 async fn get_balance(
488 &self,
489 minconf: Option<usize>,
490 include_watchonly: Option<bool>,
491 ) -> Result<Amount> {
492 let mut args = ["*".into(), opt_into_json(minconf)?, opt_into_json(include_watchonly)?];
493 Ok(Amount::from_btc(
494 self.call("getbalance", handle_defaults(&mut args, &[0.into(), null()])).await?,
495 )?)
496 }
497
498 async fn get_balances(&self) -> Result<json::GetBalancesResult> {
499 Ok(self.call("getbalances", &[]).await?)
500 }
501
502 async fn get_received_by_address(
503 &self,
504 address: &Address,
505 minconf: Option<u32>,
506 ) -> Result<Amount> {
507 let mut args = [address.to_string().into(), opt_into_json(minconf)?];
508 Ok(Amount::from_btc(
509 self.call("getreceivedbyaddress", handle_defaults(&mut args, &[null()])).await?,
510 )?)
511 }
512
513 async fn get_transaction(
514 &self,
515 txid: &bitcoin::Txid,
516 include_watchonly: Option<bool>,
517 ) -> Result<json::GetTransactionResult> {
518 let mut args = [into_json(txid)?, opt_into_json(include_watchonly)?];
519 self.call("gettransaction", handle_defaults(&mut args, &[null()])).await
520 }
521
522 async fn list_transactions(
523 &self,
524 label: Option<&str>,
525 count: Option<usize>,
526 skip: Option<usize>,
527 include_watchonly: Option<bool>,
528 ) -> Result<Vec<json::ListTransactionResult>> {
529 let mut args = [
530 label.unwrap_or("*").into(),
531 opt_into_json(count)?,
532 opt_into_json(skip)?,
533 opt_into_json(include_watchonly)?,
534 ];
535 self.call("listtransactions", handle_defaults(&mut args, &[10.into(), 0.into(), null()]))
536 .await
537 }
538
539 async fn list_since_block(
540 &self,
541 blockhash: Option<&bitcoin::BlockHash>,
542 target_confirmations: Option<usize>,
543 include_watchonly: Option<bool>,
544 include_removed: Option<bool>,
545 ) -> Result<json::ListSinceBlockResult> {
546 let mut args = [
547 opt_into_json(blockhash)?,
548 opt_into_json(target_confirmations)?,
549 opt_into_json(include_watchonly)?,
550 opt_into_json(include_removed)?,
551 ];
552 self.call("listsinceblock", handle_defaults(&mut args, &[null()])).await
553 }
554
555 async fn get_tx_out(
556 &self,
557 txid: &bitcoin::Txid,
558 vout: u32,
559 include_mempool: Option<bool>,
560 ) -> Result<Option<json::GetTxOutResult>> {
561 let mut args = [into_json(txid)?, into_json(vout)?, opt_into_json(include_mempool)?];
562 opt_result(self.call("gettxout", handle_defaults(&mut args, &[null()])).await?)
563 }
564
565 async fn get_tx_out_proof(
566 &self,
567 txids: &[bitcoin::Txid],
568 block_hash: Option<&bitcoin::BlockHash>,
569 ) -> Result<Vec<u8>> {
570 let mut args = [into_json(txids)?, opt_into_json(block_hash)?];
571 let hex: String = self.call("gettxoutproof", handle_defaults(&mut args, &[null()])).await?;
572 Ok(FromHex::from_hex(&hex)?)
573 }
574
575 async fn import_public_key(
576 &self,
577 pubkey: &PublicKey,
578 label: Option<&str>,
579 rescan: Option<bool>,
580 ) -> Result<()> {
581 let mut args = [pubkey.to_string().into(), opt_into_json(label)?, opt_into_json(rescan)?];
582 self.call("importpubkey", handle_defaults(&mut args, &[into_json("")?, null()])).await
583 }
584
585 async fn import_private_key(
586 &self,
587 privkey: &PrivateKey,
588 label: Option<&str>,
589 rescan: Option<bool>,
590 ) -> Result<()> {
591 let mut args = [privkey.to_string().into(), opt_into_json(label)?, opt_into_json(rescan)?];
592 self.call("importprivkey", handle_defaults(&mut args, &[into_json("")?, null()])).await
593 }
594
595 async fn import_address(
596 &self,
597 address: &Address,
598 label: Option<&str>,
599 rescan: Option<bool>,
600 ) -> Result<()> {
601 let mut args = [address.to_string().into(), opt_into_json(label)?, opt_into_json(rescan)?];
602 self.call("importaddress", handle_defaults(&mut args, &[into_json("")?, null()])).await
603 }
604
605 async fn import_address_script(
606 &self,
607 script: &Script,
608 label: Option<&str>,
609 rescan: Option<bool>,
610 p2sh: Option<bool>,
611 ) -> Result<()> {
612 let mut args = [
613 script.to_hex().into(),
614 opt_into_json(label)?,
615 opt_into_json(rescan)?,
616 opt_into_json(p2sh)?,
617 ];
618 self.call(
619 "importaddress",
620 handle_defaults(&mut args, &[into_json("")?, true.into(), null()]),
621 )
622 .await
623 }
624
625 async fn import_multi(
626 &self,
627 requests: &[json::ImportMultiRequest<'_>],
628 options: Option<&json::ImportMultiOptions>,
629 ) -> Result<Vec<json::ImportMultiResult>> {
630 let mut json_requests = Vec::with_capacity(requests.len());
631 for req in requests {
632 json_requests.push(serde_json::to_value(req)?);
633 }
634 let mut args = [json_requests.into(), opt_into_json(options)?];
635 self.call("importmulti", handle_defaults(&mut args, &[null()])).await
636 }
637
638 async fn set_label(&self, address: &Address, label: &str) -> Result<()> {
639 self.call("setlabel", &[address.to_string().into(), label.into()]).await
640 }
641
642 async fn key_pool_refill(&self, new_size: Option<usize>) -> Result<()> {
643 let mut args = [opt_into_json(new_size)?];
644 self.call("keypoolrefill", handle_defaults(&mut args, &[null()])).await
645 }
646
647 async fn list_unspent(
648 &self,
649 minconf: Option<usize>,
650 maxconf: Option<usize>,
651 addresses: Option<&[&Address]>,
652 include_unsafe: Option<bool>,
653 query_options: Option<json::ListUnspentQueryOptions>,
654 ) -> Result<Vec<json::ListUnspentResultEntry>> {
655 let mut args = [
656 opt_into_json(minconf)?,
657 opt_into_json(maxconf)?,
658 opt_into_json(addresses)?,
659 opt_into_json(include_unsafe)?,
660 opt_into_json(query_options)?,
661 ];
662 let defaults = [into_json(0)?, into_json(9999999)?, empty_arr(), into_json(true)?, null()];
663 self.call("listunspent", handle_defaults(&mut args, &defaults)).await
664 }
665
666 async fn lock_unspent(&self, outputs: &[OutPoint]) -> Result<bool> {
668 let outputs: Vec<_> = outputs
669 .into_iter()
670 .map(|o| serde_json::to_value(JsonOutPoint::from(*o)).unwrap())
671 .collect();
672 self.call("lockunspent", &[false.into(), outputs.into()]).await
673 }
674
675 async fn unlock_unspent(&self, outputs: &[OutPoint]) -> Result<bool> {
676 let outputs: Vec<_> = outputs
677 .into_iter()
678 .map(|o| serde_json::to_value(JsonOutPoint::from(*o)).unwrap())
679 .collect();
680 self.call("lockunspent", &[true.into(), outputs.into()]).await
681 }
682
683 async fn list_received_by_address(
684 &self,
685 address_filter: Option<&Address>,
686 minconf: Option<u32>,
687 include_empty: Option<bool>,
688 include_watchonly: Option<bool>,
689 ) -> Result<Vec<json::ListReceivedByAddressResult>> {
690 let mut args = [
691 opt_into_json(minconf)?,
692 opt_into_json(include_empty)?,
693 opt_into_json(include_watchonly)?,
694 opt_into_json(address_filter)?,
695 ];
696 let defaults = [1.into(), false.into(), false.into(), null()];
697 self.call("listreceivedbyaddress", handle_defaults(&mut args, &defaults)).await
698 }
699
700 async fn create_raw_transaction_hex(
701 &self,
702 utxos: &[json::CreateRawTransactionInput],
703 outs: &HashMap<String, Amount>,
704 locktime: Option<i64>,
705 replaceable: Option<bool>,
706 ) -> Result<String> {
707 let outs_converted = serde_json::Map::from_iter(
708 outs.iter().map(|(k, v)| (k.clone(), serde_json::Value::from(v.as_btc()))),
709 );
710 let mut args = [
711 into_json(utxos)?,
712 into_json(outs_converted)?,
713 opt_into_json(locktime)?,
714 opt_into_json(replaceable)?,
715 ];
716 let defaults = [into_json(0i64)?, null()];
717 self.call("createrawtransaction", handle_defaults(&mut args, &defaults)).await
718 }
719
720 async fn create_raw_transaction(
721 &self,
722 utxos: &[json::CreateRawTransactionInput],
723 outs: &HashMap<String, Amount>,
724 locktime: Option<i64>,
725 replaceable: Option<bool>,
726 ) -> Result<Transaction> {
727 let hex: String =
728 self.create_raw_transaction_hex(utxos, outs, locktime, replaceable).await?;
729 let bytes: Vec<u8> = FromHex::from_hex(&hex)?;
730 Ok(bitcoin::consensus::encode::deserialize(&bytes)?)
731 }
732
733 async fn fund_raw_transaction<R: RawTx>(
734 &self,
735 tx: R,
736 options: Option<&json::FundRawTransactionOptions>,
737 is_witness: Option<bool>,
738 ) -> Result<json::FundRawTransactionResult>
739 where
740 R: Sync + Send,
741 {
742 let mut args = [tx.raw_hex().into(), opt_into_json(options)?, opt_into_json(is_witness)?];
743 let defaults = [empty_obj(), null()];
744 self.call("fundrawtransaction", handle_defaults(&mut args, &defaults)).await
745 }
746
747 #[deprecated]
748 async fn sign_raw_transaction<R: RawTx>(
749 &self,
750 tx: R,
751 utxos: Option<&[json::SignRawTransactionInput]>,
752 private_keys: Option<&[PrivateKey]>,
753 sighash_type: Option<json::SigHashType>,
754 ) -> Result<json::SignRawTransactionResult>
755 where
756 R: Sync + Send,
757 {
758 let mut args = [
759 tx.raw_hex().into(),
760 opt_into_json(utxos)?,
761 opt_into_json(private_keys)?,
762 opt_into_json(sighash_type)?,
763 ];
764 let defaults = [empty_arr(), empty_arr(), null()];
765 self.call("signrawtransaction", handle_defaults(&mut args, &defaults)).await
766 }
767
768 async fn sign_raw_transaction_with_wallet<R: RawTx>(
769 &self,
770 tx: R,
771 utxos: Option<&[json::SignRawTransactionInput]>,
772 sighash_type: Option<json::SigHashType>,
773 ) -> Result<json::SignRawTransactionResult>
774 where
775 R: Sync + Send,
776 {
777 let mut args = [tx.raw_hex().into(), opt_into_json(utxos)?, opt_into_json(sighash_type)?];
778 let defaults = [empty_arr(), null()];
779 self.call("signrawtransactionwithwallet", handle_defaults(&mut args, &defaults)).await
780 }
781
782 async fn sign_raw_transaction_with_key<R: RawTx>(
783 &self,
784 tx: R,
785 privkeys: &[PrivateKey],
786 prevtxs: Option<&[json::SignRawTransactionInput]>,
787 sighash_type: Option<json::SigHashType>,
788 ) -> Result<json::SignRawTransactionResult>
789 where
790 R: Sync + Send,
791 {
792 let mut args = [
793 tx.raw_hex().into(),
794 into_json(privkeys)?,
795 opt_into_json(prevtxs)?,
796 opt_into_json(sighash_type)?,
797 ];
798 let defaults = [empty_arr(), null()];
799 self.call("signrawtransactionwithkey", handle_defaults(&mut args, &defaults)).await
800 }
801
802 async fn test_mempool_accept<R: RawTx>(
803 &self,
804 rawtxs: &[R],
805 ) -> Result<Vec<json::TestMempoolAcceptResult>>
806 where
807 R: Sync + Send,
808 {
809 let hexes: Vec<serde_json::Value> =
810 rawtxs.to_vec().into_iter().map(|r| r.raw_hex().into()).collect();
811 self.call("testmempoolaccept", &[hexes.into()]).await
812 }
813
814 async fn stop(&self) -> Result<String> {
815 self.call("stop", &[]).await
816 }
817
818 async fn verify_message(
819 &self,
820 address: &Address,
821 signature: &Signature,
822 message: &str,
823 ) -> Result<bool> {
824 let args = [address.to_string().into(), signature.to_string().into(), into_json(message)?];
825 self.call("verifymessage", &args).await
826 }
827
828 async fn get_new_address(
830 &self,
831 label: Option<&str>,
832 address_type: Option<json::AddressType>,
833 ) -> Result<Address> {
834 self.call("getnewaddress", &[opt_into_json(label)?, opt_into_json(address_type)?]).await
835 }
836
837 async fn get_address_info(&self, address: &Address) -> Result<json::GetAddressInfoResult> {
838 self.call("getaddressinfo", &[address.to_string().into()]).await
839 }
840
841 async fn generate_to_address(
845 &self,
846 block_num: u64,
847 address: &Address,
848 ) -> Result<Vec<bitcoin::BlockHash>> {
849 self.call("generatetoaddress", &[block_num.into(), address.to_string().into()]).await
850 }
851
852 async fn generate(
855 &self,
856 block_num: u64,
857 maxtries: Option<u64>,
858 ) -> Result<Vec<bitcoin::BlockHash>> {
859 self.call("generate", &[block_num.into(), opt_into_json(maxtries)?]).await
860 }
861
862 async fn invalidate_block(&self, block_hash: &bitcoin::BlockHash) -> Result<()> {
864 self.call("invalidateblock", &[into_json(block_hash)?]).await
865 }
866
867 async fn reconsider_block(&self, block_hash: &bitcoin::BlockHash) -> Result<()> {
869 self.call("reconsiderblock", &[into_json(block_hash)?]).await
870 }
871
872 async fn get_raw_mempool(&self) -> Result<Vec<bitcoin::Txid>> {
874 self.call("getrawmempool", &[]).await
875 }
876
877 async fn get_mempool_entry(&self, txid: &bitcoin::Txid) -> Result<json::GetMempoolEntryResult> {
879 self.call("getmempoolentry", &[into_json(txid)?]).await
880 }
881
882 async fn send_to_address(
883 &self,
884 address: &Address,
885 amount: Amount,
886 comment: Option<&str>,
887 comment_to: Option<&str>,
888 subtract_fee: Option<bool>,
889 replaceable: Option<bool>,
890 confirmation_target: Option<u32>,
891 estimate_mode: Option<json::EstimateMode>,
892 ) -> Result<bitcoin::Txid> {
893 let mut args = [
894 address.to_string().into(),
895 into_json(amount.as_btc())?,
896 opt_into_json(comment)?,
897 opt_into_json(comment_to)?,
898 opt_into_json(subtract_fee)?,
899 opt_into_json(replaceable)?,
900 opt_into_json(confirmation_target)?,
901 opt_into_json(estimate_mode)?,
902 ];
903 self.call(
904 "sendtoaddress",
905 handle_defaults(
906 &mut args,
907 &["".into(), "".into(), false.into(), false.into(), 6.into(), null()],
908 ),
909 )
910 .await
911 }
912
913 async fn get_peer_info(&self) -> Result<Vec<json::GetPeerInfoResult>> {
918 self.call("getpeerinfo", &[]).await
919 }
920
921 async fn ping(&self) -> Result<()> {
930 self.call("ping", &[]).await
931 }
932
933 async fn send_raw_transaction<R: RawTx>(&self, tx: R) -> Result<bitcoin::Txid>
934 where
935 R: Sync + Send,
936 {
937 self.call("sendrawtransaction", &[tx.raw_hex().into()]).await
938 }
939
940 async fn estimate_smart_fee(
941 &self,
942 conf_target: u16,
943 estimate_mode: Option<json::EstimateMode>,
944 ) -> Result<json::EstimateSmartFeeResult> {
945 let mut args = [into_json(conf_target)?, opt_into_json(estimate_mode)?];
946 self.call("estimatesmartfee", handle_defaults(&mut args, &[null()])).await
947 }
948
949 async fn wait_for_new_block(&self, timeout: u64) -> Result<json::BlockRef> {
957 self.call("waitfornewblock", &[into_json(timeout)?]).await
958 }
959
960 async fn wait_for_block(
969 &self,
970 blockhash: &bitcoin::BlockHash,
971 timeout: u64,
972 ) -> Result<json::BlockRef> {
973 let args = [into_json(blockhash)?, into_json(timeout)?];
974 self.call("waitforblock", &args).await
975 }
976
977 async fn wallet_create_funded_psbt(
978 &self,
979 inputs: &[json::CreateRawTransactionInput],
980 outputs: &HashMap<String, Amount>,
981 locktime: Option<i64>,
982 options: Option<json::WalletCreateFundedPsbtOptions>,
983 bip32derivs: Option<bool>,
984 ) -> Result<json::WalletCreateFundedPsbtResult> {
985 let outputs_converted = serde_json::Map::from_iter(
986 outputs.iter().map(|(k, v)| (k.clone(), serde_json::Value::from(v.as_btc()))),
987 );
988 let mut args = [
989 into_json(inputs)?,
990 into_json(outputs_converted)?,
991 opt_into_json(locktime)?,
992 opt_into_json(options)?,
993 opt_into_json(bip32derivs)?,
994 ];
995 self.call(
996 "walletcreatefundedpsbt",
997 handle_defaults(&mut args, &[0.into(), serde_json::Map::new().into(), false.into()]),
998 )
999 .await
1000 }
1001
1002 async fn get_descriptor_info(&self, desc: &str) -> Result<json::GetDescriptorInfoResult> {
1003 self.call("getdescriptorinfo", &[desc.to_string().into()]).await
1004 }
1005
1006 async fn combine_psbt(&self, psbts: &[String]) -> Result<String> {
1007 self.call("combinepsbt", &[into_json(psbts)?]).await
1008 }
1009
1010 async fn finalize_psbt(
1011 &self,
1012 psbt: &str,
1013 extract: Option<bool>,
1014 ) -> Result<json::FinalizePsbtResult> {
1015 let mut args = [into_json(psbt)?, opt_into_json(extract)?];
1016 self.call("finalizepsbt", handle_defaults(&mut args, &[true.into()])).await
1017 }
1018
1019 async fn derive_addresses(
1020 &self,
1021 descriptor: &str,
1022 range: Option<[u32; 2]>,
1023 ) -> Result<Vec<Address>> {
1024 let mut args = [into_json(descriptor)?, opt_into_json(range)?];
1025 self.call("deriveaddresses", handle_defaults(&mut args, &[null()])).await
1026 }
1027
1028 async fn rescan_blockchain(
1029 &self,
1030 start_from: Option<usize>,
1031 stop_height: Option<usize>,
1032 ) -> Result<(usize, Option<usize>)> {
1033 let mut args = [opt_into_json(start_from)?, opt_into_json(stop_height)?];
1034
1035 #[derive(Deserialize)]
1036 struct Response {
1037 pub start_height: usize,
1038 pub stop_height: Option<usize>,
1039 }
1040 let res: Response =
1041 self.call("rescanblockchain", handle_defaults(&mut args, &[0.into(), null()])).await?;
1042 Ok((res.start_height, res.stop_height))
1043 }
1044
1045 async fn get_tx_out_set_info(&self) -> Result<json::GetTxOutSetInfoResult> {
1048 self.call("gettxoutsetinfo", &[]).await
1049 }
1050
1051 async fn get_net_totals(&self) -> Result<json::GetNetTotalsResult> {
1054 self.call("getnettotals", &[]).await
1055 }
1056
1057 async fn get_network_hash_ps(&self, nblocks: Option<u64>, height: Option<u64>) -> Result<f64> {
1059 let mut args = [opt_into_json(nblocks)?, opt_into_json(height)?];
1060 self.call("getnetworkhashps", handle_defaults(&mut args, &[null(), null()])).await
1061 }
1062
1063 async fn uptime(&self) -> Result<u64> {
1065 self.call("uptime", &[]).await
1066 }
1067
1068 async fn scan_tx_out_set_blocking(
1069 &self,
1070 descriptors: &[json::ScanTxOutRequest],
1071 ) -> Result<json::ScanTxOutResult> {
1072 self.call("scantxoutset", &["start".into(), into_json(descriptors)?]).await
1073 }
1074}
1075
1076pub struct Client {
1078 client: jsonrpc::client::Client,
1079}
1080
1081impl fmt::Debug for Client {
1082 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1083 write!(f, "bitcoincore_rpc::Client(jsonrpc::client::Client(last_nonce=?))",)
1084 }
1085}
1086
1087impl Client {
1088 pub async fn new(url: String, auth: Auth) -> Result<Self> {
1092 let mut client = jsonrpc::simple_http::SimpleHttpTransport::builder()
1093 .url(&url)
1094 .await
1095 .map_err(|e| Error::JsonRpc(e.into()))?;
1096 if let Some((user, pass)) = auth.get_user_pass()? {
1097 client = client.auth(user, Some(pass));
1098 }
1099
1100 Ok(Client {
1101 client: jsonrpc::client::Client::with_transport(client.build()),
1102 })
1103 }
1104
1105 pub fn from_jsonrpc(client: jsonrpc::client::Client) -> Client {
1107 Client {
1108 client: client,
1109 }
1110 }
1111
1112 pub fn get_jsonrpc_client(&self) -> &jsonrpc::client::Client {
1114 &self.client
1115 }
1116}
1117
1118#[async_trait]
1119impl RpcApi for Client {
1120 async fn call<T: for<'a> serde::de::Deserialize<'a>>(
1122 &self,
1123 cmd: &str,
1124 args: &[serde_json::Value],
1125 ) -> Result<T> {
1126 let v_args: Vec<_> = args
1127 .iter()
1128 .map(serde_json::value::to_raw_value)
1129 .collect::<std::result::Result<_, serde_json::Error>>()?;
1130 let req = self.client.build_request(cmd, &v_args[..]);
1131 if log_enabled!(Debug) {
1132 debug!(target: "bitcoincore_rpc", "JSON-RPC request: {} {}", cmd, serde_json::Value::from(args));
1133 }
1134
1135 let resp = self.client.send_request(req).await.map_err(Error::from);
1136 log_response(cmd, &resp);
1137 Ok(resp?.result()?)
1138 }
1139}
1140
1141fn log_response(cmd: &str, resp: &Result<jsonrpc::Response>) {
1142 if log_enabled!(Warn) || log_enabled!(Debug) || log_enabled!(Trace) {
1143 match resp {
1144 Err(ref e) => {
1145 if log_enabled!(Debug) {
1146 debug!(target: "bitcoincore_rpc", "JSON-RPC failed parsing reply of {}: {:?}", cmd, e);
1147 }
1148 }
1149 Ok(ref resp) => {
1150 if let Some(ref e) = resp.error {
1151 if log_enabled!(Debug) {
1152 debug!(target: "bitcoincore_rpc", "JSON-RPC error for {}: {:?}", cmd, e);
1153 }
1154 } else if log_enabled!(Trace) {
1155 let rawnull =
1156 serde_json::value::to_raw_value(&serde_json::Value::Null).unwrap();
1157 let result = resp.result.as_ref().unwrap_or(&rawnull);
1158 trace!(target: "bitcoincore_rpc", "JSON-RPC response for {}: {}", cmd, result);
1159 }
1160 }
1161 }
1162 }
1163}
1164
1165#[cfg(test)]
1166mod tests {
1167 use super::*;
1168 use bitcoin;
1169 use serde_json;
1170 use tokio;
1171
1172 #[tokio::test]
1173 async fn test_raw_tx() {
1174 use bitcoin::consensus::encode;
1175 let client = Client::new("http://localhost/".into(), Auth::None).await.unwrap();
1176 let tx: bitcoin::Transaction = encode::deserialize(&Vec::<u8>::from_hex("0200000001586bd02815cf5faabfec986a4e50d25dbee089bd2758621e61c5fab06c334af0000000006b483045022100e85425f6d7c589972ee061413bcf08dc8c8e589ce37b217535a42af924f0e4d602205c9ba9cb14ef15513c9d946fa1c4b797883e748e8c32171bdf6166583946e35c012103dae30a4d7870cd87b45dd53e6012f71318fdd059c1c2623b8cc73f8af287bb2dfeffffff021dc4260c010000001976a914f602e88b2b5901d8aab15ebe4a97cf92ec6e03b388ac00e1f505000000001976a914687ffeffe8cf4e4c038da46a9b1d37db385a472d88acfd211500").unwrap()).unwrap();
1177
1178 assert!(client.send_raw_transaction(&tx).await.is_err());
1179 assert!(client.send_raw_transaction(&encode::serialize(&tx)).await.is_err());
1180 assert!(client.send_raw_transaction("deadbeef").await.is_err());
1181 assert!(client.send_raw_transaction("deadbeef".to_owned()).await.is_err());
1182 }
1183
1184 fn test_handle_defaults_inner() -> Result<()> {
1185 {
1186 let mut args = [into_json(0)?, null(), null()];
1187 let defaults = [into_json(1)?, into_json(2)?];
1188 let res = [into_json(0)?];
1189 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1190 }
1191 {
1192 let mut args = [into_json(0)?, into_json(1)?, null()];
1193 let defaults = [into_json(2)?];
1194 let res = [into_json(0)?, into_json(1)?];
1195 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1196 }
1197 {
1198 let mut args = [into_json(0)?, null(), into_json(5)?];
1199 let defaults = [into_json(2)?, into_json(3)?];
1200 let res = [into_json(0)?, into_json(2)?, into_json(5)?];
1201 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1202 }
1203 {
1204 let mut args = [into_json(0)?, null(), into_json(5)?, null()];
1205 let defaults = [into_json(2)?, into_json(3)?, into_json(4)?];
1206 let res = [into_json(0)?, into_json(2)?, into_json(5)?];
1207 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1208 }
1209 {
1210 let mut args = [null(), null()];
1211 let defaults = [into_json(2)?, into_json(3)?];
1212 let res: [serde_json::Value; 0] = [];
1213 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1214 }
1215 {
1216 let mut args = [null(), into_json(1)?];
1217 let defaults = [];
1218 let res = [null(), into_json(1)?];
1219 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1220 }
1221 {
1222 let mut args = [];
1223 let defaults = [];
1224 let res: [serde_json::Value; 0] = [];
1225 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1226 }
1227 {
1228 let mut args = [into_json(0)?];
1229 let defaults = [into_json(2)?];
1230 let res = [into_json(0)?];
1231 assert_eq!(handle_defaults(&mut args, &defaults), &res);
1232 }
1233 Ok(())
1234 }
1235
1236 #[test]
1237 fn test_handle_defaults() {
1238 test_handle_defaults_inner().unwrap();
1239 }
1240}