From a9d18ec2ce64905202f990e0191693845d07da4f Mon Sep 17 00:00:00 2001 From: Matthew Watt Date: Sat, 7 Oct 2023 15:30:07 -0500 Subject: [PATCH] Gracefully handle attempted spend to a UA with neither transparent nor sapling recipients --- zcash_client_backend/src/data_api/error.rs | 4 ++++ zcash_client_backend/src/data_api/wallet.rs | 26 ++++++++++++++++----- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/zcash_client_backend/src/data_api/error.rs b/zcash_client_backend/src/data_api/error.rs index 31a9b39c9..f5297116b 100644 --- a/zcash_client_backend/src/data_api/error.rs +++ b/zcash_client_backend/src/data_api/error.rs @@ -54,6 +54,9 @@ pub enum Error write!(f, "Must scan blocks first"), Error::Builder(e) => write!(f, "An error occurred building the transaction: {}", e), Error::MemoForbidden => write!(f, "It is not possible to send a memo to a transparent address."), + Error::UnsupportedOutputType => write!(f, "Attempted to create spend to an unsupported output type"), Error::NoteMismatch(n) => write!(f, "A note being spent ({}) does not correspond to either the internal or external full viewing key for the provided spending key.", n), #[cfg(feature = "transparent-inputs")] diff --git a/zcash_client_backend/src/data_api/wallet.rs b/zcash_client_backend/src/data_api/wallet.rs index 0d1adda6f..61da02983 100644 --- a/zcash_client_backend/src/data_api/wallet.rs +++ b/zcash_client_backend/src/data_api/wallet.rs @@ -546,12 +546,26 @@ where .memo .as_ref() .map_or_else(MemoBytes::empty, |m| m.clone()); - builder.add_sapling_output( - external_ovk, - *ua.sapling().expect("TODO: Add Orchard support to builder"), - payment.amount, - memo.clone(), - )?; + + if ua.sapling().is_some() { + builder.add_sapling_output( + external_ovk, + *ua.sapling().unwrap(), + payment.amount, + memo.clone(), + )?; + } else if ua.transparent().is_some() { + if payment.memo.is_some() { + return Err(Error::MemoForbidden); + } else { + builder.add_transparent_output( + ua.transparent().unwrap(), + payment.amount + )?; + } + } else { + return Err(Error::UnsupportedOutputType); + } sapling_output_meta.push(( Recipient::Unified(ua.clone(), PoolType::Shielded(ShieldedProtocol::Sapling)), payment.amount,