Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
686 changes: 671 additions & 15 deletions Cargo.lock

Large diffs are not rendered by default.

18 changes: 12 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ serde_json = "1.0"
thiserror = "2.0.11"
tokio = { version = "1", features = ["full"] }
cli-table = "0.5.0"
tracing = "0.1.41"
tracing-subscriber = "0.3.20"

# Optional dependencies
bdk_bitcoind_rpc = { version = "0.21.0", features = ["std"], optional = true }
Expand All @@ -29,8 +31,9 @@ bdk_esplora = { version = "0.22.1", features = ["async-https", "tokio"], optiona
bdk_kyoto = { version = "0.15.1", optional = true }
bdk_redb = { version = "0.1.0", optional = true }
shlex = { version = "1.3.0", optional = true }
tracing = "0.1.41"
tracing-subscriber = "0.3.20"
payjoin = { version = "1.0.0-rc.0", features = ["v1", "v2", "io", "_test-utils"], optional = true}
reqwest = { version = "0.12.23", default-features = false, optional = true }
url = { version = "2.5.4", optional = true }

[features]
default = ["repl", "sqlite"]
Expand All @@ -43,10 +46,13 @@ sqlite = ["bdk_wallet/rusqlite"]
redb = ["bdk_redb"]

# Available blockchain client options
cbf = ["bdk_kyoto"]
electrum = ["bdk_electrum"]
esplora = ["bdk_esplora"]
rpc = ["bdk_bitcoind_rpc"]
cbf = ["bdk_kyoto", "_payjoin-dependencies"]
electrum = ["bdk_electrum", "_payjoin-dependencies"]
esplora = ["bdk_esplora", "_payjoin-dependencies"]
rpc = ["bdk_bitcoind_rpc", "_payjoin-dependencies"]

# Internal features
_payjoin-dependencies = ["payjoin", "reqwest", "url"]

# Use this to consensus verify transactions at sync time
verify = []
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ And yes, it can do Taproot!!
This crate can be used for the following purposes:
- Instantly create a miniscript based wallet and connect to your backend of choice (Electrum, Esplora, Core RPC, Kyoto etc) and quickly play around with your own complex bitcoin scripting workflow. With one or many wallets, connected with one or many backends.
- The `tests/integration.rs` module is used to document high level complex workflows between BDK and different Bitcoin infrastructure systems, like Core, Electrum and Lightning(soon TM).
- Receive and send Async Payjoins. Note that even though Async Payjoin as a protocol allows the receiver and sender to go offline during the payjoin, the BDK CLI implementation currently does not support persisting.
- (Planned) Expose the basic command handler via `wasm` to integrate `bdk-cli` functionality natively into the web platform. See also the [playground](https://bitcoindevkit.org/bdk-cli/playground/) page.

If you are considering using 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 what's possible with descriptors, miniscript, and BDK APIs. For more information on BDK refer to the [website](https://bitcoindevkit.org/) and the [rust docs](https://docs.rs/bdk_wallet/1.0.0/bdk_wallet/index.html)
Expand Down
35 changes: 35 additions & 0 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,41 @@ pub enum OnlineWalletSubCommand {
)]
tx: Option<String>,
},
// Generates a Payjoin receive URI and processes the sender's Payjoin proposal.
ReceivePayjoin {
/// Amount to be received in sats.
#[arg(env = "PAYJOIN_AMOUNT", long = "amount", required = true)]
amount: u64,
/// Payjoin directory which will be used to store the PSBTs which are pending action
/// from one of the parties.
#[arg(env = "PAYJOIN_DIRECTORY", long = "directory", required = true)]
directory: String,
/// URL of the Payjoin OHTTP relay. Can be repeated multiple times to attempt the
/// operation with multiple relays for redundancy.
#[arg(env = "PAYJOIN_OHTTP_RELAY", long = "ohttp_relay", required = true)]
ohttp_relay: Vec<String>,
/// Maximum effective fee rate the receiver is willing to pay for their own input/output contributions.
#[arg(env = "PAYJOIN_RECEIVER_MAX_FEE_RATE", long = "max_fee_rate")]
max_fee_rate: Option<u64>,
},
/// Sends an original PSBT to a BIP 21 URI and broadcasts the returned Payjoin PSBT.
SendPayjoin {
/// BIP 21 URI for the Payjoin.
#[arg(env = "PAYJOIN_URI", long = "uri", required = true)]
uri: String,
/// URL of the Payjoin OHTTP relay. Can be repeated multiple times to attempt the
/// operation with multiple relays for redundancy.
#[arg(env = "PAYJOIN_OHTTP_RELAY", long = "ohttp_relay", required = true)]
ohttp_relay: Vec<String>,
/// Fee rate to use in sat/vbyte.
#[arg(
env = "PAYJOIN_SENDER_FEE_RATE",
short = 'f',
long = "fee_rate",
required = true
)]
fee_rate: u64,
},
}

/// Subcommands for Key operations.
Expand Down
9 changes: 9 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,15 @@ pub enum BDKCliError {
#[cfg(feature = "cbf")]
#[error("BDK-Kyoto update error: {0}")]
KyotoUpdateError(#[from] bdk_kyoto::UpdateError),

#[cfg(any(
feature = "electrum",
feature = "esplora",
feature = "rpc",
feature = "cbf",
))]
#[error("Reqwest error: {0}")]
ReqwestError(#[from] reqwest::Error),
}

impl From<ExtractTxError> for BDKCliError {
Expand Down
Loading