1use bdk_esplora::esplora_client::Amount;
12use bitcoin_ext::BlockDelta;
13use lightning_invoice::Bolt11Invoice;
14
15use ark::{VtxoId, VtxoPolicy, VtxoRequest};
16use ark::lightning::{Invoice, PaymentHash, Preimage};
17
18use crate::exit::ExitVtxo;
19use crate::exit::models::ExitState;
20use crate::vtxo_state::VtxoState;
21use crate::WalletVtxo;
22
23#[derive(Clone, Debug, PartialEq, Eq)]
29pub struct PendingLightningSend {
30 pub invoice: Invoice,
31 pub amount: Amount,
32 pub htlc_vtxos: Vec<WalletVtxo>,
33}
34
35#[derive(Debug, Clone)]
42pub struct LightningReceive {
43 pub payment_hash: PaymentHash,
44 pub payment_preimage: Preimage,
45 pub invoice: Bolt11Invoice,
46 pub preimage_revealed_at: Option<u64>,
47 pub htlc_vtxos: Option<Vec<WalletVtxo>>,
48 pub htlc_recv_cltv_delta: BlockDelta,
49}
50
51pub struct StoredExit {
56 pub vtxo_id: VtxoId,
58 pub state: ExitState,
60 pub history: Vec<ExitState>,
62}
63
64impl StoredExit {
65 pub fn new(exit: &ExitVtxo) -> Self {
67 Self {
68 vtxo_id: exit.id(),
69 state: exit.state().clone(),
70 history: exit.history().clone(),
71 }
72 }
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct StoredVtxoRequest {
81 #[serde(with = "ark::encode::serde")]
82 pub request_policy: VtxoPolicy,
83 pub amount: Amount,
84 pub state: VtxoState
85}
86
87impl StoredVtxoRequest {
88 pub fn from_parts(req: VtxoRequest, state: VtxoState) -> Self {
89 Self {
90 request_policy: req.policy,
91 amount: req.amount,
92 state,
93 }
94 }
95
96 pub fn to_vtxo_request(&self) -> VtxoRequest {
97 VtxoRequest {
98 policy: self.request_policy.clone(),
99 amount: self.amount,
100 }
101 }
102}
103
104#[cfg(test)]
105mod test {
106 use super::*;
107
108 use crate::exit::models::{ExitState, ExitTxOrigin};
109 use crate::movement::MovementRecipient;
110 use crate::vtxo_state::VtxoState;
111
112 #[test]
113 fn test_serialised_structs() {
116 let serialised = r#"{"type":"start","tip_height":119}"#;
118 serde_json::from_str::<ExitState>(serialised).unwrap();
119 let serialised = r#"{"type":"processing","tip_height":119,"transactions":[{"txid":"9fd34b8c556dd9954bda80ba2cf3474a372702ebc31a366639483e78417c6812","status":{"type":"awaiting-input-confirmation","txids":["ddfe11920358d1a1fae970dc80459c60675bf1392896f69b103fc638313751de"]}}]}"#;
120 serde_json::from_str::<ExitState>(serialised).unwrap();
121 let serialised = r#"{"type":"awaiting-delta","tip_height":122,"confirmed_block":"122:3cdd30fc942301a74666c481beb82050ccd182050aee3c92d2197e8cad427b8f","claimable_height":134}"#;
122 serde_json::from_str::<ExitState>(serialised).unwrap();
123 let serialised = r#"{"type":"claimable","tip_height":134,"claimable_since": "134:71fe28f4c803a4c46a3a93d0a9937507d7c20b4bd9586ba317d1109e1aebaac9","last_scanned_block":null}"#;
124 serde_json::from_str::<ExitState>(serialised).unwrap();
125 let serialised = r#"{"type":"claim-in-progress","tip_height":134, "claimable_since": "134:6585896bdda6f08d924bf45cc2b16418af56703b3c50930e4dccbc1728d3800a","claim_txid":"599347c35870bd36f7acb22b81f9ffa8b911d9b5e94834858aebd3ec09339f4c"}"#;
126 serde_json::from_str::<ExitState>(serialised).unwrap();
127 let serialised = r#"{"type":"claimed","tip_height":134,"txid":"599347c35870bd36f7acb22b81f9ffa8b911d9b5e94834858aebd3ec09339f4c","block": "122:3cdd30fc942301a74666c481beb82050ccd182050aee3c92d2197e8cad427b8f"}"#;
128 serde_json::from_str::<ExitState>(serialised).unwrap();
129
130 let serialized = r#"{"type":"wallet","confirmed_in":null}"#;
132 serde_json::from_str::<ExitTxOrigin>(serialized).unwrap();
133 let serialized = r#"{"type":"wallet","confirmed_in": "134:71fe28f4c803a4c46a3a93d0a9937507d7c20b4bd9586ba317d1109e1aebaac9"}"#;
134 serde_json::from_str::<ExitTxOrigin>(serialized).unwrap();
135 let serialized = r#"{"type":"mempool","fee_rate_kwu":25000,"total_fee":27625}"#;
136 serde_json::from_str::<ExitTxOrigin>(serialized).unwrap();
137 let serialized = r#"{"type":"block","confirmed_in": "134:71fe28f4c803a4c46a3a93d0a9937507d7c20b4bd9586ba317d1109e1aebaac9"}"#;
138 serde_json::from_str::<ExitTxOrigin>(serialized).unwrap();
139
140 let serialised = r#"{"recipient":"03a4a6443868dbba406d03e43d7baf00d66809d57fba911616ccf90a4685de2bc1","amount_sat":150000}"#;
142 serde_json::from_str::<MovementRecipient>(serialised).unwrap();
143
144 let serialised = r#""Spendable""#;
146 serde_json::from_str::<VtxoState>(serialised).unwrap();
147 let serialised = r#""Spent""#;
148 serde_json::from_str::<VtxoState>(serialised).unwrap();
149 let serialised = r#""Locked""#;
150 serde_json::from_str::<VtxoState>(serialised).unwrap();
151
152 let serialised = r#"{"request_policy":"0003a4a6443868dbba406d03e43d7baf00d66809d57fba911616ccf90a4685de2bc1","amount":300000,"state":"Spendable"}"#;
153 serde_json::from_str::<StoredVtxoRequest>(serialised).unwrap();
154 }
155}