Skip to content

Commit 71bf53d

Browse files
committed
Merge #1840: example_cli: add feerate option to psbt new cmd
c855a09 refactor(example_cli): clean up CLI docs (valued mammal) b9be1f4 deps(example_cli): bump `bdk_coin_select` to 0.4 (valued mammal) 3e640ff feat(example_cli): add feerate option to psbt new cmd (valued mammal) 1ab269e example_cli: fix collect assets with `for_each_key` (valued mammal) Pull request description: The PR aims to add a `--feerate` option to the psbt `New` command. Also in this PR: - bump `bdk_coin_select` to 0.4 - fix collecting `Assets` and enable support for more descriptor types ### Changelog notice ### Checklists #### All Submissions: * [x] I've signed all my commits * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) * [x] I ran `cargo fmt` and `cargo clippy` before committing ACKs for top commit: ValuedMammal: ACK c855a09 Tree-SHA512: f6a4d8d793c5258690bae397bcb3992e2c83ea21f0808e2d58c471d15aa160882873c336e71354e6c948aa9850cd62cfb53379365db79f98a9b1937a6abc2c7e
2 parents ea150b4 + c855a09 commit 71bf53d

File tree

3 files changed

+47
-32
lines changed

3 files changed

+47
-32
lines changed

example-crates/example_cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ edition = "2021"
77

88
[dependencies]
99
bdk_chain = { path = "../../crates/chain", features = ["serde", "miniscript"]}
10-
bdk_coin_select = "0.3.0"
10+
bdk_coin_select = "0.4"
1111
bdk_file_store = { path = "../../crates/file_store" }
1212
bitcoin = { version = "0.32.0", features = ["base64"], default-features = false }
1313

