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