Skip to content
This repository has been archived by the owner on Nov 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #4 from tcharding/06-06-miniscript
Browse files Browse the repository at this point in the history
Add support for rust-miniscript
  • Loading branch information
tcharding authored Jun 12, 2024
2 parents 139109e + f319abf commit 08e8900
Show file tree
Hide file tree
Showing 45 changed files with 644 additions and 56 deletions.
36 changes: 18 additions & 18 deletions bitcoind/src/client.rs → bitcoind/src/client_versions.rs
Original file line number Diff line number Diff line change
@@ -1,73 +1,73 @@
// All features uses 26_0
#[cfg(feature = "26_0")]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v26::Client, json::v26 as json};
pub use bitcoind_json_rpc_client::{client_sync::v26::{Client, AddressType}, json::v26 as json};

#[cfg(all(feature = "25_2", not(feature = "26_0")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v25::Client, json::v25 as json};
pub use bitcoind_json_rpc_client::{client_sync::v25::{Client, AddressType}, json::v25 as json};

#[cfg(all(feature = "25_1", not(feature = "25_2")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v25::Client, json::v25 as json};
pub use bitcoind_json_rpc_client::{client_sync::v25::{Client, AddressType}, json::v25 as json};

#[cfg(all(feature = "25_0", not(feature = "25_1")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v25::Client, json::v25 as json};
pub use bitcoind_json_rpc_client::{client_sync::v25::{Client, AddressType}, json::v25 as json};

#[cfg(all(feature = "24_2", not(feature = "25_0")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v24::Client, json::v24 as json};
pub use bitcoind_json_rpc_client::{client_sync::v24::{Client, AddressType}, json::v24 as json};

#[cfg(all(feature = "24_1", not(feature = "24_2")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v24::Client, json::v24 as json};
pub use bitcoind_json_rpc_client::{client_sync::v24::{Client, AddressType}, json::v24 as json};

#[cfg(all(feature = "24_0_1", not(feature = "24_1")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v24::Client, json::v24 as json};
pub use bitcoind_json_rpc_client::{client_sync::v24::{Client, AddressType}, json::v24 as json};

#[cfg(all(feature = "23_2", not(feature = "24_0_1")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v23::Client, json::v23 as json};
pub use bitcoind_json_rpc_client::{client_sync::v23::{Client, AddressType}, json::v23 as json};

#[cfg(all(feature = "23_1", not(feature = "23_2")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v23::Client, json::v23 as json};
pub use bitcoind_json_rpc_client::{client_sync::v23::{Client, AddressType}, json::v23 as json};

#[cfg(all(feature = "23_0", not(feature = "23_1")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v23::Client, json::v23 as json};
pub use bitcoind_json_rpc_client::{client_sync::v23::{Client, AddressType}, json::v23 as json};

#[cfg(all(feature = "22_1", not(feature = "23_0")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v22::Client, json::v22 as json};
pub use bitcoind_json_rpc_client::{client_sync::v22::{Client, AddressType}, json::v22 as json};

#[cfg(all(feature = "22_0", not(feature = "22_1")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v22::Client, json::v22 as json};
pub use bitcoind_json_rpc_client::{client_sync::v22::{Client, AddressType}, json::v22 as json};

#[cfg(all(feature = "0_21_2", not(feature = "22_0")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v21::Client, json::v21 as json};
pub use bitcoind_json_rpc_client::{client_sync::v21::{Client, AddressType}, json::v21 as json};

#[cfg(all(feature = "0_20_2", not(feature = "0_21_2")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v20::Client, json::v20 as json};
pub use bitcoind_json_rpc_client::{client_sync::v20::{Client, AddressType}, json::v20 as json};

#[cfg(all(feature = "0_19_1", not(feature = "0_20_2")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v19::Client, json::v19 as json};
pub use bitcoind_json_rpc_client::{client_sync::v19::{Client, AddressType}, json::v19 as json};

