.map(|_| ())?)
}
- fn get_height(&self) -> Result<usize, Error> {
+ fn get_height(&self) -> Result<u32, Error> {
// TODO: unsubscribe when added to the client, or is there a better call to use here?
Ok(self
.as_ref()
.ok_or(Error::OfflineClient)?
.block_headers_subscribe()
- .map(|data| data.height)?)
+ .map(|data| data.height as u32)?)
}
fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
._broadcast(tx))?)
}
- fn get_height(&self) -> Result<usize, Error> {
+ fn get_height(&self) -> Result<u32, Error> {
Ok(await_or_block!(self
.0
.as_ref()
Ok(())
}
- async fn _get_height(&self) -> Result<usize, EsploraError> {
+ async fn _get_height(&self) -> Result<u32, EsploraError> {
let req = self
.client
.get(&format!("{}/api/blocks/tip/height", self.url))
fn get_tx(&self, txid: &Txid) -> Result<Option<Transaction>, Error>;
fn broadcast(&self, tx: &Transaction) -> Result<(), Error>;
- fn get_height(&self) -> Result<usize, Error>;
+ fn get_height(&self) -> Result<u32, Error>;
fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error>;
}
.map(|s| parse_addressee(s))
.collect::<Result<Vec<_>, _>>()
.map_err(|s| Error::Generic(s))?;
- let mut tx_builder =
- TxBuilder::from_addressees(addressees).send_all(sub_matches.is_present("send_all"));
+ let mut tx_builder = TxBuilder::from_addressees(addressees);
+
+ if sub_matches.is_present("send_all") {
+ tx_builder = tx_builder.send_all();
+ }
if let Some(fee_rate) = sub_matches.value_of("fee_rate") {
let fee_rate = f32::from_str(fee_rate).map_err(|s| Error::Generic(s.to_string()))?;
use std::cell::RefCell;
+use std::collections::HashMap;
use std::collections::{BTreeMap, HashSet};
use std::ops::DerefMut;
use std::str::FromStr;
fee_amount,
)?;
let (mut txin, prev_script_pubkeys): (Vec<_>, Vec<_>) = txin.into_iter().unzip();
+ // map that allows us to lookup the prev_script_pubkey for a given previous_output
+ let prev_script_pubkeys = txin
+ .iter()
+ .zip(prev_script_pubkeys.into_iter())
+ .map(|(txin, script)| (txin.previous_output, script))
+ .collect::<HashMap<_, _>>();
txin.iter_mut().for_each(|i| i.sequence = n_sequence);
tx.input = txin;
let mut psbt = PSBT::from_unsigned_tx(tx)?;
// add metadata for the inputs
- for ((psbt_input, prev_script), input) in psbt
+ for (psbt_input, input) in psbt
.inputs
.iter_mut()
- .zip(prev_script_pubkeys.into_iter())
.zip(psbt.global.unsigned_tx.input.iter())
{
+ let prev_script = prev_script_pubkeys.get(&input.previous_output).unwrap();
+
// Add sighash, default is obviously "ALL"
psbt_input.sighash_type = builder.sighash.or(Some(SigHashType::All));
if derived_descriptor.is_witness() {
psbt_input.witness_utxo =
Some(prev_tx.output[prev_output.vout as usize].clone());
- } else {
+ }
+ if !derived_descriptor.is_witness() || builder.force_non_witness_utxo {
psbt_input.non_witness_utxo = Some(prev_tx);
}
}
n, input.previous_output, create_height, current_height
);
- // TODO: use height once we sync headers
let satisfier =
PSBTSatisfier::new(&psbt.inputs[n], false, create_height, current_height);
))
}
+ pub fn client(&self) -> &B {
+ &self.client
+ }
+
#[maybe_async]
pub fn broadcast(&self, tx: Transaction) -> Result<Txid, Error> {
maybe_await!(self.client.broadcast(&tx))?;
Ok(tx.txid())
}
-
- #[maybe_async]
- pub fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
- Ok(maybe_await!(self.client.estimate_fee(target))?)
- }
}
#[cfg(test)]
use super::utils::FeeRate;
use crate::types::UTXO;
-// TODO: add a flag to ignore change outputs (make them unspendable)
#[derive(Debug, Default)]
pub struct TxBuilder<Cs: CoinSelectionAlgorithm> {
pub(crate) addressees: Vec<(Address, u64)>,
pub(crate) rbf: Option<u32>,
pub(crate) version: Version,
pub(crate) change_policy: ChangeSpendPolicy,
+ pub(crate) force_non_witness_utxo: bool,
pub(crate) coin_selection: Cs,
}
self
}
- pub fn send_all(mut self, send_all: bool) -> Self {
- self.send_all = send_all;
+ pub fn send_all(mut self) -> Self {
+ self.send_all = true;
self
}
self
}
+ pub fn change_policy(mut self, change_policy: ChangeSpendPolicy) -> Self {
+ self.change_policy = change_policy;
+ self
+ }
+
+ pub fn force_non_witness_utxo(mut self) -> Self {
+ self.force_non_witness_utxo = true;
+ self
+ }
+
pub fn coin_selection<P: CoinSelectionAlgorithm>(self, coin_selection: P) -> TxBuilder<P> {
TxBuilder {
addressees: self.addressees,
rbf: self.rbf,
version: self.version,
change_policy: self.change_policy,
+ force_non_witness_utxo: self.force_non_witness_utxo,
coin_selection,
}
}