use std::io::Error;
use bitcoin::hashes::sha256::Hash as Sha256;
use bitcoin::hashes::{Hash as BitcoinHash, hash_newtype};
use fedimint_core::encoding::{Decodable, DecodeError, Encodable};
use fedimint_core::module::registry::ModuleDecoderRegistry;
use fedimint_core::{Amount, OutPoint, secp256k1};
use serde::{Deserialize, Serialize};
use crate::LightningInput;
use crate::contracts::{ContractId, DecryptedPreimage, EncryptedPreimage, IdentifiableContract};
#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Encodable, Decodable)]
pub struct IncomingContractOffer {
pub amount: fedimint_core::Amount,
pub hash: bitcoin::hashes::sha256::Hash,
pub encrypted_preimage: EncryptedPreimage,
pub expiry_time: Option<u64>,
}
impl IncomingContractOffer {
pub fn id(&self) -> OfferId {
OfferId::from_raw_hash(self.hash)
}
}
#[derive(Debug, Clone, Eq, PartialEq, Hash, Deserialize, Serialize, Encodable, Decodable)]
pub struct IncomingContract {
pub hash: bitcoin::hashes::sha256::Hash,
pub encrypted_preimage: EncryptedPreimage,
pub decrypted_preimage: DecryptedPreimage,
pub gateway_key: secp256k1::PublicKey,
}
#[derive(Debug, Clone, Eq, PartialEq, Hash, Encodable, Decodable, Serialize, Deserialize)]
pub struct FundedIncomingContract {
pub contract: IncomingContract,
pub out_point: OutPoint,
}
hash_newtype!(
pub struct OfferId(Sha256);
);
impl IdentifiableContract for IncomingContract {
fn contract_id(&self) -> ContractId {
ContractId::from_raw_hash(self.hash)
}
}
impl Encodable for OfferId {
fn consensus_encode<W: std::io::Write>(&self, writer: &mut W) -> Result<(), Error> {
self.to_byte_array().consensus_encode(writer)
}
}
impl Decodable for OfferId {
fn consensus_decode_partial<D: std::io::Read>(
d: &mut D,
modules: &ModuleDecoderRegistry,
) -> Result<Self, DecodeError> {
Ok(OfferId::from_byte_array(
Decodable::consensus_decode_partial(d, modules)?,
))
}
}
#[derive(Debug, Clone, Eq, PartialEq, Hash, Encodable, Decodable, Serialize, Deserialize)]
pub struct IncomingContractAccount {
pub amount: Amount,
pub contract: IncomingContract,
}
impl IncomingContractAccount {
pub fn claim(&self) -> LightningInput {
LightningInput::new_v0(self.contract.contract_id(), self.amount, None)
}
}