#[cfg(all(feature = "0_18_1", not(feature = "0_19_1")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v18::Client, json::v18 as json};
pub use bitcoind_json_rpc_client::{client_sync::v18::{Client, AddressType}, json::v18 as json};

#[cfg(all(feature = "0_17_2", not(feature = "0_18_1")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v17::Client, json::v17 as json};
pub use bitcoind_json_rpc_client::{client_sync::v17::{Client, AddressType}, json::v17 as json};

// To make --no-default-features work we have to enable some feature, use most recent version same as for default.
#[cfg(all(not(feature = "26_0"), not(feature = "25_2"), not(feature = "25_1"), not(feature = "25_0"), not(feature = "24_2"),not(feadure = "24_1"), not(feature = "24_0_1"), not(feature = "23_2"), not(feature = "23_1"), not(feature = "23_0"), not(feature = "22_1"), not(feature = "22_0"), not(feature = "0_21_2"), not(feature = "0_20_2"), not(feature = "0_19_1"), not(feature = "0_18_1"), not(feature = "0_17_2")))]
#[allow(unused_imports)] // Not all users need the json types.
pub use bitcoind_json_rpc_client::{client_sync::v26::Client, json::v26 as json};
pub use bitcoind_json_rpc_client::{client_sync::v26::{Client, AddressType}, json::v26 as json};
14 changes: 8 additions & 6 deletions bitcoind/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![cfg_attr(feature = "doc", cfg_attr(all(), doc = include_str!("../README.md")))]

pub extern crate bitcoind_json_rpc_client as client;

#[rustfmt::skip]
mod client;
mod client_versions;
mod versions;

use std::ffi::OsStr;
Expand All @@ -18,9 +20,11 @@ use log::{debug, error, warn};
use tempfile::TempDir;
pub use {anyhow, tempfile, which};

use self::client::Client;
#[allow(unused_imports)] // for --no-default-features
use self::versions::VERSION;
#[rustfmt::skip] // Keep pubic re-exports separate.
pub use self::{
client_versions::{json, Client, AddressType},
versions::VERSION,
};

#[derive(Debug)]
/// Struct representing the bitcoind process with related information
Expand Down Expand Up @@ -687,8 +691,6 @@ mod test {
fn test_multi_wallet() {
use bitcoind_json_rpc_client::bitcoin::Amount;

use crate::client::json;

let exe = init();
let bitcoind = BitcoinD::new(exe).unwrap();
let alice = bitcoind.create_wallet("alice").unwrap();
Expand Down
27 changes: 27 additions & 0 deletions client/src/client_sync/v17/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ pub mod blockchain;
pub mod control;
pub mod generating;
pub mod network;
pub mod raw_transactions;
pub mod wallet;

use bitcoin::address::{Address, NetworkChecked};
use bitcoin::{Amount, Block, BlockHash, Txid};
use serde::{Deserialize, Serialize};

use crate::client_sync::{handle_defaults, into_json};
use crate::json::v17::*;
Expand All @@ -34,10 +36,35 @@ crate::impl_client_v17__generatetoaddress!();
crate::impl_client_v17__getnetworkinfo!();
crate::impl_client_check_expected_server_version!({ [170200] });

// == Rawtransactions ==
crate::impl_client_v17__sendrawtransaction!();

// == Wallet ==
crate::impl_client_v17__createwallet!();
crate::impl_client_v17__unloadwallet!();
crate::impl_client_v17__loadwallet!();
crate::impl_client_v17__getnewaddress!();
crate::impl_client_v17__getbalance!();
crate::impl_client_v17__sendtoaddress!();
crate::impl_client_v17__gettransaction!();

/// Argument to the `Client::get_new_address_with_type` function.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub enum AddressType {
Legacy,
P2ShSegwit,
Bech32,
}

impl fmt::Display for AddressType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use AddressType::*;

let s = match *self {
Legacy => "legacy",
P2ShSegwit => "p2sh-segwit",
Bech32 => "bech32",
};
fmt::Display::fmt(s, f)
}
}
25 changes: 25 additions & 0 deletions client/src/client_sync/v17/raw_transactions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: CC0-1.0

