Skip to content

Commit 0112c92

Browse files
committed
feat: add payjoin send support
temp: move the send_payjoin out of the commit
1 parent f62287a commit 0112c92

File tree

8 files changed

+1122
-22
lines changed

8 files changed

+1122
-22
lines changed

Cargo.lock

Lines changed: 671 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ serde_json = "1.0"
2121
thiserror = "2.0.11"
2222
tokio = { version = "1", features = ["full"] }
2323
cli-table = "0.5.0"
24+
tracing = "0.1.41"
25+
tracing-subscriber = "0.3.20"
2426

2527
# Optional dependencies
2628
bdk_bitcoind_rpc = { version = "0.21.0", features = ["std"], optional = true }
@@ -29,8 +31,9 @@ bdk_esplora = { version = "0.22.1", features = ["async-https", "tokio"], optiona
2931
bdk_kyoto = { version = "0.15.1", optional = true }
3032
bdk_redb = { version = "0.1.0", optional = true }
3133
shlex = { version = "1.3.0", optional = true }
32-
tracing = "0.1.41"
33-
tracing-subscriber = "0.3.20"
34+
payjoin = { version = "1.0.0-rc.1", features = ["v1", "v2", "io", "_test-utils"], optional = true}
35+
reqwest = { version = "0.12.23", default-features = false, optional = true }
36+
url = { version = "2.5.4", optional = true }
3437

3538
[features]
3639
default = ["repl", "sqlite"]
@@ -43,10 +46,13 @@ sqlite = ["bdk_wallet/rusqlite"]
4346
redb = ["bdk_redb"]
4447

4548
# Available blockchain client options
46-
cbf = ["bdk_kyoto"]
47-
electrum = ["bdk_electrum"]
48-
esplora = ["bdk_esplora"]
49-
rpc = ["bdk_bitcoind_rpc"]
49+
cbf = ["bdk_kyoto", "_payjoin-dependencies"]
50+
electrum = ["bdk_electrum", "_payjoin-dependencies"]
51+
esplora = ["bdk_esplora", "_payjoin-dependencies"]
52+
rpc = ["bdk_bitcoind_rpc", "_payjoin-dependencies"]
53+
54+
# Internal features
55+
_payjoin-dependencies = ["payjoin", "reqwest", "url"]
5056

5157
# Use this to consensus verify transactions at sync time
5258
verify = []

src/commands.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,24 @@ pub enum OnlineWalletSubCommand {
430430
)]
431431
tx: Option<String>,
432432
},
433+
/// Sends an original PSBT to a BIP 21 URI and broadcasts the returned Payjoin PSBT.
434+
SendPayjoin {
435+
/// BIP 21 URI for the Payjoin.
436+
#[arg(env = "PAYJOIN_URI", long = "uri", required = true)]
437+
uri: String,
438+
/// URL of the Payjoin OHTTP relay. Can be repeated multiple times to attempt the
439+
/// operation with multiple relays for redundancy.
440+
#[arg(env = "PAYJOIN_OHTTP_RELAY", long = "ohttp_relay", required = true)]
441+
ohttp_relay: Vec<String>,
442+
/// Fee rate to use in sat/vbyte.
443+
#[arg(
444+
env = "PAYJOIN_SENDER_FEE_RATE",
445+
short = 'f',
446+
long = "fee_rate",
447+
required = true
448+
)]
449+
fee_rate: u64,
450+
},
433451
}
434452

435453
/// Subcommands for Key operations.

src/error.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,15 @@ pub enum BDKCliError {
103103
#[cfg(feature = "cbf")]
104104
#[error("BDK-Kyoto update error: {0}")]
105105
KyotoUpdateError(#[from] bdk_kyoto::UpdateError),
106+
107+
#[cfg(any(
108+
feature = "electrum",
109+
feature = "esplora",
110+
feature = "rpc",
111+
feature = "cbf",
112+
))]
113+
#[error("Reqwest error: {0}")]
114+
ReqwestError(#[from] reqwest::Error),
106115
}
107116

108117
impl From<ExtractTxError> for BDKCliError {

src/handlers.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,14 @@ use std::convert::TryFrom;
5858
#[cfg(any(feature = "repl", feature = "electrum", feature = "esplora"))]
5959
use std::io::Write;
6060
use std::str::FromStr;
61-
#[cfg(any(feature = "redb", feature = "compiler"))]
61+
#[cfg(any(
62+
feature = "redb",
63+
feature = "compiler",
64+
feature = "electrum",
65+
feature = "esplora",
66+
feature = "cbf",
67+
feature = "rpc"
68+
))]
6269
use std::sync::Arc;
6370
#[cfg(any(
6471
feature = "electrum",
@@ -68,7 +75,9 @@ use std::sync::Arc;
6875
))]
6976
use {
7077
crate::commands::OnlineWalletSubCommand::*,
78+
crate::payjoin::{PayjoinManager, ohttp::RelayManager},
7179
bdk_wallet::bitcoin::{Transaction, consensus::Decodable, hex::FromHex},
80+
std::sync::Mutex,
7281
};
7382
#[cfg(feature = "esplora")]
7483
use {crate::utils::BlockchainClient::Esplora, bdk_esplora::EsploraAsyncExt};
@@ -706,6 +715,17 @@ pub(crate) async fn handle_online_wallet_subcommand(
706715
let txid = broadcast_transaction(client, tx).await?;
707716
Ok(serde_json::to_string_pretty(&json!({ "txid": txid }))?)
708717
}
718+
SendPayjoin {
719+
uri,
720+
ohttp_relay,
721+
fee_rate,
722+
} => {
723+
let relay_manager = Arc::new(Mutex::new(RelayManager::new()));
724+
let mut payjoin_manager = PayjoinManager::new(wallet, relay_manager);
725+
return payjoin_manager
726+
.send_payjoin(uri, fee_rate, ohttp_relay, client)
727+
.await;
728+
}
709729
}
710730
}
711731

src/main.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@
1313
mod commands;
1414
mod error;
1515
mod handlers;
16+
#[cfg(any(
17+
feature = "electrum",
18+
feature = "esplora",
19+
feature = "cbf",
20+
feature = "rpc"
21+
))]
22+
mod payjoin;
1623
#[cfg(any(feature = "sqlite", feature = "redb"))]
1724
mod persister;
1825
mod utils;

0 commit comments

Comments
 (0)