diff --git a/src/electrum.rs b/src/electrum.rs index 31547a5..a4df772 100644 --- a/src/electrum.rs +++ b/src/electrum.rs @@ -78,6 +78,29 @@ impl From<&TxGetArgs> for (Txid, bool) { } } +#[derive(Deserialize)] +#[serde(untagged)] +enum BroadcastArgs { + Package((Vec,)), + PackageVerbose((Vec, bool)), +} + +impl BroadcastArgs { + fn txs(&self) -> &[String] { + match self { + BroadcastArgs::Package((txs,)) => txs, + BroadcastArgs::PackageVerbose((txs, _)) => txs, + } + } + + fn verbose(&self) -> bool { + match self { + BroadcastArgs::Package(_) => false, + BroadcastArgs::PackageVerbose((_, verbose)) => *verbose, + } + } +} + enum StandardError { ParseError, InvalidRequest, @@ -363,12 +386,34 @@ impl Rpc { Ok(json!(txid)) } - fn transaction_broadcast_package(&self, (txs_hex,): &(Vec,)) -> Result { - let txs = txs_hex + fn transaction_broadcast_package(&self, args: &BroadcastArgs) -> Result { + let txs: Vec = args + .txs() .iter() .map(|s| tx_from_hex(s)) - .collect::>>()?; - self.daemon.submitpackage(&txs) + .collect::>()?; + let response = self.daemon.submitpackage(&txs)?; + if args.verbose() { + return Ok(response); + } + let build_result = || -> Option { + let success = response.get("package_msg")? == &json!("success"); + + let mut errors = vec![]; + for tx in response.get("tx-results")?.as_object()?.values() { + let tx_obj = tx.as_object()?; + if let Some(error) = tx_obj.get("error") { + let txid = tx_obj.get("txid"); + errors.push(json!({"error": error, "txid": txid})); + } + } + Some(if errors.is_empty() { + json!({"success": success}) + } else { + json!({"success": success, "errors": errors}) + }) + }; + build_result().ok_or(anyhow!("Unexpected `submitpackage` response")) } fn transaction_get(&self, args: &TxGetArgs) -> Result { @@ -587,7 +632,7 @@ enum Params { BlockHeader((usize,)), BlockHeaders((usize, usize)), TransactionBroadcast((String,)), - TransactionBroadcastPackage((Vec,)), + TransactionBroadcastPackage(BroadcastArgs), Donation, EstimateFee((u16,)), Features,