//! Macros for implementing JSON-RPC methods on a client.
//!
//! Specifically this is methods found under the `== Rawtransactions ==` section of the
//! API docs of `bitcoind v0.17.1`.
//!
//! All macros require `Client` to be in scope.
//!
//! See or use the `define_jsonrpc_minreq_client!` macro to define a `Client`.
/// Implements bitcoind JSON-RPC API method `sendrawtransaction`
#[macro_export]
macro_rules! impl_client_v17__sendrawtransaction {
() => {
impl Client {
pub fn send_raw_transaction(
&self,
tx: &bitcoin::Transaction,
) -> Result<SendRawTransaction> {
self.call("sendrawtransaction", &[into_json(tx)?])
}
}
};
}
27 changes: 27 additions & 0 deletions client/src/client_sync/v17/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,24 @@ macro_rules! impl_client_v17__getnewaddress {
Ok(address)
}

/// Gets a new address from `bitcoind` and parses it assuming its correct.
pub fn new_address_with_type(&self, ty: AddressType) -> Result<bitcoin::Address> {
use core::str::FromStr;

let json = self.get_new_address_with_type(ty)?;
let address = bitcoin::Address::from_str(&json.0)
.expect("assume the address is valid")
.assume_checked(); // Assume bitcoind will return an invalid address for the network its on.
Ok(address)
}

pub fn get_new_address(&self) -> Result<GetNewAddress> {
self.call("getnewaddress", &[])
}

pub fn get_new_address_with_type(&self, ty: AddressType) -> Result<GetNewAddress> {
self.call("getnewaddress", &["".into(), into_json(ty)?])
}
}
};
}
Expand All @@ -94,3 +109,15 @@ macro_rules! impl_client_v17__sendtoaddress {
}
};
}

/// Implements bitcoind JSON-RPC API method `gettransaction`
#[macro_export]
macro_rules! impl_client_v17__gettransaction {
() => {
impl Client {
pub fn get_transaction(&self, txid: Txid) -> Result<GetTransaction> {
self.call("gettransaction", &[into_json(txid)?])
}
}
};
}
6 changes: 6 additions & 0 deletions client/src/client_sync/v18.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,16 @@ crate::impl_client_v17__generatetoaddress!();
crate::impl_client_v17__getnetworkinfo!();
crate::impl_client_check_expected_server_version!({ [180100] });

// == Rawtransactions ==
crate::impl_client_v17__sendrawtransaction!();

// == Wallet ==
crate::impl_client_v17__createwallet!();
crate::impl_client_v17__unloadwallet!();
crate::impl_client_v17__loadwallet!();
crate::impl_client_v17__getnewaddress!();
crate::impl_client_v17__getbalance!();
crate::impl_client_v17__sendtoaddress!();
crate::impl_client_v17__gettransaction!();

pub use crate::client_sync::v17::AddressType;
6 changes: 6 additions & 0 deletions client/src/client_sync/v19/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ crate::impl_client_v17__generatetoaddress!();
crate::impl_client_v17__getnetworkinfo!();
crate::impl_client_check_expected_server_version!({ [190100] });

// == Rawtransactions ==
crate::impl_client_v17__sendrawtransaction!();

// == Wallet ==
crate::impl_client_v17__createwallet!();
crate::impl_client_v17__unloadwallet!();
Expand All @@ -38,3 +41,6 @@ crate::impl_client_v17__getnewaddress!();
crate::impl_client_v17__getbalance!();
crate::impl_client_v19__getbalances!();
crate::impl_client_v17__sendtoaddress!();
crate::impl_client_v17__gettransaction!();

pub use crate::client_sync::v17::AddressType;
6 changes: 6 additions & 0 deletions client/src/client_sync/v20.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ crate::impl_client_v17__generatetoaddress!();
crate::impl_client_v17__getnetworkinfo!();
crate::impl_client_check_expected_server_version!({ [200200] });

// == Rawtransactions ==
crate::impl_client_v17__sendrawtransaction!();

