Skip to content

Commit

Permalink
Update crate documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
rajarshimaitra committed Jun 27, 2022
1 parent 4b61e64 commit dd98a34
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 32 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ default = ["repl", "sqlite-db"]
# To use the app in a REPL mode
repl = ["regex", "rustyline", "fd-lock"]

# Avaialable dataabse options
# Avaialable databse options
key-value-db = ["bdk/key-value-db"]
sqlite-db = ["bdk/sqlite"]

Expand Down
56 changes: 50 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,56 @@
# bdk-cli lib and example bin tool
<div align="center">
<h1>BDK-CLI</h1>

<img src="https://github.com/bitcoindevkit/bdk/raw/master/static/bdk.png" width="220" />

<p>
<strong>A Command-line Bitcoin Wallet App in pure rust using BDK</strong>
</p>

<p>
<a href="https://crates.io/crates/bdk-cli"><img alt="Crate Info" src="https://img.shields.io/crates/v/bdk-cli.svg"/></a>
<a href="https://github.com/bitcoindevkit/bdk-cli/blob/master/LICENSE"><img alt="MIT or Apache-2.0 Licensed" src="https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg"/></a>
<a href="https://github.com/bitcoindevkit/bdk-cli/actions?query=workflow%3ACI"><img alt="CI Status" src="https://github.com/bitcoindevkit/bdk-cli/workflows/CI/badge.svg"></a>
<a href="https://codecov.io/gh/bitcoindevkit/bdk-cli"><img src="https://codecov.io/gh/bitcoindevkit/bdk-cli/branch/master/graph/badge.svg"/></a>
<a href="https://docs.rs/bdk-cli"><img alt="API Docs" src="https://img.shields.io/badge/docs.rs-bdk_cli-green"/></a>
<a href="https://blog.rust-lang.org/2020/08/27/Rust-1.56.0.html"><img alt="Rustc Version 1.56+" src="https://img.shields.io/badge/rustc-1.56%2B-lightgrey.svg"/></a>
<a href="https://discord.gg/d7NkDKm"><img alt="Chat on Discord" src="https://img.shields.io/discord/753336465005608961?logo=discord"></a>
</p>

<h4>
<a href="https://bitcoindevkit.org">Project Homepage</a>
<span> | </span>
<a href="https://docs.rs/bdk-cli">Documentation</a>
</h4>
</div>

