1use bitcoin::{Amount, ScriptBuf};
4use ddk_dlc::Error;
5use lightning::ln::msgs::DecodeError;
6use lightning::util::ser::{Readable, Writeable, Writer};
7use secp256k1_zkp::{
8 ecdsa::Signature, EcdsaAdaptorSignature, PublicKey, Secp256k1, SecretKey, Verification,
9};
10
11use crate::FundingSignatures;
12use crate::{
13 contract_msgs::ContractInfo,
14 ser_impls::{read_ecdsa_adaptor_signature, write_ecdsa_adaptor_signature},
15 types::*,
16 CetAdaptorSignatures, FundingInput, NegotiationFields,
17};
18
19#[derive(Clone, Debug, PartialEq)]
23#[cfg_attr(
24 feature = "use-serde",
25 derive(serde::Serialize, serde::Deserialize),
26 serde(rename_all = "camelCase")
27)]
28pub struct OfferChannel {
29 pub protocol_version: u32,
31 pub contract_flags: u8,
33 #[cfg_attr(
35 feature = "use-serde",
36 serde(
37 serialize_with = "crate::serde_utils::serialize_hex",
38 deserialize_with = "crate::serde_utils::deserialize_hex_array"
39 )
40 )]
41 pub chain_hash: [u8; 32],
42 pub temporary_contract_id: [u8; 32],
45 pub temporary_channel_id: [u8; 32],
48 pub contract_info: ContractInfo,
50 pub funding_pubkey: PublicKey,
52 pub revocation_basepoint: PublicKey,
54 pub publish_basepoint: PublicKey,
57 pub own_basepoint: PublicKey,
60 pub first_per_update_point: PublicKey,
62 pub payout_spk: ScriptBuf,
64 pub payout_serial_id: u64,
66 pub offer_collateral: Amount,
68 pub funding_inputs: Vec<FundingInput>,
70 pub change_spk: ScriptBuf,
72 pub change_serial_id: u64,
74 pub fund_output_serial_id: u64,
76 pub fee_rate_per_vb: u64,
78 pub cet_locktime: u32,
80 pub refund_locktime: u32,
82 pub cet_nsequence: u32,
84}
85
86impl_dlc_writeable!(OfferChannel, OFFER_CHANNEL_TYPE, {
87 (protocol_version, writeable),
88 (contract_flags, writeable),
89 (chain_hash, writeable),
90 (temporary_contract_id, writeable),
91 (temporary_channel_id, writeable),
92 (contract_info, writeable),
93 (funding_pubkey, writeable),
94 (revocation_basepoint, writeable),
95 (publish_basepoint, writeable),
96 (own_basepoint, writeable),
97 (first_per_update_point, writeable),
98 (payout_spk, writeable),
99 (payout_serial_id, writeable),
100 (offer_collateral, writeable),
101 (funding_inputs, vec),
102 (change_spk, writeable),
103 (change_serial_id, writeable),
104 (fund_output_serial_id, writeable),
105 (fee_rate_per_vb, writeable),
106 (cet_locktime, writeable),
107 (refund_locktime, writeable),
108 (cet_nsequence, writeable)
109});
110
111impl OfferChannel {
112 pub fn validate<C: Verification>(
114 &self,
115 secp: &Secp256k1<C>,
116 min_timeout_interval: u32,
117 max_timeout_interval: u32,
118 min_cet_nsequence: u32,
119 max_cet_nsequence: u32,
120 ) -> Result<(), Error> {
121 let closest_maturity_date = self.contract_info.get_closest_maturity_date();
122 let valid_dates = self.cet_locktime <= closest_maturity_date
123 && closest_maturity_date + min_timeout_interval <= self.refund_locktime
124 && self.refund_locktime <= closest_maturity_date + max_timeout_interval
125 && self.cet_nsequence >= min_cet_nsequence
126 && self.cet_nsequence <= max_cet_nsequence;
127 if !valid_dates {
128 return Err(Error::InvalidArgument(
129 "Locktime is less than closest maturity date".to_string(),
130 ));
131 }
132
133 match &self.contract_info {
134 ContractInfo::SingleContractInfo(s) => s.contract_info.oracle_info.validate(secp)?,
135 ContractInfo::DisjointContractInfo(d) => {
136 for c in &d.contract_infos {
137 c.oracle_info.validate(secp)?;
138 }
139 }
140 }
141
142 Ok(())
143 }
144}
145
146#[derive(Clone, Debug, PartialEq, Eq)]
151#[cfg_attr(
152 feature = "use-serde",
153 derive(serde::Serialize, serde::Deserialize),
154 serde(rename_all = "camelCase")
155)]
156pub struct AcceptChannel {
157 #[cfg_attr(
158 feature = "use-serde",
159 serde(
160 serialize_with = "crate::serde_utils::serialize_hex",
161 deserialize_with = "crate::serde_utils::deserialize_hex_array"
162 )
163 )]
164 pub temporary_channel_id: [u8; 32],
166 pub accept_collateral: Amount,
168 pub funding_pubkey: PublicKey,
170 pub revocation_basepoint: PublicKey,
172 pub publish_basepoint: PublicKey,
174 pub own_basepoint: PublicKey,
176 pub first_per_update_point: PublicKey,
178 pub payout_spk: ScriptBuf,
180 pub payout_serial_id: u64,
182 pub funding_inputs: Vec<FundingInput>,
184 pub change_spk: ScriptBuf,
186 pub change_serial_id: u64,
188 pub cet_adaptor_signatures: CetAdaptorSignatures,
190 pub buffer_adaptor_signature: EcdsaAdaptorSignature,
193 pub refund_signature: Signature,
195 pub negotiation_fields: Option<NegotiationFields>,
197}
198
199impl_dlc_writeable!(AcceptChannel, ACCEPT_CHANNEL_TYPE, {
200 (temporary_channel_id, writeable),
201 (accept_collateral, writeable),
202 (funding_pubkey, writeable),
203 (revocation_basepoint, writeable),
204 (publish_basepoint, writeable),
205 (own_basepoint, writeable),
206 (first_per_update_point, writeable),
207 (payout_spk, writeable),
208 (payout_serial_id, writeable),
209 (funding_inputs, vec),
210 (change_spk, writeable),
211 (change_serial_id, writeable),
212 (cet_adaptor_signatures, writeable),
213 (buffer_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature}),
214 (refund_signature, writeable),
215 (negotiation_fields, option)
216});
217
218#[derive(Clone, Debug, PartialEq, Eq)]
219#[cfg_attr(
220 feature = "use-serde",
221 derive(serde::Serialize, serde::Deserialize),
222 serde(rename_all = "camelCase")
223)]
224pub struct SignChannel {
226 #[cfg_attr(
227 feature = "use-serde",
228 serde(
229 serialize_with = "crate::serde_utils::serialize_hex",
230 deserialize_with = "crate::serde_utils::deserialize_hex_array"
231 )
232 )]
233 pub channel_id: [u8; 32],
235 pub cet_adaptor_signatures: CetAdaptorSignatures,
237 pub buffer_adaptor_signature: EcdsaAdaptorSignature,
240 pub refund_signature: Signature,
242 pub funding_signatures: FundingSignatures,
244}
245
246impl_dlc_writeable!(SignChannel, SIGN_CHANNEL_TYPE, {
247 (channel_id, writeable),
248 (cet_adaptor_signatures, writeable),
249 (buffer_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature}),
250 (refund_signature, writeable),
251 (funding_signatures, writeable)
252});
253
254#[derive(Clone, Debug, PartialEq, Eq)]
255#[cfg_attr(
256 feature = "use-serde",
257 derive(serde::Serialize, serde::Deserialize),
258 serde(rename_all = "camelCase")
259)]
260pub struct SettleOffer {
262 #[cfg_attr(
263 feature = "use-serde",
264 serde(
265 serialize_with = "crate::serde_utils::serialize_hex",
266 deserialize_with = "crate::serde_utils::deserialize_hex_array"
267 )
268 )]
269 pub channel_id: [u8; 32],
271 pub counter_payout: Amount,
273 pub next_per_update_point: PublicKey,
276}
277
278impl_dlc_writeable!(SettleOffer, SETTLE_CHANNEL_OFFER_TYPE, {
279 (channel_id, writeable),
280 (counter_payout, writeable),
281 (next_per_update_point, writeable)
282});
283
284#[derive(Clone, Debug, PartialEq, Eq)]
285#[cfg_attr(
286 feature = "use-serde",
287 derive(serde::Serialize, serde::Deserialize),
288 serde(rename_all = "camelCase")
289)]
290pub struct SettleAccept {
292 #[cfg_attr(
293 feature = "use-serde",
294 serde(
295 serialize_with = "crate::serde_utils::serialize_hex",
296 deserialize_with = "crate::serde_utils::deserialize_hex_array"
297 )
298 )]
299 pub channel_id: [u8; 32],
301 pub next_per_update_point: PublicKey,
304 pub settle_adaptor_signature: EcdsaAdaptorSignature,
307}
308
309impl_dlc_writeable!(SettleAccept, SETTLE_CHANNEL_ACCEPT_TYPE, {
310 (channel_id, writeable),
311 (next_per_update_point, writeable),
312 (settle_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature})
313});
314
315#[derive(Clone, Debug, PartialEq, Eq)]
316#[cfg_attr(
317 feature = "use-serde",
318 derive(serde::Serialize, serde::Deserialize),
319 serde(rename_all = "camelCase")
320)]
321pub struct SettleConfirm {
323 #[cfg_attr(
324 feature = "use-serde",
325 serde(
326 serialize_with = "crate::serde_utils::serialize_hex",
327 deserialize_with = "crate::serde_utils::deserialize_hex_array"
328 )
329 )]
330 pub channel_id: [u8; 32],
332 pub prev_per_update_secret: SecretKey,
335 pub settle_adaptor_signature: EcdsaAdaptorSignature,
338}
339
340impl_dlc_writeable!(SettleConfirm, SETTLE_CHANNEL_CONFIRM_TYPE, {
341 (channel_id, writeable),
342 (prev_per_update_secret, writeable),
343 (settle_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature})
344});
345
346#[derive(Clone, Debug, PartialEq, Eq)]
347#[cfg_attr(
348 feature = "use-serde",
349 derive(serde::Serialize, serde::Deserialize),
350 serde(rename_all = "camelCase")
351)]
352pub struct SettleFinalize {
354 #[cfg_attr(
355 feature = "use-serde",
356 serde(
357 serialize_with = "crate::serde_utils::serialize_hex",
358 deserialize_with = "crate::serde_utils::deserialize_hex_array"
359 )
360 )]
361 pub channel_id: [u8; 32],
363 pub prev_per_update_secret: SecretKey,
366}
367
368impl_dlc_writeable!(SettleFinalize, SETTLE_CHANNEL_FINALIZE_TYPE, {
369 (channel_id, writeable),
370 (prev_per_update_secret, writeable)
371});
372
373#[derive(Clone, Debug, PartialEq)]
374#[cfg_attr(
375 feature = "use-serde",
376 derive(serde::Serialize, serde::Deserialize),
377 serde(rename_all = "camelCase")
378)]
379pub struct RenewOffer {
381 #[cfg_attr(
382 feature = "use-serde",
383 serde(
384 serialize_with = "crate::serde_utils::serialize_hex",
385 deserialize_with = "crate::serde_utils::deserialize_hex_array"
386 )
387 )]
388 pub channel_id: [u8; 32],
390 pub temporary_contract_id: [u8; 32],
392 pub counter_payout: Amount,
395 pub next_per_update_point: PublicKey,
398 pub contract_info: ContractInfo,
400 pub cet_locktime: u32,
402 pub refund_locktime: u32,
404 pub cet_nsequence: u32,
406}
407
408impl_dlc_writeable!(RenewOffer, RENEW_CHANNEL_OFFER_TYPE, {
409 (channel_id, writeable),
410 (temporary_contract_id, writeable),
411 (counter_payout, writeable),
412 (next_per_update_point, writeable),
413 (contract_info, writeable),
414 (cet_locktime, writeable),
415 (refund_locktime, writeable),
416 (cet_nsequence, writeable)
417});
418
419#[derive(Clone, Debug, PartialEq, Eq)]
420#[cfg_attr(
421 feature = "use-serde",
422 derive(serde::Serialize, serde::Deserialize),
423 serde(rename_all = "camelCase")
424)]
425pub struct RenewAccept {
427 #[cfg_attr(
428 feature = "use-serde",
429 serde(
430 serialize_with = "crate::serde_utils::serialize_hex",
431 deserialize_with = "crate::serde_utils::deserialize_hex_array"
432 )
433 )]
434 pub channel_id: [u8; 32],
436 pub next_per_update_point: PublicKey,
439 pub cet_adaptor_signatures: CetAdaptorSignatures,
441 pub refund_signature: Signature,
443}
444
445impl_dlc_writeable!(RenewAccept, RENEW_CHANNEL_ACCEPT_TYPE, {
446 (channel_id, writeable),
447 (next_per_update_point, writeable),
448 (cet_adaptor_signatures, writeable),
449 (refund_signature, writeable)
450});
451
452#[derive(Clone, Debug, PartialEq, Eq)]
453#[cfg_attr(
454 feature = "use-serde",
455 derive(serde::Serialize, serde::Deserialize),
456 serde(rename_all = "camelCase")
457)]
458pub struct RenewConfirm {
460 #[cfg_attr(
461 feature = "use-serde",
462 serde(
463 serialize_with = "crate::serde_utils::serialize_hex",
464 deserialize_with = "crate::serde_utils::deserialize_hex_array"
465 )
466 )]
467 pub channel_id: [u8; 32],
469 pub buffer_adaptor_signature: EcdsaAdaptorSignature,
472 pub cet_adaptor_signatures: CetAdaptorSignatures,
474 pub refund_signature: Signature,
476}
477
478impl_dlc_writeable!(RenewConfirm, RENEW_CHANNEL_CONFIRM_TYPE, {
479 (channel_id, writeable),
480 (buffer_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature}),
481 (cet_adaptor_signatures, writeable),
482 (refund_signature, writeable)
483});
484
485#[derive(Clone, Debug, PartialEq, Eq)]
486#[cfg_attr(
487 feature = "use-serde",
488 derive(serde::Serialize, serde::Deserialize),
489 serde(rename_all = "camelCase")
490)]
491pub struct RenewFinalize {
493 #[cfg_attr(
494 feature = "use-serde",
495 serde(
496 serialize_with = "crate::serde_utils::serialize_hex",
497 deserialize_with = "crate::serde_utils::deserialize_hex_array"
498 )
499 )]
500 pub channel_id: [u8; 32],
502 pub per_update_secret: SecretKey,
505 pub buffer_adaptor_signature: EcdsaAdaptorSignature,
508}
509
510impl_dlc_writeable!(RenewFinalize, RENEW_CHANNEL_FINALIZE_TYPE, {
511 (channel_id, writeable),
512 (per_update_secret, writeable),
513 (buffer_adaptor_signature, {cb_writeable, write_ecdsa_adaptor_signature, read_ecdsa_adaptor_signature})
514
515});
516
517#[derive(Clone, Debug, PartialEq, Eq)]
518#[cfg_attr(
519 feature = "serde",
520 derive(serde::Serialize, serde::Deserialize),
521 serde(rename_all = "camelCase")
522)]
523pub struct RenewRevoke {
525 #[cfg_attr(
526 feature = "serde",
527 serde(
528 serialize_with = "crate::serde_utils::serialize_hex",
529 deserialize_with = "crate::serde_utils::deserialize_hex_array"
530 )
531 )]
532 pub channel_id: [u8; 32],
534 pub per_update_secret: SecretKey,
537}
538
539impl_dlc_writeable!(RenewRevoke, RENEW_CHANNEL_REVOKE_TYPE, {
540 (channel_id, writeable),
541 (per_update_secret, writeable)
542});
543
544#[derive(Clone, Debug, PartialEq, Eq)]
545#[cfg_attr(
546 feature = "use-serde",
547 derive(serde::Serialize, serde::Deserialize),
548 serde(rename_all = "camelCase")
549)]
550pub struct CollaborativeCloseOffer {
552 #[cfg_attr(
553 feature = "use-serde",
554 serde(
555 serialize_with = "crate::serde_utils::serialize_hex",
556 deserialize_with = "crate::serde_utils::deserialize_hex_array"
557 )
558 )]
559 pub channel_id: [u8; 32],
561 pub counter_payout: Amount,
563 pub close_signature: Signature,
565}
566
567impl_dlc_writeable!(CollaborativeCloseOffer, COLLABORATIVE_CLOSE_OFFER_TYPE, {
568 (channel_id, writeable),
569 (counter_payout, writeable),
570 (close_signature, writeable)
571});
572
573#[derive(Clone, Debug, PartialEq, Eq)]
574#[cfg_attr(
575 feature = "use-serde",
576 derive(serde::Serialize, serde::Deserialize),
577 serde(rename_all = "camelCase")
578)]
579pub struct Reject {
581 #[cfg_attr(
582 feature = "use-serde",
583 serde(
584 serialize_with = "crate::serde_utils::serialize_hex",
585 deserialize_with = "crate::serde_utils::deserialize_hex_array"
586 )
587 )]
588 pub channel_id: [u8; 32],
590}
591
592impl_dlc_writeable!(Reject, REJECT, { (channel_id, writeable) });