fedimint_ln_common/contracts/
mod.rs1pub mod incoming;
2pub mod outgoing;
3
4use std::io::Error;
5
6use bitcoin::hashes::sha256::Hash as Sha256;
7use bitcoin::hashes::{Hash as BitcoinHash, hash_newtype};
8use fedimint_core::encoding::{Decodable, DecodeError, Encodable};
9use fedimint_core::module::registry::ModuleDecoderRegistry;
10use fedimint_core::{OutPoint, secp256k1};
11use serde::{Deserialize, Serialize};
12
13pub trait IdentifiableContract: Encodable {
15 fn contract_id(&self) -> ContractId;
16}
17
18hash_newtype!(
19 pub struct ContractId(Sha256);
21);
22
23#[allow(clippy::large_enum_variant)]
26#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Encodable, Decodable)]
27pub enum Contract {
28 Incoming(incoming::IncomingContract),
29 Outgoing(outgoing::OutgoingContract),
30}
31
32#[allow(clippy::large_enum_variant)]
34#[derive(Debug, Clone, Eq, PartialEq, Hash, Encodable, Decodable, Serialize, Deserialize)]
35pub enum FundedContract {
36 Incoming(incoming::FundedIncomingContract),
37 Outgoing(outgoing::OutgoingContract),
38}
39
40#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Encodable, Decodable)]
43pub enum ContractOutcome {
44 Incoming(DecryptedPreimage),
45 Outgoing(OutgoingContractOutcome),
46}
47
48impl ContractOutcome {
49 pub fn is_permanent(&self) -> bool {
50 match self {
51 ContractOutcome::Incoming(o) => o.is_permanent(),
52 ContractOutcome::Outgoing(_) => true,
53 }
54 }
55}
56
57#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Encodable, Decodable)]
58pub struct OutgoingContractOutcome {}
59
60impl IdentifiableContract for Contract {
61 fn contract_id(&self) -> ContractId {
62 match self {
63 Contract::Incoming(c) => c.contract_id(),
64 Contract::Outgoing(c) => c.contract_id(),
65 }
66 }
67}
68
69impl IdentifiableContract for FundedContract {
70 fn contract_id(&self) -> ContractId {
71 match self {
72 FundedContract::Incoming(c) => c.contract.contract_id(),
73 FundedContract::Outgoing(c) => c.contract_id(),
74 }
75 }
76}
77
78impl Contract {
79 pub fn to_outcome(&self) -> ContractOutcome {
82 match self {
83 Contract::Incoming(_) => ContractOutcome::Incoming(DecryptedPreimage::Pending),
84 Contract::Outgoing(_) => ContractOutcome::Outgoing(OutgoingContractOutcome {}),
85 }
86 }
87
88 pub fn to_funded(self, out_point: OutPoint) -> FundedContract {
90 match self {
91 Contract::Incoming(incoming) => {
92 FundedContract::Incoming(incoming::FundedIncomingContract {
93 contract: incoming,
94 out_point,
95 })
96 }
97 Contract::Outgoing(outgoing) => FundedContract::Outgoing(outgoing),
98 }
99 }
100}
101
102impl Encodable for ContractId {
103 fn consensus_encode<W: std::io::Write>(&self, writer: &mut W) -> Result<(), Error> {
104 self.to_byte_array().consensus_encode(writer)
105 }
106}
107
108impl Decodable for ContractId {
109 fn consensus_decode_partial<D: std::io::Read>(
110 d: &mut D,
111 modules: &ModuleDecoderRegistry,
112 ) -> Result<Self, DecodeError> {
113 Ok(ContractId::from_byte_array(
114 Decodable::consensus_decode_partial(d, modules)?,
115 ))
116 }
117}
118
119#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Encodable, Decodable)]
120pub struct Preimage(pub [u8; 32]);
121
122#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Encodable, Decodable)]
123pub struct PreimageKey(#[serde(with = "serde_big_array::BigArray")] pub [u8; 33]);
124
125impl PreimageKey {
126 pub fn to_public_key(&self) -> Result<secp256k1::PublicKey, secp256k1::Error> {
133 secp256k1::PublicKey::from_slice(&self.0)
134 }
135}
136
137#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Encodable, Decodable)]
139pub enum DecryptedPreimageStatus {
140 Pending,
142 Some(Preimage),
144 Invalid,
146}
147
148#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Encodable, Decodable)]
150pub enum DecryptedPreimage {
151 Pending,
153 Some(PreimageKey),
155 Invalid,
157}
158
159impl DecryptedPreimage {
160 pub fn is_permanent(&self) -> bool {
161 match self {
162 DecryptedPreimage::Pending => false,
163 DecryptedPreimage::Some(_) | DecryptedPreimage::Invalid => true,
164 }
165 }
166}
167#[derive(Debug, Clone, Eq, PartialEq, Hash, Encodable, Decodable, Deserialize, Serialize)]
169pub struct EncryptedPreimage(pub threshold_crypto::Ciphertext);
170
171#[derive(Debug, Clone, PartialEq, Eq, Hash, Encodable, Decodable, Serialize, Deserialize)]
173pub struct PreimageDecryptionShare(pub threshold_crypto::DecryptionShare);
174
175impl EncryptedPreimage {
176 pub fn new(preimage_key: &PreimageKey, key: &threshold_crypto::PublicKey) -> EncryptedPreimage {
177 EncryptedPreimage(key.encrypt(preimage_key.0))
178 }
179}