![CI](https://github.com/bitcoindevkit/bdk-cli/workflows/CI/badge.svg)
![Code Coverage](https://github.com/bitcoindevkit/bdk-cli/workflows/Code%20Coverage/badge.svg)

## About

This project provides a command line interface (cli) Bitcoin wallet library and [`REPL`](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)
wallet tool based on the [bdk](https://github.com/bitcoindevkit/bdk) library.
This project provides a command-line Bitcoin wallet application using the latest [BDK APIs](https://docs.rs/bdk/0.19.0/bdk/wallet/struct.Wallet.html). This is used mostly as an high level integration testing framework, by the BDK team, using the [tests](/tests/integration.rs) modules.

But if you are planning to use BDK in your own wallet project, bdk-cli is a nice playground to get started with. It allows easy testnet and regtest wallet operations, to try out whats possible with descriptors, miniscripts, and BDK APIs. For more information on BDK refer the [website](https://bitcoindevkit.org/), and the [rust docs](https://docs.rs/bdk/latest/bdk/index.html)

bdk-cli can be compiled in various different ways to suit the experimental needs.
- Database Options
- `key-value-db` : Sets the wallet database a `sled` db.
- `sqlite-db` : Sets the wallet database as `sqlite3` db.
- Blockchain Options
- `rpc` : Connects the wallet to bitcoin core via RPC.
- `electrum` : Connects the wallet to an electrum server.
- `compact_filters` : Deploy a BIP157 node to get blockchain data from bitcoin p2p network.
- `esplora-ureq/reqwest` : Connects the wallet to a esplora server sync/asynchronously.
- Extra Utility Tools
- `repl` : use bdk-cli as a [REPL](https://codewith.mu/en/tutorials/1.0/repl) shell (useful for quick hand testing wallet operations).
- `compiler` : opens up bdk-cli policy compiler commands.
- `verify` : uses `bitcoinconsensus` to verify transactions at every `sync` call of the wallet.
- `reserves` : opens up bdk-cli **Proof of Reserves** operation commands using the [bdk-reserves plugin](https://github.com/weareseba/bdk-reserves). (requires `electrum`)
- Automated Node Backend
- `regtest-bitcoin` : Auto deploys a regtest bitcoin node, connects the wallet, and exposes core rpc commands via `bdk-cli node` subsommands.
- `regtest-electrum` : Auto deploys a `electrsd` connected to a `bitcoind` and an wallet connectded to `electrsd`. `bdk-cli node` subcommand still calls the `bitcoind` RPC.

The `deafult` feature sets are `repl` and `sqlite-db`. With `default` features, `bdk-cli` works as an **air-gapped** wallet, and can do everything that doesn't require a network connection.


## Install bdk-cli
### From source
Expand All @@ -20,7 +64,7 @@ bdk-cli help # to verify it worked

If no blockchain client feature is enabled online wallet commands `sync` and `broadcast` will be
disabled. To enable these commands a blockchain client features such as `electrum` or another
blockchain backend feature must be enabled. Below is an example of how run the `bdk-cli` bin with
blockchain client feature must be enabled. Below is an example of how run the `bdk-cli` bin with
the `esplora-ureq` blockchain client feature.

```shell
Expand Down
23 changes: 12 additions & 11 deletions src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
// You may not use this file except in accordance with one or both of these
// licenses.

//! The Backend
//! Backend to hold the running background nodes
//!
//! This module defines the Backend struct and associated operations
//! This module defines the [Backend] enum and associated operations.
//! This Backends are used in `regtest-*` features to spawn a bitcoin blockchain
//! of selected type automatically, and connects the bdk-cli wallet to it.
//!
Expand All @@ -26,26 +26,27 @@ use {
};

#[allow(dead_code)]
// Different Backend types activated with `regtest-*` mode.
// If `regtest-*` feature not activated, then default is `None`.
//
// Box the backend to reduce size of Enum in memory.
/// Different Backend types activated with `regtest-*` mode.
/// If `regtest-*` feature not activated, then default is `None`.
///
/// Box the backend to reduce size of Enum in memory.
pub enum Backend {
/// Used when no regtest-* features are enabled
None,
#[cfg(feature = "regtest-bitcoin")]
// A bitcoin core backend. Wallet connected to it via RPC.
/// A bitcoin core backend. Wallet connected to it via RPC.
Bitcoin {
bitcoind: Box<electrsd::bitcoind::BitcoinD>,
},
#[cfg(feature = "regtest-electrum")]
// An Electrum backend, with an underlying bitcoin core
// Wallet connected to it, via the electrum url
/// An Electrum backend, with an underlying bitcoin core
/// Wallet connected to it, via the electrum url
Electrum {
bitcoind: Box<electrsd::bitcoind::BitcoinD>,
electrsd: Box<electrsd::ElectrsD>,
},
// An Esplora backend with underlying bitcoin core.
// Wallet connected to it, via the esplora url
/// An Esplora backend with underlying bitcoin core.
/// Wallet connected to it, via the esplora url
#[cfg(any(feature = "regtest-esplora-ureq", feature = "regtest-esplora-reqwest"))]
Esplora {
bitcoind: Box<electrsd::bitcoind::BitcoinD>,
Expand Down
24 changes: 19 additions & 5 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@

//! bdk-cli Command structure
//!
//! This module defines all the bdk-cli commands using [structopt]
//! This module defines all the bdk-cli commands structure.
//! All option args are defined in the structs below.
//! All subcommands are defined in the below enums.
#![allow(clippy::large_enum_variant)]

Expand Down Expand Up @@ -37,7 +39,7 @@ use crate::utils::{parse_outpoint, parse_recipient};
/// But this is not just any toy.
/// bdk-cli is also a fully functioning Bitcoin wallet with taproot support!
///
/// For more information checkout https://bitcoindevkit.org/
/// For more information checkout <https://bitcoindevkit.org/>
#[structopt(version = option_env ! ("CARGO_PKG_VERSION").unwrap_or("unknown"),
author = option_env ! ("CARGO_PKG_AUTHORS").unwrap_or(""))]
pub struct CliOpts {
Expand All @@ -53,12 +55,12 @@ pub struct CliOpts {
/// Default value : "~/.bdk-bitcoin
#[structopt(name = "DATADIR", short = "d", long = "datadir")]
pub datadir: Option<std::path::PathBuf>,
/// Top level cli sub-command
/// Top level cli sub-commands
#[structopt(subcommand)]
pub subcommand: CliSubCommand,
}

/// CLI sub-commands
/// Top level cli sub-commands
#[derive(Debug, StructOpt, Clone, PartialEq)]
#[structopt(rename_all = "snake")]
pub enum CliSubCommand {
Expand All @@ -68,7 +70,7 @@ pub enum CliSubCommand {
/// launched automatically with the `regtest-*` feature sets. The commands issues
/// bitcoin-cli rpc calls on the demon, in the background.
///
/// Feel free to open feature-request in https://github.com/bitcoindevkit/bdk-cli
/// Feel free to open feature-request in <https://github.com/bitcoindevkit/bdk-cli>
/// if you need extra rpc calls not covered in the command list.
#[cfg(feature = "regtest-node")]
#[structopt(long_about = "Regtest Node mode")]
Expand Down Expand Up @@ -141,6 +143,7 @@ pub enum CliSubCommand {
},
}

/// Backend Node operation subcommands
#[derive(Debug, StructOpt, Clone, PartialEq)]
#[structopt(rename_all = "lower")]
#[cfg(any(feature = "regtest-node"))]
Expand All @@ -157,6 +160,7 @@ pub enum NodeSubCommand {
SendToAddress { address: String, amount: u64 },
}

/// Wallet operation subcommands
#[derive(Debug, StructOpt, Clone, PartialEq)]
pub enum WalletSubCommand {
#[cfg(any(
Expand All @@ -171,6 +175,7 @@ pub enum WalletSubCommand {
OfflineWalletSubCommand(OfflineWalletSubCommand),
}

/// Config options wallet operations can take
#[derive(Debug, StructOpt, Clone, PartialEq)]
pub struct WalletOpts {
/// Selects the wallet to use
Expand Down Expand Up @@ -202,6 +207,7 @@ pub struct WalletOpts {
pub proxy_opts: ProxyOpts,
}

/// Options to configure SOCKS5 Proxy connection to backend
#[cfg(any(feature = "compact_filters", feature = "electrum", feature = "esplora"))]
#[derive(Debug, StructOpt, Clone, PartialEq)]
pub struct ProxyOpts {
Expand All @@ -223,6 +229,7 @@ pub struct ProxyOpts {
pub retries: u8,
}

/// Options to configure BIP157 Compact Filter backend
#[cfg(feature = "compact_filters")]
#[derive(Debug, StructOpt, Clone, PartialEq)]
pub struct CompactFilterOpts {
Expand All @@ -249,6 +256,7 @@ pub struct CompactFilterOpts {
pub skip_blocks: usize,
}

/// Options to configure bitcoin core rpc backend
#[cfg(feature = "rpc")]
#[derive(Debug, StructOpt, Clone, PartialEq)]
pub struct RpcOpts {
Expand Down Expand Up @@ -280,6 +288,7 @@ pub struct RpcOpts {
pub skip_blocks: Option<u32>,
}

/// Options to configure electrum backend
#[cfg(feature = "electrum")]
#[derive(Debug, StructOpt, Clone, PartialEq)]
pub struct ElectrumOpts {
Expand All @@ -305,6 +314,7 @@ pub struct ElectrumOpts {
pub stop_gap: usize,
}

/// Options to configure Esplora backend
#[cfg(feature = "esplora")]
#[derive(Debug, StructOpt, Clone, PartialEq)]
pub struct EsploraOpts {
Expand Down Expand Up @@ -335,6 +345,7 @@ pub struct EsploraOpts {
pub conc: u8,
}

/// Wallet subcommands that can be issued without a blockchain backend
#[derive(Debug, StructOpt, Clone, PartialEq)]
#[structopt(rename_all = "snake")]
pub enum OfflineWalletSubCommand {
Expand Down Expand Up @@ -439,6 +450,7 @@ pub enum OfflineWalletSubCommand {
},
}

/// Wallet subcommands that needs a blockchain backend
#[derive(Debug, StructOpt, Clone, PartialEq)]
#[structopt(rename_all = "snake")]
#[cfg(any(
Expand Down Expand Up @@ -491,6 +503,7 @@ pub enum OnlineWalletSubCommand {
},
}

/// Subcommands for Key operations
#[derive(Debug, StructOpt, Clone, PartialEq)]
pub enum KeySubCommand {
/// Generates new random seed mnemonic phrase and corresponding master extended key
Expand Down Expand Up @@ -528,6 +541,7 @@ pub enum KeySubCommand {
},
}

/// Subcommands available in REPL mode
#[cfg(feature = "repl")]
#[derive(Debug, StructOpt, Clone, PartialEq)]
pub enum ReplSubCommand {
Expand Down
7 changes: 4 additions & 3 deletions src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ where
}
}

/// Execute a key sub-command
/// Handle a key sub-command
///
/// Key sub-commands are described in [`KeySubCommand`].
pub(crate) fn handle_key_subcommand(
Expand Down Expand Up @@ -449,7 +449,7 @@ pub(crate) fn handle_key_subcommand(
}
}

/// Execute the miniscript compiler sub-command
/// Handle the miniscript compiler sub-command
///
/// Compiler options are described in [`CliSubCommand::Compile`].
#[cfg(feature = "compiler")]
Expand Down Expand Up @@ -477,7 +477,7 @@ pub(crate) fn handle_compile_subcommand(
Ok(json!({"descriptor": descriptor.to_string()}))
}

/// Proof of reserves verification sub-command
/// Handle Proof of Reserves commands
///
/// Proof of reserves options are described in [`CliSubCommand::ExternalReserves`].
#[cfg(all(feature = "reserves", feature = "electrum"))]
Expand Down Expand Up @@ -518,6 +518,7 @@ pub(crate) fn handle_ext_reserves_subcommand(
Ok(json!({ "spendable": spendable }))
}

/// The mother of all handlers
pub(crate) fn handle_command(cli_opts: CliOpts) -> Result<String, Error> {
let network = cli_opts.network;
let home_dir = prepare_home_dir(cli_opts.datadir)?;
Expand Down
6 changes: 3 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
// You may not use this file except in accordance with one or both of these
// licenses.

//! BDK CLI APP
//!
//! This module describes the app's main() function
#![doc = include_str!("../README.md")]
#![doc(html_logo_url = "https://github.com/bitcoindevkit/bdk/raw/master/static/bdk.png")]
#![warn(missing_docs)]

mod backend;
mod commands;
Expand Down
8 changes: 5 additions & 3 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ pub(crate) fn parse_proxy_auth(s: &str) -> Result<(String, String), String> {
Ok((user, passwd))
}

/// Fetch all the utxos, for a given address
#[cfg(all(feature = "reserves", feature = "electrum"))]
pub fn get_outpoints_for_address(
address: Address,
Expand Down Expand Up @@ -213,9 +214,9 @@ fn prepare_bc_dir(wallet_name: &str, home_path: &Path) -> Result<PathBuf, Error>
Ok(bc_dir)
}

// We create only a global single node directory. Because multiple
// wallets can access the same node datadir, and they will have separate
// wallet names in `<home_path>/bitcoind/regtest/wallets`.
/// We create only a global single node directory. Because multiple
/// wallets can access the same node datadir, and they will have separate
/// wallet names in `<home_path>/bitcoind/regtest/wallets`.
#[cfg(feature = "regtest-node")]
pub(crate) fn prepare_bitcoind_datadir(home_path: &Path) -> Result<PathBuf, Error> {
let mut dir = home_path.to_owned();
Expand Down Expand Up @@ -275,6 +276,7 @@ pub(crate) fn open_database(
Ok(database)
}

/// Create a new backend node at given datadir
#[allow(dead_code)]
pub(crate) fn new_backend(_datadir: &Path) -> Result<Backend, Error> {
#[cfg(feature = "regtest-node")]
Expand Down

0 comments on commit dd98a34

Please sign in to comment.