fedimint_ln_common/
config.rs

1pub use bitcoin::Network;
2use fedimint_core::core::ModuleKind;
3use fedimint_core::encoding::btc::NetworkLegacyEncodingWrapper;
4use fedimint_core::encoding::{Decodable, Encodable};
5use fedimint_core::envs::BitcoinRpcConfig;
6use fedimint_core::{Amount, msats, plugin_types_trait_impl_config};
7use lightning_invoice::RoutingFees;
8use serde::{Deserialize, Serialize};
9use threshold_crypto::serde_impl::SerdeSecret;
10
11use crate::LightningCommonInit;
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct LightningConfig {
15    pub private: LightningConfigPrivate,
16    pub consensus: LightningConfigConsensus,
17}
18
19#[derive(Clone, Debug, Serialize, Deserialize, Decodable, Encodable)]
20pub struct LightningConfigLocal {
21    /// Configures which bitcoin RPC to use
22    pub bitcoin_rpc: BitcoinRpcConfig,
23}
24
25#[derive(Debug, Clone, Serialize, Deserialize, Encodable, Decodable)]
26pub struct LightningConfigConsensus {
27    /// The threshold public keys for encrypting the LN preimage
28    pub threshold_pub_keys: threshold_crypto::PublicKeySet,
29    /// Fees charged for LN transactions
30    pub fee_consensus: FeeConsensus,
31    pub network: NetworkLegacyEncodingWrapper,
32}
33
34impl LightningConfigConsensus {
35    /// The number of decryption shares required
36    pub fn threshold(&self) -> usize {
37        self.threshold_pub_keys.threshold() + 1
38    }
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize)]
42pub struct LightningConfigPrivate {
43    // TODO: propose serde(with = "…") based protection upstream instead
44    /// Our secret key for decrypting preimages
45    pub threshold_sec_key: SerdeSecret<threshold_crypto::SecretKeyShare>,
46}
47
48#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Encodable, Decodable)]
49pub struct LightningClientConfig {
50    pub threshold_pub_key: threshold_crypto::PublicKey,
51    pub fee_consensus: FeeConsensus,
52    pub network: NetworkLegacyEncodingWrapper,
53}
54
55impl std::fmt::Display for LightningClientConfig {
56    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57        write!(
58            f,
59            "LightningClientConfig {}",
60            serde_json::to_string(self).map_err(|_e| std::fmt::Error)?
61        )
62    }
63}
64
65// Wire together the configs for this module
66plugin_types_trait_impl_config!(
67    LightningCommonInit,
68    LightningConfig,
69    LightningConfigPrivate,
70    LightningConfigConsensus,
71    LightningClientConfig
72);
73
74#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Encodable, Decodable)]
75pub struct FeeConsensus {
76    pub contract_input: fedimint_core::Amount,
77    pub contract_output: fedimint_core::Amount,
78}
79
80impl Default for FeeConsensus {
81    fn default() -> Self {
82        Self {
83            contract_input: fedimint_core::Amount::ZERO,
84            contract_output: fedimint_core::Amount::ZERO,
85        }
86    }
87}
88
89/// Trait for converting a fee type to specific `Amount`,
90/// relative to a given payment `Amount`
91pub trait FeeToAmount {
92    /// Calculates fee `Amount` given a payment `Amount`
93    fn to_amount(&self, payment: &Amount) -> Amount;
94}
95
96impl FeeToAmount for RoutingFees {
97    fn to_amount(&self, payment: &Amount) -> Amount {
98        let base_fee = u64::from(self.base_msat);
99        let margin_fee: u64 = if self.proportional_millionths > 0 {
100            let fee_percent = 1_000_000 / u64::from(self.proportional_millionths);
101            payment.msats / fee_percent
102        } else {
103            0
104        };
105
106        msats(base_fee + margin_fee)
107    }
108}