feat: htlc from hash (#753)

* feat: htlc from hash

* chore: typos
This commit is contained in:
thesimplekid
2025-05-17 14:21:49 +01:00
committed by GitHub
parent 385ec4d295
commit 67342ec793
2 changed files with 55 additions and 4 deletions

View File

@@ -312,6 +312,16 @@ impl SpendingConditions {
}) })
} }
/// New HTLC [SpendingConditions] from a hash directly instead of preimage
pub fn new_htlc_hash(hash: &str, conditions: Option<Conditions>) -> Result<Self, Error> {
let hash = Sha256Hash::from_str(hash).map_err(|_| Error::InvalidHash)?;
Ok(Self::HTLCConditions {
data: hash,
conditions,
})
}
/// New P2PK [SpendingConditions] /// New P2PK [SpendingConditions]
pub fn new_p2pk(pubkey: PublicKey, conditions: Option<Conditions>) -> Self { pub fn new_p2pk(pubkey: PublicKey, conditions: Option<Conditions>) -> Self {
Self::P2PKConditions { Self::P2PKConditions {

View File

@@ -16,8 +16,11 @@ pub struct SendSubCommand {
#[arg(short, long)] #[arg(short, long)]
memo: Option<String>, memo: Option<String>,
/// Preimage /// Preimage
#[arg(long)] #[arg(long, conflicts_with = "hash")]
preimage: Option<String>, preimage: Option<String>,
/// Hash for HTLC (alternative to preimage)
#[arg(long, conflicts_with = "preimage")]
hash: Option<String>,
/// Required number of signatures /// Required number of signatures
#[arg(long)] #[arg(long)]
required_sigs: Option<u64>, required_sigs: Option<u64>,
@@ -62,8 +65,12 @@ pub async fn send(
check_sufficient_funds(mints_amounts[mint_number].1, token_amount)?; check_sufficient_funds(mints_amounts[mint_number].1, token_amount)?;
let conditions = match &sub_command_args.preimage { let conditions = match (&sub_command_args.preimage, &sub_command_args.hash) {
Some(preimage) => { (Some(_), Some(_)) => {
// This case shouldn't be reached due to Clap's conflicts_with attribute
unreachable!("Both preimage and hash were provided despite conflicts_with attribute")
}
(Some(preimage), None) => {
let pubkeys = match sub_command_args.pubkey.is_empty() { let pubkeys = match sub_command_args.pubkey.is_empty() {
true => None, true => None,
false => Some( false => Some(
@@ -100,7 +107,41 @@ pub async fn send(
Some(conditions), Some(conditions),
)?) )?)
} }
None => match sub_command_args.pubkey.is_empty() { (None, Some(hash)) => {
let pubkeys = match sub_command_args.pubkey.is_empty() {
true => None,
false => Some(
sub_command_args
.pubkey
.iter()
.map(|p| PublicKey::from_str(p).unwrap())
.collect(),
),
};
let refund_keys = match sub_command_args.refund_keys.is_empty() {
true => None,
false => Some(
sub_command_args
.refund_keys
.iter()
.map(|p| PublicKey::from_str(p).unwrap())
.collect(),
),
};
let conditions = Conditions::new(
sub_command_args.locktime,
pubkeys,
refund_keys,
sub_command_args.required_sigs,
None,
)
.unwrap();
Some(SpendingConditions::new_htlc_hash(hash, Some(conditions))?)
}
(None, None) => match sub_command_args.pubkey.is_empty() {
true => None, true => None,
false => { false => {
let pubkeys: Vec<PublicKey> = sub_command_args let pubkeys: Vec<PublicKey> = sub_command_args