diff --git a/ddk-manager/src/dlc_input.rs b/ddk-manager/src/dlc_input.rs index 3c11810..6a50ce5 100644 --- a/ddk-manager/src/dlc_input.rs +++ b/ddk-manager/src/dlc_input.rs @@ -10,6 +10,14 @@ use crate::{ contract::Contract, error::Error, ContractId, ContractSigner, ContractSignerProvider, Storage, }; +/// Check if unconfirmed (Signed) contracts are allowed for DLC input signing. +/// Set DDK_ALLOW_UNCONFIRMED_SPLICE=true to enable 0-conf splice operations. +fn allow_unconfirmed_splice() -> bool { + std::env::var("DDK_ALLOW_UNCONFIRMED_SPLICE") + .map(|v| v.to_lowercase() == "true" || v == "1") + .unwrap_or(false) +} + // todo: definitely test /// Get the DlcInputInfo from FundingInputs pub fn get_dlc_inputs_from_funding_inputs(funding_inputs: &[FundingInput]) -> Vec { @@ -44,8 +52,18 @@ where "Contract not found to sign DLC input.".to_string(), ))?; + // Extract keys_id from contract based on state. + // By default, only Confirmed contracts are allowed for DLC input signing. + // Set DDK_ALLOW_UNCONFIRMED_SPLICE=true to also allow Signed contracts + // (funding tx in mempool but not yet confirmed). Useful for testnets and 0-conf operations. let key_id = match contract { Contract::Confirmed(c) => Ok(c.accepted_contract.offered_contract.keys_id), + Contract::Signed(s) if allow_unconfirmed_splice() => { + Ok(s.accepted_contract.offered_contract.keys_id) + } + Contract::Signed(_) => Err(Error::InvalidState( + "Contract must be confirmed to sign DLC input. Set DDK_ALLOW_UNCONFIRMED_SPLICE=true for 0-conf splice.".to_string(), + )), _ => Err(Error::InvalidState( "Contract must be confirmed to sign DLC input.".to_string(), )),