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