Skip to content
Merged
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
7 changes: 7 additions & 0 deletions payjoin-cli/src/app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ pub trait App: Send + Sync {
amount: Amount,
fee_rate: FeeRate,
) -> Result<Psbt> {
// Check if wallet has spendable UTXOs before attempting to create PSBT
if !self.wallet().has_spendable_utxos()? {
return Err(anyhow::anyhow!(
"No spendable UTXOs available in wallet. Please ensure your wallet has confirmed funds."
));
}

// wallet_create_funded_psbt requires a HashMap<address: String, Amount>
let mut outputs = HashMap::with_capacity(1);
outputs.insert(address.to_string(), amount);
Expand Down
9 changes: 9 additions & 0 deletions payjoin-cli/src/app/v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,15 @@ fn try_contributing_inputs(
let candidate_inputs =
wallet.list_unspent().map_err(|e| ImplementationError::from(e.into_boxed_dyn_error()))?;

if candidate_inputs.is_empty() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same comment as v2 applies here

return Err(ImplementationError::from(
anyhow::anyhow!(
"No spendable UTXOs available in wallet. Please fund your wallet before resuming this session"
)
.into_boxed_dyn_error(),
));
}

let selected_input =
payjoin.try_preserving_privacy(candidate_inputs).map_err(ImplementationError::new)?;

Expand Down
6 changes: 6 additions & 0 deletions payjoin-cli/src/app/v2/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,12 @@ impl App {
let wallet = self.wallet();
let candidate_inputs = wallet.list_unspent()?;

if candidate_inputs.is_empty() {
return Err(anyhow::anyhow!(
"No spendable UTXOs available in wallet. Cannot contribute inputs to payjoin."
));
}
Comment on lines +476 to +480

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This check if fine as the internal error is opaque and this is checked in the input selection logic https://github.com/payjoin/rust-payjoin/blob/3f057e130d45c423a22c5e41007529cc0ee6894f/payjoin/src/core/receive/common/mod.rs#L273C51-L273C87

But ideally the receiver should fallback here instead. And we propogate the internally error somehow so we don't have a duplicate check


let selected_input = proposal.try_preserving_privacy(candidate_inputs)?;
let proposal =
proposal.contribute_inputs(vec![selected_input])?.commit_inputs().save(persister)?;
Expand Down
6 changes: 6 additions & 0 deletions payjoin-cli/src/app/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ impl BitcoindWallet {
Ok(unspent.into_iter().map(input_pair_from_corepc).collect())
}

/// Check if wallet has any spendable UTXOs
pub fn has_spendable_utxos(&self) -> Result<bool> {
let unspent = self.list_unspent()?;
Ok(!unspent.is_empty())
}

/// Get the network this wallet is operating on
pub fn network(&self) -> Result<Network> {
tokio::task::block_in_place(|| {
Expand Down