#![crate_name = "bitcoincore_rpc_json"]
#![crate_type = "rlib"]
#![allow(deprecated)] pub extern crate bitcoin;
#[allow(unused)]
#[macro_use] extern crate serde;
extern crate serde_json;
use std::collections::HashMap;
use bitcoin::address::NetworkUnchecked;
use bitcoin::block::Version;
use bitcoin::consensus::encode;
use bitcoin::hashes::hex::FromHex;
use bitcoin::hashes::sha256;
use bitcoin::{Address, Amount, PrivateKey, PublicKey, SignedAmount, Transaction, ScriptBuf, Script, bip158, bip32, Network};
use serde::de::Error as SerdeError;
use serde::{Deserialize, Serialize};
use std::fmt;
pub mod serde_hex {
use bitcoin::hex::{DisplayHex, FromHex};
use serde::de::Error;
use serde::{Deserializer, Serializer};
pub fn serialize<S: Serializer>(b: &Vec<u8>, s: S) -> Result<S::Ok, S::Error> {
s.serialize_str(&b.to_lower_hex_string())
}
pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Vec<u8>, D::Error> {
let hex_str: String = ::serde::Deserialize::deserialize(d)?;
Ok(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?)
}
pub mod opt {
use bitcoin::hex::{DisplayHex, FromHex};
use serde::de::Error;
use serde::{Deserializer, Serializer};
pub fn serialize<S: Serializer>(b: &Option<Vec<u8>>, s: S) -> Result<S::Ok, S::Error> {
match *b {
None => s.serialize_none(),
Some(ref b) => s.serialize_str(&b.to_lower_hex_string()),
}
}
pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<Option<Vec<u8>>, D::Error> {
let hex_str: String = ::serde::Deserialize::deserialize(d)?;
Ok(Some(FromHex::from_hex(&hex_str).map_err(D::Error::custom)?))
}
}
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetNetworkInfoResultNetwork {
pub name: String,
pub limited: bool,
pub reachable: bool,
pub proxy: String,
pub proxy_randomize_credentials: bool,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetNetworkInfoResultAddress {
pub address: String,
pub port: usize,
pub score: usize,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetNetworkInfoResult {
pub version: usize,
pub subversion: String,
#[serde(rename = "protocolversion")]
pub protocol_version: usize,
#[serde(rename = "localservices")]
pub local_services: String,
#[serde(rename = "localrelay")]
pub local_relay: bool,
#[serde(rename = "timeoffset")]
pub time_offset: isize,
pub connections: usize,
pub connections_in: Option<usize>,
pub connections_out: Option<usize>,
#[serde(rename = "networkactive")]
pub network_active: bool,
pub networks: Vec<GetNetworkInfoResultNetwork>,
#[serde(rename = "relayfee", with = "bitcoin::amount::serde::as_btc")]
pub relay_fee: Amount,
#[serde(rename = "incrementalfee", with = "bitcoin::amount::serde::as_btc")]
pub incremental_fee: Amount,
#[serde(rename = "localaddresses")]
pub local_addresses: Vec<GetNetworkInfoResultAddress>,
pub warnings: StringOrStringArray,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct AddMultiSigAddressResult {
pub address: Address<NetworkUnchecked>,
pub redeem_script: ScriptBuf,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct LoadWalletResult {
pub name: String,
pub warning: Option<String>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct UnloadWalletResult {
pub warning: Option<String>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct ListWalletDirResult {
pub wallets: Vec<ListWalletDirItem>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct ListWalletDirItem {
pub name: String,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetWalletInfoResult {
#[serde(rename = "walletname")]
pub wallet_name: String,
#[serde(rename = "walletversion")]
pub wallet_version: u32,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub balance: Amount,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub unconfirmed_balance: Amount,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub immature_balance: Amount,
#[serde(rename = "txcount")]
pub tx_count: usize,
#[serde(rename = "keypoololdest")]
pub keypool_oldest: Option<usize>,
#[serde(rename = "keypoolsize")]
pub keypool_size: usize,
#[serde(rename = "keypoolsize_hd_internal")]
pub keypool_size_hd_internal: usize,
pub unlocked_until: Option<u64>,
#[serde(rename = "paytxfee", with = "bitcoin::amount::serde::as_btc")]
pub pay_tx_fee: Amount,
#[serde(rename = "hdseedid")]
pub hd_seed_id: Option<bitcoin::bip32::XKeyIdentifier>,
pub private_keys_enabled: bool,
pub avoid_reuse: Option<bool>,
pub scanning: Option<ScanningDetails>,
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
#[serde(untagged)]
pub enum ScanningDetails {
Scanning {
duration: usize,
progress: f32,
},
NotScanning(bool),
}
impl Eq for ScanningDetails {}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetBlockResult {
pub hash: bitcoin::BlockHash,
pub confirmations: i32,
pub size: usize,
pub strippedsize: Option<usize>,
pub weight: usize,
pub height: usize,
pub version: i32,
#[serde(default, with = "crate::serde_hex::opt")]
pub version_hex: Option<Vec<u8>>,
pub merkleroot: bitcoin::hash_types::TxMerkleNode,
pub tx: Vec<bitcoin::Txid>,
pub time: usize,
pub mediantime: Option<usize>,
pub nonce: u32,
pub bits: String,
pub difficulty: f64,
#[serde(with = "crate::serde_hex")]
pub chainwork: Vec<u8>,
pub n_tx: usize,
pub previousblockhash: Option<bitcoin::BlockHash>,
pub nextblockhash: Option<bitcoin::BlockHash>,
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetBlockHeaderResult {
pub hash: bitcoin::BlockHash,
pub confirmations: i32,
pub height: usize,
pub version: Version,
#[serde(default, with = "crate::serde_hex::opt")]
pub version_hex: Option<Vec<u8>>,
#[serde(rename = "merkleroot")]
pub merkle_root: bitcoin::hash_types::TxMerkleNode,
pub time: usize,
#[serde(rename = "mediantime")]
pub median_time: Option<usize>,
pub nonce: u32,
pub bits: String,
pub difficulty: f64,
#[serde(with = "crate::serde_hex")]
pub chainwork: Vec<u8>,
pub n_tx: usize,
#[serde(rename = "previousblockhash")]
pub previous_block_hash: Option<bitcoin::BlockHash>,
#[serde(rename = "nextblockhash")]
pub next_block_hash: Option<bitcoin::BlockHash>,
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct GetBlockStatsResult {
#[serde(rename = "avgfee", with = "bitcoin::amount::serde::as_sat")]
pub avg_fee: Amount,
#[serde(rename = "avgfeerate", with = "bitcoin::amount::serde::as_sat")]
pub avg_fee_rate: Amount,
#[serde(rename = "avgtxsize")]
pub avg_tx_size: u32,
#[serde(rename = "blockhash")]
pub block_hash: bitcoin::BlockHash,
#[serde(rename = "feerate_percentiles")]
pub fee_rate_percentiles: FeeRatePercentiles,
pub height: u64,
pub ins: usize,
#[serde(rename = "maxfee", with = "bitcoin::amount::serde::as_sat")]
pub max_fee: Amount,
#[serde(rename = "maxfeerate", with = "bitcoin::amount::serde::as_sat")]
pub max_fee_rate: Amount,
#[serde(rename = "maxtxsize")]
pub max_tx_size: u32,
#[serde(rename = "medianfee", with = "bitcoin::amount::serde::as_sat")]
pub median_fee: Amount,
#[serde(rename = "mediantime")]
pub median_time: u64,
#[serde(rename = "mediantxsize")]
pub median_tx_size: u32,
#[serde(rename = "minfee", with = "bitcoin::amount::serde::as_sat")]
pub min_fee: Amount,
#[serde(rename = "minfeerate", with = "bitcoin::amount::serde::as_sat")]
pub min_fee_rate: Amount,
#[serde(rename = "mintxsize")]
pub min_tx_size: u32,
pub outs: usize,
#[serde(with = "bitcoin::amount::serde::as_sat")]
pub subsidy: Amount,
#[serde(rename = "swtotal_size")]
pub sw_total_size: usize,
#[serde(rename = "swtotal_weight")]
pub sw_total_weight: usize,
#[serde(rename = "swtxs")]
pub sw_txs: usize,
pub time: u64,
#[serde(with = "bitcoin::amount::serde::as_sat")]
pub total_out: Amount,
pub total_size: usize,
pub total_weight: usize,
#[serde(rename = "totalfee", with = "bitcoin::amount::serde::as_sat")]
pub total_fee: Amount,
pub txs: usize,
pub utxo_increase: i32,
pub utxo_size_inc: i32,
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct GetBlockStatsResultPartial {
#[serde(
default,
rename = "avgfee",
with = "bitcoin::amount::serde::as_sat::opt",
skip_serializing_if = "Option::is_none"
)]
pub avg_fee: Option<Amount>,
#[serde(
default,
rename = "avgfeerate",
with = "bitcoin::amount::serde::as_sat::opt",
skip_serializing_if = "Option::is_none"
)]
pub avg_fee_rate: Option<Amount>,
#[serde(default, rename = "avgtxsize", skip_serializing_if = "Option::is_none")]
pub avg_tx_size: Option<u32>,
#[serde(default, rename = "blockhash", skip_serializing_if = "Option::is_none")]
pub block_hash: Option<bitcoin::BlockHash>,
#[serde(default, rename = "feerate_percentiles", skip_serializing_if = "Option::is_none")]
pub fee_rate_percentiles: Option<FeeRatePercentiles>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub height: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub ins: Option<usize>,
#[serde(
default,
rename = "maxfee",
with = "bitcoin::amount::serde::as_sat::opt",
skip_serializing_if = "Option::is_none"
)]
pub max_fee: Option<Amount>,
#[serde(
default,
rename = "maxfeerate",
with = "bitcoin::amount::serde::as_sat::opt",
skip_serializing_if = "Option::is_none"
)]
pub max_fee_rate: Option<Amount>,
#[serde(default, rename = "maxtxsize", skip_serializing_if = "Option::is_none")]
pub max_tx_size: Option<u32>,
#[serde(
default,
rename = "medianfee",
with = "bitcoin::amount::serde::as_sat::opt",
skip_serializing_if = "Option::is_none"
)]
pub median_fee: Option<Amount>,
#[serde(default, rename = "mediantime", skip_serializing_if = "Option::is_none")]
pub median_time: Option<u64>,
#[serde(default, rename = "mediantxsize", skip_serializing_if = "Option::is_none")]
pub median_tx_size: Option<u32>,
#[serde(
default,
rename = "minfee",
with = "bitcoin::amount::serde::as_sat::opt",
skip_serializing_if = "Option::is_none"
)]
pub min_fee: Option<Amount>,
#[serde(
default,
rename = "minfeerate",
with = "bitcoin::amount::serde::as_sat::opt",
skip_serializing_if = "Option::is_none"
)]
pub min_fee_rate: Option<Amount>,
#[serde(default, rename = "mintxsize", skip_serializing_if = "Option::is_none")]
pub min_tx_size: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub outs: Option<usize>,
#[serde(
default,
with = "bitcoin::amount::serde::as_sat::opt",
skip_serializing_if = "Option::is_none"
)]
pub subsidy: Option<Amount>,
#[serde(default, rename = "swtotal_size", skip_serializing_if = "Option::is_none")]
pub sw_total_size: Option<usize>,
#[serde(default, rename = "swtotal_weight", skip_serializing_if = "Option::is_none")]
pub sw_total_weight: Option<usize>,
#[serde(default, rename = "swtxs", skip_serializing_if = "Option::is_none")]
pub sw_txs: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub time: Option<u64>,
#[serde(
default,
with = "bitcoin::amount::serde::as_sat::opt",
skip_serializing_if = "Option::is_none"
)]
pub total_out: Option<Amount>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub total_size: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub total_weight: Option<usize>,
#[serde(
default,
rename = "totalfee",
with = "bitcoin::amount::serde::as_sat::opt",
skip_serializing_if = "Option::is_none"
)]
pub total_fee: Option<Amount>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub txs: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub utxo_increase: Option<i32>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub utxo_size_inc: Option<i32>,
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct FeeRatePercentiles {
#[serde(with = "bitcoin::amount::serde::as_sat")]
pub fr_10th: Amount,
#[serde(with = "bitcoin::amount::serde::as_sat")]
pub fr_25th: Amount,
#[serde(with = "bitcoin::amount::serde::as_sat")]
pub fr_50th: Amount,
#[serde(with = "bitcoin::amount::serde::as_sat")]
pub fr_75th: Amount,
#[serde(with = "bitcoin::amount::serde::as_sat")]
pub fr_90th: Amount,
}
#[derive(Clone)]
pub enum BlockStatsFields {
AverageFee,
AverageFeeRate,
AverageTxSize,
BlockHash,
FeeRatePercentiles,
Height,
Ins,
MaxFee,
MaxFeeRate,
MaxTxSize,
MedianFee,
MedianTime,
MedianTxSize,
MinFee,
MinFeeRate,
MinTxSize,
Outs,
Subsidy,
SegWitTotalSize,
SegWitTotalWeight,
SegWitTxs,
Time,
TotalOut,
TotalSize,
TotalWeight,
TotalFee,
Txs,
UtxoIncrease,
UtxoSizeIncrease,
}
impl BlockStatsFields {
fn get_rpc_keyword(&self) -> &str {
match *self {
BlockStatsFields::AverageFee => "avgfee",
BlockStatsFields::AverageFeeRate => "avgfeerate",
BlockStatsFields::AverageTxSize => "avgtxsize",
BlockStatsFields::BlockHash => "blockhash",
BlockStatsFields::FeeRatePercentiles => "feerate_percentiles",
BlockStatsFields::Height => "height",
BlockStatsFields::Ins => "ins",
BlockStatsFields::MaxFee => "maxfee",
BlockStatsFields::MaxFeeRate => "maxfeerate",
BlockStatsFields::MaxTxSize => "maxtxsize",
BlockStatsFields::MedianFee => "medianfee",
BlockStatsFields::MedianTime => "mediantime",
BlockStatsFields::MedianTxSize => "mediantxsize",
BlockStatsFields::MinFee => "minfee",
BlockStatsFields::MinFeeRate => "minfeerate",
BlockStatsFields::MinTxSize => "minfeerate",
BlockStatsFields::Outs => "outs",
BlockStatsFields::Subsidy => "subsidy",
BlockStatsFields::SegWitTotalSize => "swtotal_size",
BlockStatsFields::SegWitTotalWeight => "swtotal_weight",
BlockStatsFields::SegWitTxs => "swtxs",
BlockStatsFields::Time => "time",
BlockStatsFields::TotalOut => "total_out",
BlockStatsFields::TotalSize => "total_size",
BlockStatsFields::TotalWeight => "total_weight",
BlockStatsFields::TotalFee => "totalfee",
BlockStatsFields::Txs => "txs",
BlockStatsFields::UtxoIncrease => "utxo_increase",
BlockStatsFields::UtxoSizeIncrease => "utxo_size_inc",
}
}
}
impl fmt::Display for BlockStatsFields {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.get_rpc_keyword())
}
}
impl From<BlockStatsFields> for serde_json::Value {
fn from(bsf: BlockStatsFields) -> Self {
Self::from(bsf.to_string())
}
}
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetMiningInfoResult {
pub blocks: u32,
#[serde(rename = "currentblockweight")]
pub current_block_weight: Option<u64>,
#[serde(rename = "currentblocktx")]
pub current_block_tx: Option<usize>,
pub difficulty: f64,
#[serde(rename = "networkhashps")]
pub network_hash_ps: f64,
#[serde(rename = "pooledtx")]
pub pooled_tx: usize,
#[serde(deserialize_with = "deserialize_bip70_network")]
pub chain: Network,
pub warnings: StringOrStringArray,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetRawTransactionResultVinScriptSig {
pub asm: String,
#[serde(with = "crate::serde_hex")]
pub hex: Vec<u8>,
}
impl GetRawTransactionResultVinScriptSig {
pub fn script(&self) -> Result<ScriptBuf, encode::Error> {
Ok(ScriptBuf::from(self.hex.clone()))
}
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetRawTransactionResultVin {
pub sequence: u32,
#[serde(default, with = "crate::serde_hex::opt")]
pub coinbase: Option<Vec<u8>>,
pub txid: Option<bitcoin::Txid>,
pub vout: Option<u32>,
pub script_sig: Option<GetRawTransactionResultVinScriptSig>,
#[serde(default, deserialize_with = "deserialize_hex_array_opt")]
pub txinwitness: Option<Vec<Vec<u8>>>,
}
impl GetRawTransactionResultVin {
pub fn is_coinbase(&self) -> bool {
self.coinbase.is_some()
}
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetRawTransactionResultVoutScriptPubKey {
pub asm: String,
#[serde(with = "crate::serde_hex")]
pub hex: Vec<u8>,
pub req_sigs: Option<usize>,
#[serde(rename = "type")]
pub type_: Option<ScriptPubkeyType>,
#[serde(default)]
pub addresses: Vec<Address<NetworkUnchecked>>,
#[serde(default)]
pub address: Option<Address<NetworkUnchecked>>,
}
impl GetRawTransactionResultVoutScriptPubKey {
pub fn script(&self) -> Result<ScriptBuf, encode::Error> {
Ok(ScriptBuf::from(self.hex.clone()))
}
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetRawTransactionResultVout {
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub value: Amount,
pub n: u32,
pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetRawTransactionResult {
#[serde(rename = "in_active_chain")]
pub in_active_chain: Option<bool>,
#[serde(with = "crate::serde_hex")]
pub hex: Vec<u8>,
pub txid: bitcoin::Txid,
pub hash: bitcoin::Wtxid,
pub size: usize,
pub vsize: usize,
pub version: u32,
pub locktime: u32,
pub vin: Vec<GetRawTransactionResultVin>,
pub vout: Vec<GetRawTransactionResultVout>,
pub blockhash: Option<bitcoin::BlockHash>,
pub confirmations: Option<u32>,
pub time: Option<usize>,
pub blocktime: Option<usize>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetBlockFilterResult {
pub header: bitcoin::hash_types::FilterHash,
#[serde(with = "crate::serde_hex")]
pub filter: Vec<u8>,
}
impl GetBlockFilterResult {
pub fn to_filter(&self) -> bip158::BlockFilter {
bip158::BlockFilter::new(&self.filter)
}
pub fn into_filter(self) -> bip158::BlockFilter {
bip158::BlockFilter {
content: self.filter,
}
}
}
impl GetRawTransactionResult {
pub fn is_coinbase(&self) -> bool {
self.vin.len() == 1 && self.vin[0].is_coinbase()
}
pub fn transaction(&self) -> Result<Transaction, encode::Error> {
Ok(encode::deserialize(&self.hex)?)
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum Bip125Replaceable {
Yes,
No,
Unknown,
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum GetTransactionResultDetailCategory {
Send,
Receive,
Generate,
Immature,
Orphan,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetTransactionResultDetail {
pub address: Option<Address<NetworkUnchecked>>,
pub category: GetTransactionResultDetailCategory,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub amount: SignedAmount,
pub label: Option<String>,
pub vout: u32,
#[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
pub fee: Option<SignedAmount>,
pub abandoned: Option<bool>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct WalletTxInfo {
pub confirmations: i32,
pub blockhash: Option<bitcoin::BlockHash>,
pub blockindex: Option<usize>,
pub blocktime: Option<u64>,
pub blockheight: Option<u32>,
pub txid: bitcoin::Txid,
pub time: u64,
pub timereceived: u64,
#[serde(rename = "bip125-replaceable")]
pub bip125_replaceable: Bip125Replaceable,
#[serde(rename = "walletconflicts")]
pub wallet_conflicts: Vec<bitcoin::Txid>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetTransactionResult {
#[serde(flatten)]
pub info: WalletTxInfo,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub amount: SignedAmount,
#[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
pub fee: Option<SignedAmount>,
pub details: Vec<GetTransactionResultDetail>,
#[serde(with = "crate::serde_hex")]
pub hex: Vec<u8>,
}
impl GetTransactionResult {
pub fn transaction(&self) -> Result<Transaction, encode::Error> {
Ok(encode::deserialize(&self.hex)?)
}
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct ListTransactionResult {
#[serde(flatten)]
pub info: WalletTxInfo,
#[serde(flatten)]
pub detail: GetTransactionResultDetail,
pub trusted: Option<bool>,
pub comment: Option<String>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct ListSinceBlockResult {
pub transactions: Vec<ListTransactionResult>,
#[serde(default)]
pub removed: Vec<ListTransactionResult>,
pub lastblock: bitcoin::BlockHash,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetTxOutResult {
pub bestblock: bitcoin::BlockHash,
pub confirmations: u32,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub value: Amount,
pub script_pub_key: GetRawTransactionResultVoutScriptPubKey,
pub coinbase: bool,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
#[serde(rename_all = "camelCase")]
pub struct ListUnspentQueryOptions {
#[serde(
rename = "minimumAmount",
with = "bitcoin::amount::serde::as_btc::opt",
skip_serializing_if = "Option::is_none"
)]
pub minimum_amount: Option<Amount>,
#[serde(
rename = "maximumAmount",
with = "bitcoin::amount::serde::as_btc::opt",
skip_serializing_if = "Option::is_none"
)]
pub maximum_amount: Option<Amount>,
#[serde(rename = "maximumCount", skip_serializing_if = "Option::is_none")]
pub maximum_count: Option<usize>,
#[serde(
rename = "minimumSumAmount",
with = "bitcoin::amount::serde::as_btc::opt",
skip_serializing_if = "Option::is_none"
)]
pub minimum_sum_amount: Option<Amount>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ListUnspentResultEntry {
pub txid: bitcoin::Txid,
pub vout: u32,
pub address: Option<Address<NetworkUnchecked>>,
pub label: Option<String>,
pub redeem_script: Option<ScriptBuf>,
pub witness_script: Option<ScriptBuf>,
pub script_pub_key: ScriptBuf,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub amount: Amount,
pub confirmations: u32,
pub spendable: bool,
pub solvable: bool,
#[serde(rename = "desc")]
pub descriptor: Option<String>,
pub safe: bool,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ListReceivedByAddressResult {
#[serde(default, rename = "involvesWatchonly")]
pub involved_watch_only: bool,
pub address: Address<NetworkUnchecked>,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub amount: Amount,
pub confirmations: u32,
pub label: String,
pub txids: Vec<bitcoin::Txid>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SignRawTransactionResultError {
pub txid: bitcoin::Txid,
pub vout: u32,
pub script_sig: ScriptBuf,
pub sequence: u32,
pub error: String,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct SignRawTransactionResult {
#[serde(with = "crate::serde_hex")]
pub hex: Vec<u8>,
pub complete: bool,
pub errors: Option<Vec<SignRawTransactionResultError>>,
}
impl SignRawTransactionResult {
pub fn transaction(&self) -> Result<Transaction, encode::Error> {
Ok(encode::deserialize(&self.hex)?)
}
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct TestMempoolAcceptResult {
pub txid: bitcoin::Txid,
pub allowed: bool,
#[serde(rename = "reject-reason")]
pub reject_reason: Option<String>,
pub vsize: Option<u64>,
pub fees: Option<TestMempoolAcceptResultFees>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct TestMempoolAcceptResultFees {
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub base: Amount,
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Bip9SoftforkStatus {
Defined,
Started,
LockedIn,
Active,
Failed,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct Bip9SoftforkStatistics {
pub period: u32,
pub threshold: Option<u32>,
pub elapsed: u32,
pub count: u32,
pub possible: Option<bool>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct Bip9SoftforkInfo {
pub status: Bip9SoftforkStatus,
pub bit: Option<u8>,
pub start_time: i64,
pub timeout: u64,
pub since: u32,
pub statistics: Option<Bip9SoftforkStatistics>,
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum SoftforkType {
Buried,
Bip9,
#[serde(other)]
Other,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct Softfork {
#[serde(rename = "type")]
pub type_: SoftforkType,
pub bip9: Option<Bip9SoftforkInfo>,
pub height: Option<u32>,
pub active: bool,
}
#[allow(non_camel_case_types)]
#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum ScriptPubkeyType {
Nonstandard,
Pubkey,
PubkeyHash,
ScriptHash,
MultiSig,
NullData,
Witness_v0_KeyHash,
Witness_v0_ScriptHash,
Witness_v1_Taproot,
Witness_Unknown,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetAddressInfoResultEmbedded {
pub address: Address<NetworkUnchecked>,
#[serde(rename = "scriptPubKey")]
pub script_pub_key: ScriptBuf,
#[serde(rename = "is_script")]
pub is_script: Option<bool>,
#[serde(rename = "is_witness")]
pub is_witness: Option<bool>,
pub witness_version: Option<u32>,
#[serde(with = "crate::serde_hex")]
pub witness_program: Vec<u8>,
pub script: Option<ScriptPubkeyType>,
#[serde(default, with = "crate::serde_hex::opt")]
pub hex: Option<Vec<u8>>,
pub pubkeys: Option<Vec<PublicKey>>,
#[serde(rename = "sigsrequired")]
pub n_signatures_required: Option<usize>,
pub pubkey: Option<PublicKey>,
#[serde(rename = "is_compressed")]
pub is_compressed: Option<bool>,
pub label: Option<String>,
#[serde(rename = "hdkeypath")]
pub hd_key_path: Option<bip32::DerivationPath>,
#[serde(rename = "hdseedid")]
pub hd_seed_id: Option<bitcoin::bip32::XKeyIdentifier>,
#[serde(default)]
pub labels: Vec<GetAddressInfoResultLabel>,
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum GetAddressInfoResultLabelPurpose {
Send,
Receive,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(untagged)]
pub enum GetAddressInfoResultLabel {
Simple(String),
WithPurpose {
name: String,
purpose: GetAddressInfoResultLabelPurpose,
},
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetAddressInfoResult {
pub address: Address<NetworkUnchecked>,
#[serde(rename = "scriptPubKey")]
pub script_pub_key: ScriptBuf,
#[serde(rename = "ismine")]
pub is_mine: Option<bool>,
#[serde(rename = "iswatchonly")]
pub is_watchonly: Option<bool>,
#[serde(rename = "isscript")]
pub is_script: Option<bool>,
#[serde(rename = "iswitness")]
pub is_witness: Option<bool>,
pub witness_version: Option<u32>,
#[serde(default, with = "crate::serde_hex::opt")]
pub witness_program: Option<Vec<u8>>,
pub script: Option<ScriptPubkeyType>,
#[serde(default, with = "crate::serde_hex::opt")]
pub hex: Option<Vec<u8>>,
pub pubkeys: Option<Vec<PublicKey>>,
#[serde(rename = "sigsrequired")]
pub n_signatures_required: Option<usize>,
pub pubkey: Option<PublicKey>,
pub embedded: Option<GetAddressInfoResultEmbedded>,
#[serde(rename = "is_compressed")]
pub is_compressed: Option<bool>,
pub timestamp: Option<u64>,
#[serde(rename = "hdkeypath")]
pub hd_key_path: Option<bip32::DerivationPath>,
#[serde(rename = "hdseedid")]
pub hd_seed_id: Option<bitcoin::bip32::XKeyIdentifier>,
pub labels: Vec<GetAddressInfoResultLabel>,
#[deprecated(note = "since Core v0.20.0")]
pub label: Option<String>,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
#[serde(untagged)]
pub enum StringOrStringArray {
String(String),
StringArray(Vec<String>),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GetBlockchainInfoResult {
#[serde(deserialize_with = "deserialize_bip70_network")]
pub chain: Network,
pub blocks: u64,
pub headers: u64,
#[serde(rename = "bestblockhash")]
pub best_block_hash: bitcoin::BlockHash,
pub difficulty: f64,
#[serde(rename = "mediantime")]
pub median_time: u64,
#[serde(rename = "verificationprogress")]
pub verification_progress: f64,
#[serde(rename = "initialblockdownload")]
pub initial_block_download: bool,
#[serde(rename = "chainwork", with = "crate::serde_hex")]
pub chain_work: Vec<u8>,
pub size_on_disk: u64,
pub pruned: bool,
#[serde(rename = "pruneheight")]
pub prune_height: Option<u64>,
pub automatic_pruning: Option<bool>,
pub prune_target_size: Option<u64>,
#[serde(default)]
pub softforks: HashMap<String, Softfork>,
pub warnings: StringOrStringArray,
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum ImportMultiRequestScriptPubkey<'a> {
Address(&'a Address),
Script(&'a Script),
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetMempoolInfoResult {
pub loaded: Option<bool>,
pub size: usize,
pub bytes: usize,
pub usage: usize,
#[serde(default, with = "bitcoin::amount::serde::as_btc::opt")]
pub total_fee: Option<Amount>,
#[serde(rename = "maxmempool")]
pub max_mempool: usize,
#[serde(rename = "mempoolminfee", with = "bitcoin::amount::serde::as_btc")]
pub mempool_min_fee: Amount,
#[serde(rename = "minrelaytxfee", with = "bitcoin::amount::serde::as_btc")]
pub min_relay_tx_fee: Amount,
#[serde(rename = "incrementalrelayfee", default, with = "bitcoin::amount::serde::as_btc::opt")]
pub incremental_relay_fee: Option<Amount>,
#[serde(rename = "unbroadcastcount")]
pub unbroadcast_count: Option<usize>,
#[serde(rename = "fullrbf")]
pub full_rbf: Option<bool>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetMempoolEntryResult {
#[serde(alias = "size")]
pub vsize: u64,
pub weight: Option<u64>,
pub time: u64,
pub height: u64,
#[serde(rename = "descendantcount")]
pub descendant_count: u64,
#[serde(rename = "descendantsize")]
pub descendant_size: u64,
#[serde(rename = "ancestorcount")]
pub ancestor_count: u64,
#[serde(rename = "ancestorsize")]
pub ancestor_size: u64,
pub wtxid: bitcoin::Txid,
pub fees: GetMempoolEntryResultFees,
pub depends: Vec<bitcoin::Txid>,
#[serde(rename = "spentby")]
pub spent_by: Vec<bitcoin::Txid>,
#[serde(rename = "bip125-replaceable")]
pub bip125_replaceable: bool,
pub unbroadcast: Option<bool>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetMempoolEntryResultFees {
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub base: Amount,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub modified: Amount,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub ancestor: Amount,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub descendant: Amount,
}
impl<'a> serde::Serialize for ImportMultiRequestScriptPubkey<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match *self {
ImportMultiRequestScriptPubkey::Address(ref addr) => {
#[derive(Serialize)]
struct Tmp<'a> {
pub address: &'a Address,
}
serde::Serialize::serialize(
&Tmp {
address: addr,
},
serializer,
)
}
ImportMultiRequestScriptPubkey::Script(script) => {
serializer.serialize_str(&script.to_hex_string())
}
}
}
}
#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize)]
pub struct ImportMultiRequest<'a> {
pub timestamp: Timestamp,
#[serde(rename = "desc", skip_serializing_if = "Option::is_none")]
pub descriptor: Option<&'a str>,
#[serde(rename = "scriptPubKey", skip_serializing_if = "Option::is_none")]
pub script_pubkey: Option<ImportMultiRequestScriptPubkey<'a>>,
#[serde(rename = "redeemscript", skip_serializing_if = "Option::is_none")]
pub redeem_script: Option<&'a Script>,
#[serde(rename = "witnessscript", skip_serializing_if = "Option::is_none")]
pub witness_script: Option<&'a Script>,
#[serde(skip_serializing_if = "<[_]>::is_empty")]
pub pubkeys: &'a [PublicKey],
#[serde(skip_serializing_if = "<[_]>::is_empty")]
pub keys: &'a [PrivateKey],
#[serde(skip_serializing_if = "Option::is_none")]
pub range: Option<(usize, usize)>,
#[serde(skip_serializing_if = "Option::is_none")]
pub internal: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub watchonly: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<&'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub keypool: Option<bool>,
}
#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
pub struct ImportMultiOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub rescan: Option<bool>,
}
#[derive(Clone, PartialEq, Eq, Copy, Debug)]
pub enum Timestamp {
Now,
Time(u64),
}
impl serde::Serialize for Timestamp {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match *self {
Timestamp::Now => serializer.serialize_str("now"),
Timestamp::Time(timestamp) => serializer.serialize_u64(timestamp),
}
}
}
impl<'de> serde::Deserialize<'de> for Timestamp {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
use serde::de;
struct Visitor;
impl<'de> de::Visitor<'de> for Visitor {
type Value = Timestamp;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "unix timestamp or 'now'")
}
fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Timestamp::Time(value))
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
if value == "now" {
Ok(Timestamp::Now)
} else {
Err(de::Error::custom(format!(
"invalid str '{}', expecting 'now' or unix timestamp",
value
)))
}
}
}
deserializer.deserialize_any(Visitor)
}
}
impl Default for Timestamp {
fn default() -> Self {
Timestamp::Time(0)
}
}
impl From<u64> for Timestamp {
fn from(t: u64) -> Self {
Timestamp::Time(t)
}
}
impl From<Option<u64>> for Timestamp {
fn from(timestamp: Option<u64>) -> Self {
timestamp.map_or(Timestamp::Now, Timestamp::Time)
}
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct ImportMultiResultError {
pub code: i64,
pub message: String,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct ImportMultiResult {
pub success: bool,
#[serde(default)]
pub warnings: Vec<String>,
pub error: Option<ImportMultiResultError>,
}
#[derive(Clone, PartialEq, Eq, Debug, Default, Deserialize, Serialize)]
pub struct ImportDescriptors {
#[serde(rename = "desc")]
pub descriptor: String,
pub timestamp: Timestamp,
#[serde(skip_serializing_if = "Option::is_none")]
pub active: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub range: Option<(usize, usize)>,
#[serde(skip_serializing_if = "Option::is_none")]
pub next_index: Option<usize>,
#[serde(skip_serializing_if = "Option::is_none")]
pub internal: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub label: Option<String>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct RejectStatus {
pub status: bool,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GetPeerInfoResult {
pub id: u64,
pub addr: String,
pub addrbind: String,
pub addrlocal: Option<String>,
pub network: Option<GetPeerInfoResultNetwork>,
pub services: String,
pub relaytxes: bool,
pub lastsend: u64,
pub lastrecv: u64,
pub last_transaction: Option<u64>,
pub last_block: Option<u64>,
pub bytessent: u64,
pub bytesrecv: u64,
pub conntime: u64,
pub timeoffset: i64,
pub pingtime: Option<f64>,
pub minping: Option<f64>,
pub pingwait: Option<f64>,
pub version: u64,
pub subver: String,
pub inbound: bool,
pub addnode: Option<bool>,
pub startingheight: i64,
pub banscore: Option<i64>,
pub synced_headers: i64,
pub synced_blocks: i64,
pub inflight: Vec<u64>,
pub whitelisted: Option<bool>,
#[serde(rename = "minfeefilter", default, with = "bitcoin::amount::serde::as_btc::opt")]
pub min_fee_filter: Option<Amount>,
pub bytessent_per_msg: HashMap<String, u64>,
pub bytesrecv_per_msg: HashMap<String, u64>,
pub connection_type: Option<GetPeerInfoResultConnectionType>,
}
#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "snake_case")]
pub enum GetPeerInfoResultNetwork {
Ipv4,
Ipv6,
Onion,
#[deprecated]
Unroutable,
NotPubliclyRoutable,
I2p,
Cjdns,
Internal,
}
#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "kebab-case")]
pub enum GetPeerInfoResultConnectionType {
OutboundFullRelay,
BlockRelayOnly,
Inbound,
Manual,
AddrFetch,
Feeler,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetAddedNodeInfoResult {
#[serde(rename = "addednode")]
pub added_node: String,
pub connected: bool,
pub addresses: Vec<GetAddedNodeInfoResultAddress>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetAddedNodeInfoResultAddress {
pub address: String,
pub connected: GetAddedNodeInfoResultAddressType,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum GetAddedNodeInfoResultAddressType {
Inbound,
Outbound,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetNodeAddressesResult {
pub time: u64,
pub services: usize,
pub address: String,
pub port: u16,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct ListBannedResult {
pub address: String,
pub banned_until: u64,
pub ban_created: u64,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct EstimateSmartFeeResult {
#[serde(
default,
rename = "feerate",
skip_serializing_if = "Option::is_none",
with = "bitcoin::amount::serde::as_btc::opt"
)]
pub fee_rate: Option<Amount>,
pub errors: Option<Vec<String>>,
pub blocks: i64,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct BlockRef {
pub hash: bitcoin::BlockHash,
pub height: u64,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetDescriptorInfoResult {
pub descriptor: String,
pub checksum: Option<String>,
#[serde(rename = "isrange")]
pub is_range: bool,
#[serde(rename = "issolvable")]
pub is_solvable: bool,
#[serde(rename = "hasprivatekeys")]
pub has_private_keys: bool,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetBlockTemplateOptions {
pub mode: GetBlockTemplateModes,
pub rules: Vec<GetBlockTemplateRules>,
pub capabilities: Vec<GetBlockTemplateCapabilities>,
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum GetBlockTemplateCapabilities {
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum GetBlockTemplateRules {
SegWit,
Signet,
Csv,
Taproot,
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum GetBlockTemplateModes {
Template,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetBlockTemplateResult {
#[serde(with = "crate::serde_hex")]
pub bits: Vec<u8>,
#[serde(rename = "previousblockhash")]
pub previous_block_hash: bitcoin::BlockHash,
#[serde(rename = "curtime")]
pub current_time: u64,
pub height: u64,
#[serde(rename = "sigoplimit")]
pub sigop_limit: u32,
#[serde(rename = "sizelimit")]
pub size_limit: u32,
#[serde(rename = "weightlimit")]
pub weight_limit: u32,
pub version: u32,
pub rules: Vec<GetBlockTemplateResultRules>,
pub capabilities: Vec<GetBlockTemplateResultCapabilities>,
#[serde(rename = "vbavailable")]
pub version_bits_available: HashMap<String, u32>,
#[serde(rename = "vbrequired")]
pub version_bits_required: u32,
pub longpollid: String,
pub transactions: Vec<GetBlockTemplateResultTransaction>,
#[serde(default, with = "bitcoin::script::ScriptBuf")]
pub signet_challenge: bitcoin::script::ScriptBuf,
#[serde(with = "bitcoin::script::ScriptBuf", default)]
pub default_witness_commitment: bitcoin::script::ScriptBuf,
pub coinbaseaux: HashMap<String, String>,
#[serde(rename = "coinbasevalue", with = "bitcoin::amount::serde::as_sat", default)]
pub coinbase_value: Amount,
#[serde(with = "crate::serde_hex")]
pub target: Vec<u8>,
#[serde(rename = "mintime")]
pub min_time: u64,
pub mutable: Vec<GetBlockTemplateResulMutations>,
#[serde(with = "crate::serde_hex", rename = "noncerange")]
pub nonce_range: Vec<u8>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetBlockTemplateResultTransaction {
pub txid: bitcoin::Txid,
#[serde(rename = "hash")]
pub wtxid: bitcoin::Wtxid,
#[serde(with = "crate::serde_hex", rename = "data")]
pub raw_tx: Vec<u8>,
#[serde(with = "bitcoin::amount::serde::as_sat")]
pub fee: Amount,
pub sigops: u32,
pub weight: usize,
pub depends: Vec<u32>,
}
impl GetBlockTemplateResultTransaction {
pub fn transaction(&self) -> Result<Transaction, encode::Error> {
encode::deserialize(&self.raw_tx)
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum GetBlockTemplateResultCapabilities {
Proposal,
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum GetBlockTemplateResultRules {
#[serde(alias = "!segwit")]
SegWit,
#[serde(alias = "!signet")]
Signet,
Csv,
Taproot,
Testdummy,
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum GetBlockTemplateResulMutations {
Time,
Transactions,
#[serde(rename = "prevblock")]
PreviousBlock,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct WalletCreateFundedPsbtResult {
pub psbt: String,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub fee: Amount,
#[serde(rename = "changepos")]
pub change_position: i32,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct WalletProcessPsbtResult {
pub psbt: String,
pub complete: bool,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize, Default)]
pub struct WalletCreateFundedPsbtOptions {
#[serde(skip_serializing_if = "Option::is_none")]
pub add_inputs: Option<bool>,
#[serde(rename = "changeAddress", skip_serializing_if = "Option::is_none")]
pub change_address: Option<Address<NetworkUnchecked>>,
#[serde(rename = "changePosition", skip_serializing_if = "Option::is_none")]
pub change_position: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
pub change_type: Option<AddressType>,
#[serde(rename = "includeWatching", skip_serializing_if = "Option::is_none")]
pub include_watching: Option<bool>,
#[serde(rename = "lockUnspents", skip_serializing_if = "Option::is_none")]
pub lock_unspent: Option<bool>,
#[serde(
rename = "feeRate",
skip_serializing_if = "Option::is_none",
with = "bitcoin::amount::serde::as_btc::opt"
)]
pub fee_rate: Option<Amount>,
#[serde(rename = "subtractFeeFromOutputs", skip_serializing_if = "Vec::is_empty")]
pub subtract_fee_from_outputs: Vec<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
pub replaceable: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub conf_target: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
pub estimate_mode: Option<EstimateMode>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct FinalizePsbtResult {
pub psbt: Option<String>,
#[serde(default, with = "crate::serde_hex::opt")]
pub hex: Option<Vec<u8>>,
pub complete: bool,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct DecodeRawTransactionResult {
pub txid: bitcoin::Txid,
pub hash: bitcoin::Wtxid,
pub size: u32,
pub vsize: u32,
pub weight: u32,
pub version: u32,
pub locktime: u32,
pub vin: Vec<GetRawTransactionResultVin>,
pub vout: Vec<GetRawTransactionResultVout>,
}
pub type GetChainTipsResult = Vec<GetChainTipsResultTip>;
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetChainTipsResultTip {
pub height: u64,
pub hash: bitcoin::BlockHash,
#[serde(rename = "branchlen")]
pub branch_length: usize,
pub status: GetChainTipsResultStatus,
}
#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "lowercase")]
pub enum GetChainTipsResultStatus {
Invalid,
#[serde(rename = "headers-only")]
HeadersOnly,
#[serde(rename = "valid-headers")]
ValidHeaders,
#[serde(rename = "valid-fork")]
ValidFork,
Active,
}
impl FinalizePsbtResult {
pub fn transaction(&self) -> Option<Result<Transaction, encode::Error>> {
self.hex.as_ref().map(|h| encode::deserialize(h))
}
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq, Hash)]
#[serde(rename_all = "UPPERCASE")]
pub enum EstimateMode {
Unset,
Economical,
Conservative,
}
pub struct SigHashType(bitcoin::sighash::EcdsaSighashType);
impl From<bitcoin::sighash::EcdsaSighashType> for SigHashType {
fn from(sht: bitcoin::sighash::EcdsaSighashType) -> SigHashType {
SigHashType(sht)
}
}
impl serde::Serialize for SigHashType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(match self.0 {
bitcoin::sighash::EcdsaSighashType::All => "ALL",
bitcoin::sighash::EcdsaSighashType::None => "NONE",
bitcoin::sighash::EcdsaSighashType::Single => "SINGLE",
bitcoin::sighash::EcdsaSighashType::AllPlusAnyoneCanPay => "ALL|ANYONECANPAY",
bitcoin::sighash::EcdsaSighashType::NonePlusAnyoneCanPay => "NONE|ANYONECANPAY",
bitcoin::sighash::EcdsaSighashType::SinglePlusAnyoneCanPay => "SINGLE|ANYONECANPAY",
})
}
}
#[derive(Serialize, Clone, PartialEq, Eq, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CreateRawTransactionInput {
pub txid: bitcoin::Txid,
pub vout: u32,
#[serde(skip_serializing_if = "Option::is_none")]
pub sequence: Option<u32>,
}
#[derive(Serialize, Clone, PartialEq, Eq, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct FundRawTransactionOptions {
#[serde(rename = "add_inputs", skip_serializing_if = "Option::is_none")]
pub add_inputs: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub change_address: Option<Address>,
#[serde(skip_serializing_if = "Option::is_none")]
pub change_position: Option<u32>,
#[serde(rename = "change_type", skip_serializing_if = "Option::is_none")]
pub change_type: Option<AddressType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub include_watching: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lock_unspents: Option<bool>,
#[serde(
with = "bitcoin::amount::serde::as_btc::opt",
skip_serializing_if = "Option::is_none"
)]
pub fee_rate: Option<Amount>,
#[serde(skip_serializing_if = "Option::is_none")]
pub subtract_fee_from_outputs: Option<Vec<u32>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub replaceable: Option<bool>,
#[serde(rename = "conf_target", skip_serializing_if = "Option::is_none")]
pub conf_target: Option<u32>,
#[serde(rename = "estimate_mode", skip_serializing_if = "Option::is_none")]
pub estimate_mode: Option<EstimateMode>,
}
#[derive(Deserialize, Clone, PartialEq, Eq, Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct FundRawTransactionResult {
#[serde(with = "crate::serde_hex")]
pub hex: Vec<u8>,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub fee: Amount,
#[serde(rename = "changepos")]
pub change_position: i32,
}
#[derive(Deserialize, Clone, PartialEq, Eq, Debug, Serialize)]
pub struct GetBalancesResultEntry {
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub trusted: Amount,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub untrusted_pending: Amount,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub immature: Amount,
}
#[derive(Deserialize, Clone, PartialEq, Eq, Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct GetBalancesResult {
pub mine: GetBalancesResultEntry,
pub watchonly: Option<GetBalancesResultEntry>,
}
impl FundRawTransactionResult {
pub fn transaction(&self) -> Result<Transaction, encode::Error> {
encode::deserialize(&self.hex)
}
}
#[derive(Serialize, Clone, PartialEq, Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SignRawTransactionInput {
pub txid: bitcoin::Txid,
pub vout: u32,
pub script_pub_key: ScriptBuf,
#[serde(skip_serializing_if = "Option::is_none")]
pub redeem_script: Option<ScriptBuf>,
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "bitcoin::amount::serde::as_btc::opt"
)]
pub amount: Option<Amount>,
}
#[derive(Clone, Serialize, PartialEq, Eq, Debug, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TxOutSetHashType {
HashSerialized2,
Muhash,
None,
}
#[derive(Clone, Serialize, PartialEq, Eq, Debug, Deserialize)]
#[serde(untagged)]
pub enum HashOrHeight {
BlockHash(bitcoin::BlockHash),
Height(u64),
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetTxOutSetInfoResult {
pub height: u64,
#[serde(rename = "bestblock")]
pub best_block: bitcoin::BlockHash,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub transactions: Option<u64>,
#[serde(rename = "txouts")]
pub tx_outs: u64,
pub bogosize: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub hash_serialized_2: Option<sha256::Hash>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub muhash: Option<sha256::Hash>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub disk_size: Option<u64>,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub total_amount: Amount,
#[serde(
default,
skip_serializing_if = "Option::is_none",
with = "bitcoin::amount::serde::as_btc::opt"
)]
pub total_unspendable_amount: Option<Amount>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub block_info: Option<BlockInfo>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct BlockInfo {
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub prevout_spent: Amount,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub coinbase: Amount,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub new_outputs_ex_coinbase: Amount,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub unspendable: Amount,
pub unspendables: Unspendables,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct Unspendables {
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub genesis_block: Amount,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub bip30: Amount,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub scripts: Amount,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub unclaimed_rewards: Amount,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetNetTotalsResult {
#[serde(rename = "totalbytesrecv")]
pub total_bytes_recv: u64,
#[serde(rename = "totalbytessent")]
pub total_bytes_sent: u64,
#[serde(rename = "timemillis")]
pub time_millis: u64,
#[serde(rename = "uploadtarget")]
pub upload_target: GetNetTotalsResultUploadTarget,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetNetTotalsResultUploadTarget {
#[serde(rename = "timeframe")]
pub time_frame: u64,
pub target: u64,
pub target_reached: bool,
pub serve_historical_blocks: bool,
pub bytes_left_in_cycle: u64,
pub time_left_in_cycle: u64,
}
#[derive(Copy, Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "kebab-case")]
pub enum AddressType {
Legacy,
P2shSegwit,
Bech32,
Bech32m,
}
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub enum PubKeyOrAddress<'a> {
Address(&'a Address),
PubKey(&'a PublicKey),
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(untagged)]
pub enum ScanTxOutRequest {
Single(String),
Extended {
desc: String,
range: (u64, u64),
},
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
pub struct ScanTxOutResult {
pub success: Option<bool>,
#[serde(rename = "txouts")]
pub tx_outs: Option<u64>,
pub height: Option<u64>,
#[serde(rename = "bestblock")]
pub best_block_hash: Option<bitcoin::BlockHash>,
pub unspents: Vec<Utxo>,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub total_amount: bitcoin::Amount,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Utxo {
pub txid: bitcoin::Txid,
pub vout: u32,
pub script_pub_key: bitcoin::ScriptBuf,
#[serde(rename = "desc")]
pub descriptor: String,
#[serde(with = "bitcoin::amount::serde::as_btc")]
pub amount: bitcoin::Amount,
pub height: u64,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
pub struct IndexStatus {
pub synced: bool,
pub best_block_height: u32,
}
#[derive(Serialize, Deserialize, Clone, PartialEq, Eq, Debug)]
pub struct GetIndexInfoResult {
pub txindex: Option<IndexStatus>,
pub coinstatsindex: Option<IndexStatus>,
#[serde(rename = "basic block filter index")]
pub basic_block_filter_index: Option<IndexStatus>,
}
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
pub struct GetZmqNotificationsResult {
#[serde(rename = "type")]
pub notification_type: String,
pub address: String,
pub hwm: u64,
}
impl<'a> serde::Serialize for PubKeyOrAddress<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match *self {
PubKeyOrAddress::Address(a) => serde::Serialize::serialize(a, serializer),
PubKeyOrAddress::PubKey(k) => serde::Serialize::serialize(k, serializer),
}
}
}
fn deserialize_hex_array_opt<'de, D>(deserializer: D) -> Result<Option<Vec<Vec<u8>>>, D::Error>
where
D: serde::Deserializer<'de>,
{
let v: Vec<String> = Vec::deserialize(deserializer)?;
let mut res = Vec::new();
for h in v.into_iter() {
res.push(FromHex::from_hex(&h).map_err(D::Error::custom)?);
}
Ok(Some(res))
}
fn deserialize_bip70_network<'de, D>(deserializer: D) -> Result<Network, D::Error>
where
D: serde::Deserializer<'de>,
{
struct NetworkVisitor;
impl<'de> serde::de::Visitor<'de> for NetworkVisitor {
type Value = Network;
fn visit_str<E: serde::de::Error>(self, s: &str) -> Result<Self::Value, E> {
Network::from_core_arg(s)
.map_err(|_| E::invalid_value(serde::de::Unexpected::Str(s), &"bitcoin network encoded as a string"))
}
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "bitcoin network encoded as a string")
}
}
deserializer.deserialize_str(NetworkVisitor)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_softfork_type() {
let buried: SoftforkType = serde_json::from_str("\"buried\"").unwrap();
assert_eq!(buried, SoftforkType::Buried);
let bip9: SoftforkType = serde_json::from_str("\"bip9\"").unwrap();
assert_eq!(bip9, SoftforkType::Bip9);
let other: SoftforkType = serde_json::from_str("\"bip8\"").unwrap();
assert_eq!(other, SoftforkType::Other);
}
}