1#![deny(clippy::pedantic)]
2#![allow(clippy::module_name_repetitions)]
3#![allow(clippy::must_use_candidate)]
4
5extern crate core;
11
12pub mod config;
13pub mod contracts;
14pub mod endpoint_constants;
15pub mod gateway_api;
16
17use bitcoin::hashes::sha256;
18use bitcoin::secp256k1::schnorr::Signature;
19use config::LightningClientConfig;
20use fedimint_core::core::{Decoder, ModuleInstanceId, ModuleKind};
21use fedimint_core::encoding::{Decodable, Encodable};
22use fedimint_core::module::{CommonModuleInit, ModuleCommon, ModuleConsensusVersion};
23use fedimint_core::{OutPoint, extensible_associated_module_type, plugin_types_trait_impl_common};
24use lightning_invoice::Bolt11Invoice;
25use serde::{Deserialize, Serialize};
26use thiserror::Error;
27use tpe::AggregateDecryptionKey;
28
29use crate::contracts::{IncomingContract, OutgoingContract};
30
31#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
32pub enum Bolt11InvoiceDescription {
33 Direct(String),
34 Hash(sha256::Hash),
35}
36
37#[derive(Debug, Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Decodable, Encodable)]
38pub enum LightningInvoice {
39 Bolt11(Bolt11Invoice),
40}
41
42pub const KIND: ModuleKind = ModuleKind::from_static_str("lnv2");
43pub const MODULE_CONSENSUS_VERSION: ModuleConsensusVersion = ModuleConsensusVersion::new(1, 0);
44
45#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, Deserialize, Serialize, Encodable, Decodable)]
46pub struct ContractId(pub sha256::Hash);
47
48extensible_associated_module_type!(
49 LightningInput,
50 LightningInputV0,
51 UnknownLightningInputVariantError
52);
53
54#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Encodable, Decodable)]
55pub enum LightningInputV0 {
56 Outgoing(OutPoint, OutgoingWitness),
57 Incoming(OutPoint, AggregateDecryptionKey),
58}
59
60#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Encodable, Decodable)]
61pub enum OutgoingWitness {
62 Claim([u8; 32]),
63 Refund,
64 Cancel(Signature),
65}
66
67impl std::fmt::Display for LightningInputV0 {
68 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
69 write!(f, "LightningInputV0",)
70 }
71}
72
73extensible_associated_module_type!(
74 LightningOutput,
75 LightningOutputV0,
76 UnknownLightningOutputVariantError
77);
78
79#[allow(clippy::large_enum_variant)]
80#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Encodable, Decodable)]
81pub enum LightningOutputV0 {
82 Outgoing(OutgoingContract),
83 Incoming(IncomingContract),
84}
85
86impl std::fmt::Display for LightningOutputV0 {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
88 write!(f, "LightningOutputV0")
89 }
90}
91
92#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Encodable, Decodable)]
93pub struct LightningOutputOutcome;
94
95impl std::fmt::Display for LightningOutputOutcome {
96 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97 write!(f, "LightningOutputOutcome")
98 }
99}
100
101#[derive(Debug, Clone, Eq, PartialEq, Hash, Error, Encodable, Decodable)]
102pub enum LightningInputError {
103 #[error("The lightning input version is not supported by this federation")]
104 UnknownInputVariant(#[from] UnknownLightningInputVariantError),
105 #[error("No contract found for given ContractId")]
106 UnknownContract,
107 #[error("The preimage is invalid")]
108 InvalidPreimage,
109 #[error("The contracts locktime has passed")]
110 Expired,
111 #[error("The contracts locktime has not yet passed")]
112 NotExpired,
113 #[error("The aggregate decryption key is invalid")]
114 InvalidDecryptionKey,
115 #[error("The forfeit signature is invalid")]
116 InvalidForfeitSignature,
117}
118
119#[derive(Debug, Clone, Eq, PartialEq, Hash, Error, Encodable, Decodable)]
120pub enum LightningOutputError {
121 #[error("The lightning input version is not supported by this federation")]
122 UnknownOutputVariant(#[from] UnknownLightningOutputVariantError),
123 #[error("The contract is invalid")]
124 InvalidContract,
125 #[error("The contract is expired")]
126 ContractExpired,
127}
128
129#[derive(Debug, Clone, Hash, Eq, PartialEq, Encodable, Decodable, Serialize, Deserialize)]
130pub enum LightningConsensusItem {
131 BlockCountVote(u64),
132 UnixTimeVote(u64),
133 #[encodable_default]
134 Default {
135 variant: u64,
136 bytes: Vec<u8>,
137 },
138}
139
140impl std::fmt::Display for LightningConsensusItem {
141 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
142 write!(f, "LightningConsensusItem")
143 }
144}
145
146#[derive(Debug)]
147pub struct LightningCommonInit;
148
149impl CommonModuleInit for LightningCommonInit {
150 const CONSENSUS_VERSION: ModuleConsensusVersion = MODULE_CONSENSUS_VERSION;
151 const KIND: ModuleKind = KIND;
152
153 type ClientConfig = LightningClientConfig;
154
155 fn decoder() -> Decoder {
156 LightningModuleTypes::decoder()
157 }
158}
159
160pub struct LightningModuleTypes;
161
162plugin_types_trait_impl_common!(
163 KIND,
164 LightningModuleTypes,
165 LightningClientConfig,
166 LightningInput,
167 LightningOutput,
168 LightningOutputOutcome,
169 LightningConsensusItem,
170 LightningInputError,
171 LightningOutputError
172);