use crate::invoice::{CkbInvoice, CkbInvoiceStatus};
use crate::payment::PaymentStatus;
use crate::serde_utils::{U128Hex, U64Hex};
use crate::Hash256;
use lightning_invoice::Bolt11Invoice;
use serde::{Deserialize, Serialize};
use serde_with::{serde_as, DisplayFromStr};
#[derive(Debug, Copy, Clone, Serialize, Deserialize, Eq, PartialEq)]
pub enum CchOrderStatus {
Pending = 0,
IncomingAccepted = 1,
OutgoingInFlight = 2,
OutgoingSuccess = 3,
Success = 4,
Failed = 5,
}
impl From<CkbInvoiceStatus> for CchOrderStatus {
fn from(status: CkbInvoiceStatus) -> Self {
match status {
CkbInvoiceStatus::Open => CchOrderStatus::Pending,
CkbInvoiceStatus::Cancelled => CchOrderStatus::Failed,
CkbInvoiceStatus::Expired => CchOrderStatus::Failed,
CkbInvoiceStatus::Received => CchOrderStatus::IncomingAccepted,
CkbInvoiceStatus::Paid => CchOrderStatus::Success,
}
}
}
impl From<PaymentStatus> for CchOrderStatus {
fn from(status: PaymentStatus) -> Self {
match status {
PaymentStatus::Created => CchOrderStatus::IncomingAccepted,
PaymentStatus::Inflight => CchOrderStatus::OutgoingInFlight,
PaymentStatus::Success => CchOrderStatus::OutgoingSuccess,
PaymentStatus::Failed => CchOrderStatus::Failed,
}
}
}
#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CchInvoice {
Fiber(#[serde_as(as = "DisplayFromStr")] CkbInvoice),
Lightning(#[serde_as(as = "DisplayFromStr")] Bolt11Invoice),
}
#[serde_as]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CchOrder {
#[serde_as(as = "U64Hex")]
pub created_at: u64,
#[serde_as(as = "U64Hex")]
pub expiry_delta_seconds: u64,
pub wrapped_btc_type_script: ckb_jsonrpc_types::Script,
pub outgoing_pay_req: String,
pub incoming_invoice: CchInvoice,
pub payment_hash: Hash256,
pub payment_preimage: Option<Hash256>,
#[serde_as(as = "U128Hex")]
pub amount_sats: u128,
#[serde_as(as = "U128Hex")]
pub fee_sats: u128,
pub status: CchOrderStatus,
pub failure_reason: Option<String>,
}
impl CchOrder {
pub fn is_final(&self) -> bool {
self.status == CchOrderStatus::Success || self.status == CchOrderStatus::Failed
}
pub fn update_if_expired(&mut self, current_time: u64) -> bool {
let expiry_time = self.created_at + self.expiry_delta_seconds;
if expiry_time < current_time {
self.status = CchOrderStatus::Failed;
self.failure_reason = Some("Order expired on startup".to_string());
true
} else {
false
}
}
}