example-crates/example_cli/src/lib.rs

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use bdk_chain::miniscript::{
1717
descriptor::{DescriptorSecretKey, SinglePubKey},
1818
plan::{Assets, Plan},
1919
psbt::PsbtExt,
20-
Descriptor, DescriptorPublicKey,
20+
Descriptor, DescriptorPublicKey, ForEachKey,
2121
};
2222
use bdk_chain::ConfirmationBlockTime;
2323
use bdk_chain::{
@@ -147,9 +147,14 @@ pub enum PsbtCmd<S: clap::Args> {
147147
/// Create a new PSBT.
148148
New {
149149
/// Amount to send in satoshis
150+
#[clap(required = true)]
150151
value: u64,
151152
/// Recipient address
153+
#[clap(required = true)]
152154
address: Address<NetworkUnchecked>,
155+
/// Set the feerate of the tx (sat/vbyte)
156+
#[clap(long, short, default_value = "1.0")]
157+
feerate: Option<f32>,
153158
/// Set max absolute timelock (from consensus value)
154159
#[clap(long, short)]
155160
after: Option<u32>,
@@ -165,20 +170,21 @@ pub enum PsbtCmd<S: clap::Args> {
165170
},
166171
/// Sign with a hot signer
167172
Sign {
168-
/// PSBT
169-
#[clap(long)]
170-
psbt: Option<String>,
171-
/// Private descriptor
172-
#[clap(long, short = 'd')]
173+
/// Private descriptor [env: DESCRIPTOR=]
174+
#[clap(long, short)]
173175
descriptor: Option<String>,
176+
/// PSBT
177+
#[clap(long, short, required = true)]
178+
psbt: String,
174179
},
175180
/// Extract transaction
176181
Extract {
177182
/// PSBT
183+
#[clap(long, short, required = true)]
178184
psbt: String,
179185
/// Whether to try broadcasting the tx
180-
#[clap(long, short = 'b')]
181-
try_broadcast: bool,
186+
#[clap(long, short)]
187+
broadcast: bool,
182188
#[clap(flatten)]
183189
chain_specific: S,
184190
},
@@ -260,6 +266,7 @@ pub fn create_tx<O: ChainOracle>(
260266
cs_algorithm: CoinSelectionAlgo,
261267
address: Address,
262268
value: u64,
269+
feerate: f32,
263270
) -> anyhow::Result<(Psbt, Option<ChangeInfo>)>
264271
where
265272
O::Error: std::error::Error + Send + Sync + 'static,
@@ -288,7 +295,7 @@ where
288295
.map(|(plan, utxo)| {
289296
Candidate::new(
290297
utxo.txout.value.to_sat(),
291-
plan.satisfaction_weight() as u32,
298+
plan.satisfaction_weight() as u64,
292299
plan.witness_version().is_some(),
293300
)
294301
})
@@ -330,9 +337,12 @@ where
330337
outputs: TargetOutputs::fund_outputs(
331338
outputs
332339
.iter()
333-
.map(|output| (output.weight().to_wu() as u32, output.value.to_sat())),
340+
.map(|output| (output.weight().to_wu(), output.value.to_sat())),
334341
),
335-
fee: TargetFee::default(),
342+
fee: TargetFee {
343+
rate: FeeRate::from_sat_per_vb(feerate),
344+
..Default::default()
345+
},
336346
};
337347

338348
let change_policy = ChangePolicy {
@@ -444,7 +454,7 @@ pub fn handle_commands<CS: clap::Subcommand, S: clap::Args>(
444454
chain: &Mutex<LocalChain>,
445455
db: &Mutex<Store<ChangeSet>>,
446456
network: Network,
447-
broadcast: impl FnOnce(S, &Transaction) -> anyhow::Result<()>,
457+
broadcast_fn: impl FnOnce(S, &Transaction) -> anyhow::Result<()>,
448458
cmd: Commands<CS, S>,
449459
) -> anyhow::Result<()> {
450460
match cmd {
@@ -584,6 +594,7 @@ pub fn handle_commands<CS: clap::Subcommand, S: clap::Args>(
584594
PsbtCmd::New {
585595
value,
586596
address,
597+
feerate,
587598
after,
588599
older,
589600
coin_select,
@@ -596,26 +607,30 @@ pub fn handle_commands<CS: clap::Subcommand, S: clap::Args>(
596607
let chain = chain.lock().unwrap();
597608

598609
// collect assets we can sign for
599-
let mut assets = Assets::new();
610+
let mut pks = vec![];
611+
for (_, desc) in graph.index.keychains() {
612+
desc.for_each_key(|k| {
613+
pks.push(k.clone());
614+
true
615+
});
616+
}
617+
let mut assets = Assets::new().add(pks);
600618
if let Some(n) = after {
601619
assets = assets.after(absolute::LockTime::from_consensus(n));
602620
}
603621
if let Some(n) = older {
604622
assets = assets.older(relative::LockTime::from_consensus(n)?);
605623
}
606-
for (_, desc) in graph.index.keychains() {
607-
match desc {
608-
Descriptor::Wpkh(wpkh) => {
609-
assets = assets.add(wpkh.clone().into_inner());
610-
}
611-
Descriptor::Tr(tr) => {
612-
assets = assets.add(tr.internal_key().clone());
613-
}
614-
_ => bail!("unsupported descriptor type"),
615-
}
616-
}
617624

618-
create_tx(&mut graph, &*chain, &assets, coin_select, address, value)?
625+
create_tx(
626+
&mut graph,
627+
&*chain,
628+
&assets,
629+
coin_select,
630+
address,
631+
value,
632+
feerate.expect("must have feerate"),
633+
)?
619634
};
620635

621636
if let Some(ChangeInfo {
@@ -659,7 +674,7 @@ pub fn handle_commands<CS: clap::Subcommand, S: clap::Args>(
659674
Ok(())
660675
}
661676
PsbtCmd::Sign { psbt, descriptor } => {
662-
let mut psbt = Psbt::from_str(psbt.unwrap_or_default().as_str())?;
677+
let mut psbt = Psbt::from_str(&psbt)?;
663678

664679
let desc_str = match descriptor {
665680
Some(s) => s,
@@ -697,20 +712,20 @@ pub fn handle_commands<CS: clap::Subcommand, S: clap::Args>(
697712
Ok(())
698713
}
699714
PsbtCmd::Extract {
700-
try_broadcast,
715+
broadcast,
701716
chain_specific,
702717
psbt,
703718
} => {
704-
let mut psbt = Psbt::from_str(psbt.as_str())?;
719+
let mut psbt = Psbt::from_str(&psbt)?;
705720
psbt.finalize_mut(&Secp256k1::new())
706721
.map_err(|errors| anyhow::anyhow!("failed to finalize PSBT {errors:?}"))?;
707722

708723
let tx = psbt.extract_tx()?;
709724

710-
if try_broadcast {
725+
if broadcast {
711726
let mut graph = graph.lock().unwrap();
712727

713-
match broadcast(chain_specific, &tx) {
728+
match broadcast_fn(chain_specific, &tx) {
714729
Ok(_) => {
715730
println!("Broadcasted Tx: {}", tx.compute_txid());
716731

example-crates/example_esplora/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ impl EsploraArgs {
8787
#[derive(Parser, Debug, Clone, PartialEq)]
8888
pub struct ScanOptions {
8989
/// Max number of concurrent esplora server requests.
90-
#[clap(long, default_value = "5")]
90+
#[clap(long, default_value = "2")]
9191
pub parallel_requests: usize,
9292
}
9393

0 commit comments

Comments
 (0)