// SPDX-License-Identifier: CC0-1.0 //! This is not an example and will surely panic if executed, the purpose of this is using the //! compiled binary with tools like `cargo bloat` that cannot work with libraries. //! //! Ideal properties: //! //! * Call all the library API surface. //! * Depend on user input so that functions are not stripped out on the base of static input. //! * Use results so that calls are not stripped out. //! use std::collections::HashMap; use std::str::FromStr; use bitcoin::{ecdsa, XOnlyPublicKey}; use miniscript::descriptor::Wsh; use miniscript::policy::{Concrete, Liftable}; use miniscript::psbt::PsbtExt; use miniscript::{ translate_hash_fail, DefiniteDescriptorKey, Descriptor, DescriptorPublicKey, MiniscriptKey, TranslatePk, Translator, }; use secp256k1::Secp256k1; fn main() { let empty = "".to_string(); let mut args = std::env::args().collect::>(); let i = args.pop().unwrap_or(empty); let d = Descriptor::::from_str(&i).unwrap(); use_descriptor(d.clone()); use_descriptor(Descriptor::::from_str(&i).unwrap()); use_descriptor(Descriptor::::from_str(&i).unwrap()); use_descriptor(Descriptor::::from_str(&i).unwrap()); let a = d .at_derivation_index(0) .unwrap() .address(bitcoin::Network::Bitcoin) .unwrap(); println!("{}", a); let secp = Secp256k1::new(); let (d, m) = Descriptor::parse_descriptor(&secp, &i).unwrap(); use_descriptor(d); println!("{:?}", m); let p = Concrete::::from_str(&i).unwrap(); let h = Wsh::new(p.compile().unwrap()).unwrap(); println!("{}", h); println!("{:?}", h.lift()); println!("{:?}", h.script_pubkey()); println!("{:?}", h.address(bitcoin::Network::Bitcoin)); let psbt: bitcoin::Psbt = i.parse().unwrap(); let psbt = psbt.finalize(&secp).unwrap(); let mut tx = psbt.extract_tx().unwrap(); println!("{:?}", tx); let d = miniscript::Descriptor::::from_str(&i).unwrap(); let sigs = HashMap::::new(); d.satisfy(&mut tx.input[0], &sigs).unwrap(); let pol = Concrete::::from_str(&i).unwrap(); let desc = pol.compile_tr(Some("UNSPENDABLE_KEY".to_string())).unwrap(); println!("{}", desc); let pk_map = HashMap::new(); let mut t = StrPkTranslator { pk_map }; let real_desc = desc.translate_pk(&mut t).unwrap(); println!("{}", real_desc); let addr = real_desc.address(bitcoin::Network::Bitcoin).unwrap(); println!("{}", addr); } fn use_descriptor(d: Descriptor) { println!("{}", d); println!("{:?}", d); println!("{:?}", d.desc_type()); println!("{:?}", d.sanity_check()); } struct StrPkTranslator { pk_map: HashMap, } impl Translator for StrPkTranslator { fn pk(&mut self, pk: &String) -> Result { self.pk_map.get(pk).copied().ok_or(()) } // We don't need to implement these methods as we are not using them in the policy. // Fail if we encounter any hash fragments. See also translate_hash_clone! macro. translate_hash_fail!(String, XOnlyPublicKey, ()); }