diff --git a/src/policy/concrete.rs b/src/policy/concrete.rs index 817f699e3..6c1c5f190 100644 --- a/src/policy/concrete.rs +++ b/src/policy/concrete.rs @@ -108,6 +108,20 @@ pub enum PolicyError { DuplicatePubKeys, } +/// Descriptor context for [`Policy`] compilation into a [`Descriptor`] +pub enum DescriptorCtx { + /// [Bare][`Descriptor::Bare`] + Bare, + /// [Sh][`Descriptor::Sh`] + Sh, + /// [Wsh][`Descriptor::Wsh`] + Wsh, + /// Sh-wrapped [Wsh][`Descriptor::Wsh`] + ShWsh, + /// [Tr][`Descriptor::Tr`], where the Option corresponds to the internal_key. + Tr(Option), +} + impl error::Error for PolicyError {} impl fmt::Display for PolicyError { @@ -328,6 +342,28 @@ impl Policy { } } + /// Compile the [`Policy`] into desc_ctx [`Descriptor`] + #[cfg(feature = "compiler")] + pub fn compile_to_descriptor( + &self, + desc_ctx: DescriptorCtx, + ) -> Result, Error> { + self.is_valid()?; + match self.is_safe_nonmalleable() { + (false, _) => Err(Error::from(CompilerError::TopLevelNonSafe)), + (_, false) => Err(Error::from( + CompilerError::ImpossibleNonMalleableCompilation, + )), + _ => match desc_ctx { + DescriptorCtx::Bare => Descriptor::new_bare(compiler::best_compilation(self)?), + DescriptorCtx::Sh => Descriptor::new_sh(compiler::best_compilation(self)?), + DescriptorCtx::Wsh => Descriptor::new_wsh(compiler::best_compilation(self)?), + DescriptorCtx::ShWsh => Descriptor::new_sh_wsh(compiler::best_compilation(self)?), + DescriptorCtx::Tr(unspendable_key) => self.compile_tr(unspendable_key), + }, + } + } + /// Compile the descriptor into an optimized `Miniscript` representation #[cfg(feature = "compiler")] pub fn compile(&self) -> Result, CompilerError> {