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::{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(ContractId, OutgoingWitness),
57 Incoming(ContractId, 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 #[error("A contract with this ContractId already exists")]
128 ContractAlreadyExists,
129}
130
131#[derive(Debug, Clone, Hash, Eq, PartialEq, Encodable, Decodable, Serialize, Deserialize)]
132pub enum LightningConsensusItem {
133 BlockCountVote(u64),
134 UnixTimeVote(u64),
135 #[encodable_default]
136 Default {
137 variant: u64,
138 bytes: Vec<u8>,
139 },
140}
141
142impl std::fmt::Display for LightningConsensusItem {
143 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
144 write!(f, "LightningConsensusItem")
145 }
146}
147
148#[derive(Debug)]
149pub struct LightningCommonInit;
150
151impl CommonModuleInit for LightningCommonInit {
152 const CONSENSUS_VERSION: ModuleConsensusVersion = MODULE_CONSENSUS_VERSION;
153 const KIND: ModuleKind = KIND;
154
155 type ClientConfig = LightningClientConfig;
156
157 fn decoder() -> Decoder {
158 LightningModuleTypes::decoder()
159 }
160}
161
162pub struct LightningModuleTypes;
163
164plugin_types_trait_impl_common!(
165 KIND,
166 LightningModuleTypes,
167 LightningClientConfig,
168 LightningInput,
169 LightningOutput,
170 LightningOutputOutcome,
171 LightningConsensusItem,
172 LightningInputError,
173 LightningOutputError
174);