// == Wallet ==
crate::impl_client_v17__createwallet!();
crate::impl_client_v17__unloadwallet!();
Expand All @@ -36,3 +39,6 @@ crate::impl_client_v17__getnewaddress!();
crate::impl_client_v17__getbalance!();
crate::impl_client_v19__getbalances!();
crate::impl_client_v17__sendtoaddress!();
crate::impl_client_v17__gettransaction!();

pub use crate::client_sync::v17::AddressType;
14 changes: 10 additions & 4 deletions client/src/client_sync/v21.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@ crate::impl_client_v17__getbestblockhash!();
crate::impl_client_v17__getblock!();
crate::impl_client_v17__gettxout!();

// == Network ==
crate::impl_client_v17__getnetworkinfo!();
crate::impl_client_check_expected_server_version!({ [210200] });

// == Control ==
crate::impl_client_v17__stop!();

// == Generating ==
crate::impl_client_v17__generatetoaddress!();

// == Network ==
crate::impl_client_v17__getnetworkinfo!();
crate::impl_client_check_expected_server_version!({ [210200] });

// == Rawtransactions ==
crate::impl_client_v17__sendrawtransaction!();

// == Wallet ==
crate::impl_client_v17__createwallet!();
crate::impl_client_v17__unloadwallet!();
Expand All @@ -36,3 +39,6 @@ crate::impl_client_v17__getnewaddress!();
crate::impl_client_v17__getbalance!();
crate::impl_client_v19__getbalances!();
crate::impl_client_v17__sendtoaddress!();
crate::impl_client_v17__gettransaction!();

pub use crate::client_sync::v17::AddressType;
6 changes: 6 additions & 0 deletions client/src/client_sync/v22/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ crate::impl_client_v17__generatetoaddress!();
crate::impl_client_v17__getnetworkinfo!();
crate::impl_client_check_expected_server_version!({ [220000, 220100] });

// == Rawtransactions ==
crate::impl_client_v17__sendrawtransaction!();

// == Wallet ==
crate::impl_client_v17__createwallet!();
crate::impl_client_v22__unloadwallet!();
Expand All @@ -38,3 +41,6 @@ crate::impl_client_v17__getbalance!();
crate::impl_client_v19__getbalances!();
crate::impl_client_v17__getnewaddress!();
crate::impl_client_v17__sendtoaddress!();
crate::impl_client_v17__gettransaction!();

pub use crate::client_sync::v17::AddressType;
28 changes: 28 additions & 0 deletions client/src/client_sync/v23.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use bitcoin::address::{Address, NetworkChecked};
use bitcoin::{Amount, Block, BlockHash, Txid};
use serde::{Deserialize, Serialize};

use crate::client_sync::{handle_defaults, into_json};
use crate::json::v23::*;
Expand All @@ -28,6 +29,9 @@ crate::impl_client_v17__generatetoaddress!();
crate::impl_client_v17__getnetworkinfo!();
crate::impl_client_check_expected_server_version!({ [230000, 230100, 230200] });

// == Rawtransactions ==
crate::impl_client_v17__sendrawtransaction!();

// == Wallet ==
crate::impl_client_v17__createwallet!();
crate::impl_client_v22__unloadwallet!();
Expand All @@ -36,3 +40,27 @@ crate::impl_client_v17__getbalance!();
crate::impl_client_v19__getbalances!();
crate::impl_client_v17__getnewaddress!();
crate::impl_client_v17__sendtoaddress!();
crate::impl_client_v17__gettransaction!();

/// Argument to the `Client::get_new_address_with_type` function.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
pub enum AddressType {
Legacy,
P2ShSegwit,
Bech32,
Bech32m,
}

impl fmt::Display for AddressType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use AddressType::*;

let s = match *self {
Legacy => "legacy",
P2ShSegwit => "p2sh-segwit",
Bech32 => "bech32",
Bech32m => "bech32m",
};
fmt::Display::fmt(s, f)
}
}
Loading

0 comments on commit 08e8900

Please sign in to comment.