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.1", 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"]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the url dependency was removed from the public payjoin API for 1.0.0-rc, so it should no longer be required.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am changing the function signatures to use payjoin::IntoUrl, but going to hold on to the Url dependency to parse the URLs before passing them to the Payjoin process functions. Let me know if there is an alternative approach 👍🏻


# 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>,
Comment on lines +442 to +445

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: also plural here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as the above.

The reason I kept this singular here is that it works better from a CLI options perspective:

send_payjoin --fee_rate 1 --ohttp_relay "https://pj.bobspacebkk.com" --ohttp_relay "https://ohttp.achow101.com" --uri "..."

Having the options be --ohttp_relays would not be accurate. And to my knowledge there isn't another way to past that list in the command line.

/// 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>,
Comment on lines +455 to +458

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: plural ohttp_relays

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I kept this singular here is that it works better from a CLI options perspective:

send_payjoin --fee_rate 1 --ohttp_relay "https://pj.bobspacebkk.com" --ohttp_relay "https://ohttp.achow101.com" --uri "..."

Having the options be --ohttp_relays would not be accurate. And to my knowledge there isn't another way to past that list in the command line.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, I guess I was thinking about it from the perspective of a config file but I realize now this only supports command line argument parsing so it makes sense.

/// 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
Loading