uniffi_lipalightninglib/onchain/
mod.rspub mod channel_closes;
pub mod reverse_swap;
pub mod swap;
use crate::amount::{AsSats, Msats, Sats, ToAmount};
use crate::errors::Result;
use crate::onchain::channel_closes::ChannelClose;
use crate::onchain::reverse_swap::ReverseSwap;
use crate::onchain::swap::Swap;
use crate::support::Support;
use crate::{OnchainResolvingFees, RuntimeErrorCode, SwapToLightningFees};
use breez_sdk_core::ReceiveOnchainRequest;
use log::error;
use perro::MapToError;
use std::sync::Arc;
pub struct Onchain {
    swap: Arc<Swap>,
    reverse_swap: Arc<ReverseSwap>,
    channel_close: Arc<ChannelClose>,
}
impl Onchain {
    pub(crate) fn new(support: Arc<Support>) -> Self {
        let swap = Arc::new(Swap::new(Arc::clone(&support)));
        let reverse_swap = Arc::new(ReverseSwap::new(Arc::clone(&support)));
        let channel_close = Arc::new(ChannelClose::new(Arc::clone(&support), Arc::clone(&swap)));
        Self {
            swap,
            reverse_swap,
            channel_close,
        }
    }
    pub fn swap(&self) -> Arc<Swap> {
        Arc::clone(&self.swap)
    }
    pub fn reverse_swap(&self) -> Arc<ReverseSwap> {
        Arc::clone(&self.reverse_swap)
    }
    pub fn channel_close(&self) -> Arc<ChannelClose> {
        Arc::clone(&self.channel_close)
    }
}
fn get_onchain_resolving_fees<F>(
    support: &Support,
    swap: &Swap,
    amount: Msats,
    prepare_onchain_tx: F,
) -> Result<Option<OnchainResolvingFees>>
where
    F: FnOnce(String) -> Result<(Sats, Sats, u32)>,
{
    let rate = support.get_exchange_rate();
    let lsp_fees = swap.calculate_lsp_fee_for_amount(amount.msats)?;
    let swap_info = support
        .rt
        .handle()
        .block_on(support.sdk.receive_onchain(ReceiveOnchainRequest {
            opening_fee_params: Some(lsp_fees.lsp_fee_params),
        }))
        .ok();
    let (sent_amount, onchain_fee, sats_per_vbyte) = match prepare_onchain_tx(
        swap_info
            .clone()
            .map(|s| s.bitcoin_address)
            .unwrap_or("1BitcoinEaterAddressDontSendf59kuE".to_string()),
    ) {
        Ok(t) => t,
        Err(e) => {
            error!("Failed to prepare onchain tx due to {e}");
            return Ok(None);
        }
    };
    if onchain_fee.sats * 2 > amount.sats_round_down().sats {
        return Ok(None);
    }
    let lsp_fee_response = swap.calculate_lsp_fee_for_amount(amount.msats)?;
    if swap_info.is_none()
        || sent_amount.sats < (swap_info.clone().unwrap().min_allowed_deposit as u64)
        || sent_amount.sats > (swap_info.clone().unwrap().max_allowed_deposit as u64)
        || sent_amount.sats <= lsp_fee_response.lsp_fee.sats
    {
        return Ok(Some(OnchainResolvingFees {
            swap_fees: None,
            sweep_onchain_fee_estimate: onchain_fee.to_amount_up(&rate),
            sats_per_vbyte,
        }));
    }
    let swap_fee = 0_u64.as_sats();
    let swap_to_lightning_fees = SwapToLightningFees {
        swap_fee: swap_fee.sats.as_sats().to_amount_up(&rate),
        onchain_fee: onchain_fee.to_amount_up(&rate),
        channel_opening_fee: lsp_fee_response.lsp_fee.clone(),
        total_fees: (swap_fee.sats + onchain_fee.sats + lsp_fee_response.lsp_fee.sats)
            .as_sats()
            .to_amount_up(&rate),
        lsp_fee_params: lsp_fee_response.lsp_fee_params,
    };
    Ok(Some(OnchainResolvingFees {
        swap_fees: Some(swap_to_lightning_fees),
        sweep_onchain_fee_estimate: onchain_fee.to_amount_up(&rate),
        sats_per_vbyte,
    }))
}
fn query_onchain_fee_rate(support: &Support) -> Result<u32> {
    let recommended_fees = support
        .rt
        .handle()
        .block_on(support.sdk.recommended_fees())
        .map_to_runtime_error(
            RuntimeErrorCode::NodeUnavailable,
            "Couldn't fetch recommended fees",
        )?;
    Ok(recommended_fees.half_hour_fee as u32)
}