From: Mshehu5 Date: Mon, 16 Feb 2026 13:50:06 +0000 (+0100) Subject: Add commands to resume and view payjoin history X-Git-Url: http://internal-gitweb-vhost/blockdata/script/encode/-script/display/struct.Script.html?a=commitdiff_plain;h=559ba76255adaa2ab129c5df63d796ae53f5ac67;p=bdk-cli Add commands to resume and view payjoin history Expose persisted payjoin session state through CLI commands so users can recover interrupted sessions and review prior session progress. Add `resume` to continue pending sender and receiver sessions, `history` to list saved sessions, status text helpers for clearer output, and session ID filtering to target a specific session. This improves recovery and troubleshooting for long-running async payjoin flows by making persisted session state available from the CLI. --- diff --git a/src/commands.rs b/src/commands.rs index 46404dc..435cb68 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -636,6 +636,20 @@ pub enum OnlineWalletSubCommand { )] fee_rate: u64, }, + /// Resume pending payjoin sessions. + ResumePayjoin { + /// Payjoin directory for the session + #[arg(env = "PAYJOIN_DIRECTORY", long = "directory", required = true)] + directory: String, + /// URL of the Payjoin OHTTP relay. Can be repeated multiple times. + #[arg(env = "PAYJOIN_OHTTP_RELAY", long = "ohttp_relay", required = true)] + ohttp_relay: Vec, + /// Resume only a specific active session ID (sender and/or receiver). + #[arg(env = "PAYJOIN_SESSION_ID", long = "session_id")] + session_id: Option, + }, + /// Show payjoin session history. + PayjoinHistory, } /// Subcommands for Key operations. diff --git a/src/payjoin/mod.rs b/src/payjoin/mod.rs index a012037..df8d73d 100644 --- a/src/payjoin/mod.rs +++ b/src/payjoin/mod.rs @@ -44,6 +44,60 @@ pub(crate) struct PayjoinManager<'a> { relay_manager: Arc>, db: Arc, } + +trait StatusText { + fn status_text(&self) -> &'static str; +} + +impl StatusText for SendSession { + fn status_text(&self) -> &'static str { + match self { + SendSession::WithReplyKey(_) | SendSession::PollingForProposal(_) => { + "Waiting for proposal" + } + SendSession::Closed(session_outcome) => match session_outcome { + SenderSessionOutcome::Failure => "Session failure", + SenderSessionOutcome::Success(_) => "Session success", + SenderSessionOutcome::Cancel => "Session cancelled", + }, + } + } +} + +impl StatusText for ReceiveSession { + fn status_text(&self) -> &'static str { + match self { + ReceiveSession::Initialized(_) => "Waiting for original proposal", + ReceiveSession::UncheckedOriginalPayload(_) + | ReceiveSession::MaybeInputsOwned(_) + | ReceiveSession::MaybeInputsSeen(_) + | ReceiveSession::OutputsUnknown(_) + | ReceiveSession::WantsOutputs(_) + | ReceiveSession::WantsInputs(_) + | ReceiveSession::WantsFeeRange(_) + | ReceiveSession::ProvisionalProposal(_) => "Processing original proposal", + ReceiveSession::PayjoinProposal(_) => "Payjoin proposal sent", + ReceiveSession::HasReplyableError(_) => { + "Session failure, waiting to post error response" + } + ReceiveSession::Monitor(_) => "Monitoring payjoin proposal", + ReceiveSession::Closed(session_outcome) => match session_outcome { + ReceiverSessionOutcome::Failure => "Session failure", + ReceiverSessionOutcome::Success(_) => { + "Session success, Payjoin proposal was broadcasted" + } + ReceiverSessionOutcome::Cancel => "Session cancelled", + ReceiverSessionOutcome::FallbackBroadcasted => "Fallback broadcasted", + }, + } + } +} + +struct SessionHistoryRow { + id: String, + role: &'static str, + status: String, + completed_at: Option, } impl<'a> PayjoinManager<'a> {