]> Untitled Git - bdk-cli/commitdiff
Add commands to resume and view payjoin history
authorMshehu5 <musheu@gmail.com>
Mon, 16 Feb 2026 13:50:06 +0000 (14:50 +0100)
committerMshehu5 <musheu@gmail.com>
Thu, 2 Jul 2026 11:30:27 +0000 (12:30 +0100)
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.

src/commands.rs
src/payjoin/mod.rs

index 46404dcf3d691eeed9e5b48e3a106a0f57d028d4..435cb6804ea2fcb07b12e5fa6414cb30d97fadab 100644 (file)
@@ -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<String>,
+        /// Resume only a specific active session ID (sender and/or receiver).
+        #[arg(env = "PAYJOIN_SESSION_ID", long = "session_id")]
+        session_id: Option<i64>,
+    },
+    /// Show payjoin session history.
+    PayjoinHistory,
 }
 
 /// Subcommands for Key operations.
index a01203738308d1da36e1a4c8865b7903ef0c9eec..df8d73d7b647fbd549b6b1e3d6206bd88e44337a 100644 (file)
@@ -44,6 +44,60 @@ pub(crate) struct PayjoinManager<'a> {
     relay_manager: Arc<Mutex<RelayManager>>,
     db: Arc<crate::payjoin::db::Database>,
 }
+
+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<String>,
 }
 
 impl<'a> PayjoinManager<'a> {