From b8ac1193447ae446658ac0e1513d36ffa7539e5b Mon Sep 17 00:00:00 2001 From: Matthew Black Date: Mon, 6 Apr 2026 13:02:45 -0500 Subject: [PATCH] feat(ddk-manager): add DDK_ALLOW_UNCONFIRMED_SPLICE env var for 0-conf splice Allow signing DLC inputs from Signed (unconfirmed) contracts when DDK_ALLOW_UNCONFIRMED_SPLICE=true is set. This enables 0-conf splice operations on testnets without waiting for on-chain confirmation. By default, the behavior is unchanged - only Confirmed contracts can be used for DLC input signing. The env var opt-in allows testnet deployments to skip the confirmation wait for faster iteration. --- ddk-manager/src/dlc_input.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) 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(), )),