use super::offered_contract::OfferedContract;
use super::AdaptorInfo;
use bitcoin::{Amount, SignedAmount, Transaction};
use ddk_dlc::{DlcTransactions, PartyParams};
use ddk_messages::{AcceptDlc, FundingInput};
use secp256k1_zkp::ecdsa::Signature;
use secp256k1_zkp::EcdsaAdaptorSignature;
use std::fmt::Write as _;
#[derive(Clone)]
pub struct AcceptedContract {
pub offered_contract: OfferedContract,
pub accept_params: PartyParams,
pub funding_inputs: Vec<FundingInput>,
pub adaptor_infos: Vec<AdaptorInfo>,
pub adaptor_signatures: Vec<EcdsaAdaptorSignature>,
pub accept_refund_signature: Signature,
pub dlc_transactions: DlcTransactions,
}
impl AcceptedContract {
pub fn get_contract_id(&self) -> [u8; 32] {
crate::utils::compute_id(
self.dlc_transactions.fund.compute_txid(),
self.dlc_transactions.get_fund_output_index() as u16,
&self.offered_contract.id,
)
}
pub fn get_contract_id_string(&self) -> String {
let mut string_id = String::with_capacity(32 * 2 + 2);
string_id.push_str("0x");
let id = self.get_contract_id();
for i in &id {
write!(string_id, "{i:02x}").unwrap();
}
string_id
}
pub fn get_accept_contract_msg(
&self,
ecdsa_adaptor_signatures: &[EcdsaAdaptorSignature],
) -> AcceptDlc {
AcceptDlc {
protocol_version: crate::conversion_utils::PROTOCOL_VERSION,
temporary_contract_id: self.offered_contract.id,
accept_collateral: self.accept_params.collateral,
funding_pubkey: self.accept_params.fund_pubkey,
payout_spk: self.accept_params.payout_script_pubkey.clone(),
payout_serial_id: self.accept_params.payout_serial_id,
funding_inputs: self.funding_inputs.clone(),
change_spk: self.accept_params.change_script_pubkey.clone(),
change_serial_id: self.accept_params.change_serial_id,
cet_adaptor_signatures: ecdsa_adaptor_signatures.into(),
refund_signature: self.accept_refund_signature,
negotiation_fields: None,
}
}
pub fn compute_pnl(&self, cet: &Transaction) -> SignedAmount {
let offer = &self.offered_contract;
let party_params = if offer.is_offer_party {
&offer.offer_params
} else {
&self.accept_params
};
let collateral = party_params.collateral;
let v0_witness_payout_script = &party_params.payout_script_pubkey;
let final_payout = cet
.output
.iter()
.find_map(|x| {
if &x.script_pubkey == v0_witness_payout_script {
Some(x.value)
} else {
None
}
})
.unwrap_or(Amount::ZERO);
SignedAmount::from_sat(final_payout.to_sat() as i64 - collateral.to_sat() as i64)
}
}