1use alloc::format;
2use bitcoin::consensus::{Decodable, Encodable};
3use bitcoin::Txid;
4use bitcoin_consensus_derive::{Decodable, Encodable};
5use core::fmt::{self, Debug, Formatter};
6use lightning_signer::lightning;
7use lightning_signer::lightning::io::{self, Read, Write};
8use lightning_signer::lightning::ln::channel_keys::{
9 DelayedPaymentBasepoint, HtlcBasepoint, RevocationBasepoint,
10};
11use lightning_signer::lightning::ln::msgs::DecodeError;
12use lightning_signer::lightning::util::ser::{Readable, Writeable, Writer};
13use serde_bolt::bitcoin;
14use serde_bolt::bitcoin::consensus::encode::Error as BitcoinError;
15use serde_bolt::Octets;
16use txoo::bitcoin::secp256k1::PublicKey;
17
18macro_rules! secret_array_impl {
19 ($ty:ident, $len:tt) => {
20 #[derive(Clone, Encodable, Decodable)]
21 pub struct $ty(pub [u8; $len]);
22
23 impl Debug for $ty {
24 #[cfg(feature = "log-secrets")]
25 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
26 write!(f, "{}", hex::encode(&self.0))
27 }
28 #[cfg(not(feature = "log-secrets"))]
29 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
30 write!(f, "******")
31 }
32 }
33 };
34}
35
36macro_rules! array_impl {
37 ($ty:ident, $len:tt) => {
38 #[derive(Clone, Encodable, Decodable)]
39 #[cfg_attr(test, derive(PartialEq))]
40 pub struct $ty(pub [u8; $len]);
41
42 impl Debug for $ty {
43 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
44 write!(f, "{}", hex::encode(&self.0))
45 }
46 }
47
48 impl Readable for $ty {
49 fn read<R: Read>(reader: &mut R) -> Result<Self, lightning::ln::msgs::DecodeError> {
50 Ok($ty::consensus_decode(reader)
51 .map_err(|_| lightning::ln::msgs::DecodeError::InvalidValue)?)
52 }
53 }
54
55 impl Writeable for $ty {
56 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
57 self.consensus_encode(&mut LdkWriterWriteAdaptor(writer)).map_err(|_e| {
58 io::Error::new(io::ErrorKind::Other, "Error during consensus encoding")
59 })?;
60 Ok(())
61 }
62 }
63 };
64}
65
66pub struct LdkWriterWriteAdaptor<'a, W: Writer + 'a>(pub &'a mut W);
69impl<'a, W: Writer + 'a> Write for LdkWriterWriteAdaptor<'a, W> {
70 #[inline]
71 fn write_all(&mut self, buf: &[u8]) -> Result<(), io::Error> {
72 self.0.write_all(buf)
73 }
74 #[inline]
75 fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> {
76 self.0.write_all(buf)?;
77 Ok(buf.len())
78 }
79 #[inline]
80 fn flush(&mut self) -> Result<(), io::Error> {
81 Ok(())
82 }
83}
84
85pub struct SerBoltTlvWriteWrap<T: Encodable>(pub T);
87
88impl<T: Encodable> Writeable for SerBoltTlvWriteWrap<T> {
89 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), io::Error> {
90 self.0.consensus_encode(&mut LdkWriterWriteAdaptor(writer)).map_err(|_e| {
91 io::Error::new(io::ErrorKind::Other, "Error during consensus encoding")
92 })?;
93 Ok(())
94 }
95}
96
97impl<T: Encodable> From<T> for SerBoltTlvWriteWrap<T> {
98 fn from(t: T) -> Self {
99 SerBoltTlvWriteWrap(t)
100 }
101}
102
103pub struct SerBoltTlvReadWrap<T: Decodable>(pub T);
104
105impl<T: Decodable> Decodable for SerBoltTlvReadWrap<T> {
106 fn consensus_decode<D: Read + ?Sized>(d: &mut D) -> Result<Self, BitcoinError> {
107 T::consensus_decode(d).map(|t| SerBoltTlvReadWrap(t))
108 }
109}
110
111impl<T: Decodable> Readable for SerBoltTlvReadWrap<T> {
112 fn read<R: io::Read>(reader: &mut R) -> Result<Self, DecodeError> {
113 Ok(SerBoltTlvReadWrap::<T>::consensus_decode(reader)
114 .map_err(|_| lightning::ln::msgs::DecodeError::InvalidValue)?)
115 }
116}
117
118#[derive(Encodable, Decodable)]
119pub struct Bip32KeyVersion {
120 pub pubkey_version: u32,
121 pub privkey_version: u32,
122}
123
124impl Debug for Bip32KeyVersion {
125 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
126 f.debug_struct("Bip32KeyVersion")
127 .field("pubkey_version", &format!("0x{:x?}", self.pubkey_version))
128 .field("privkey_version", &format!("0x{:x?}", self.privkey_version))
129 .finish()
130 }
131}
132
133secret_array_impl!(Secret, 32);
135
136array_impl!(DisclosedSecret, 32);
139
140array_impl!(DevSecret, 32);
142
143array_impl!(DevPrivKey, 32);
145
146array_impl!(PubKey32, 32);
147
148array_impl!(PubKey, 33);
149
150array_impl!(ExtKey, 78);
151
152array_impl!(Sha256, 32);
153
154#[derive(Debug, Encodable, Decodable)]
155pub struct Basepoints {
156 pub revocation: PubKey,
157 pub payment: PubKey,
158 pub htlc: PubKey,
159 pub delayed_payment: PubKey,
160}
161
162impl Into<RevocationBasepoint> for PubKey {
163 fn into(self) -> RevocationBasepoint {
164 RevocationBasepoint(self.into())
165 }
166}
167
168impl Into<HtlcBasepoint> for PubKey {
169 fn into(self) -> HtlcBasepoint {
170 HtlcBasepoint(self.into())
171 }
172}
173
174impl Into<DelayedPaymentBasepoint> for PubKey {
175 fn into(self) -> DelayedPaymentBasepoint {
176 DelayedPaymentBasepoint(self.into())
177 }
178}
179
180impl Into<PublicKey> for PubKey {
181 fn into(self) -> PublicKey {
182 PublicKey::from_slice(&self.0).expect("PublicKey::from_slice")
183 }
184}
185
186array_impl!(Signature, 64);
187array_impl!(RecoverableSignature, 65);
188
189array_impl!(OnionRoutingPacket, 1366);
190
191#[derive(Debug, Encodable, Decodable)]
192pub struct FailedHtlc {
193 pub id: u64,
194}
195
196#[derive(Debug, Encodable, Decodable)]
197pub struct BitcoinSignature {
198 pub signature: Signature,
199 pub sighash: u8,
200}
201
202#[derive(Debug, Encodable, Decodable)]
203pub struct Htlc {
204 pub side: u8, pub amount: u64,
206 pub payment_hash: Sha256,
207 pub ctlv_expiry: u32,
208}
209
210impl Htlc {
211 pub const LOCAL: u8 = 0;
212 pub const REMOTE: u8 = 1;
213}
214
215#[derive(Debug, Encodable, Decodable)]
216pub struct CloseInfo {
217 pub channel_id: u64,
218 pub peer_id: PubKey,
219 pub commitment_point: Option<PubKey>,
220 pub is_anchors: bool,
222 pub csv: u32,
223}
224
225#[derive(Debug, Encodable, Decodable)]
226pub struct Utxo {
227 pub txid: Txid,
228 pub outnum: u32,
229 pub amount: u64,
230 pub keyindex: u32,
231 pub is_p2sh: bool,
232 pub script: Octets,
233 pub close_info: Option<CloseInfo>,
234 pub is_in_coinbase: bool,
235}
236
237#[cfg(test)]
238mod tests {
239 #[test]
240 fn debug_secret_test() {
241 let secret = super::Secret([0; 32]);
242 let debug = format!("{:?}", secret);
243 #[cfg(feature = "log-secrets")]
244 assert_eq!(debug, "0000000000000000000000000000000000000000000000000000000000000000");
245 #[cfg(not(feature = "log-secrets"))]
246 assert_eq!(debug, "******");
247 }
248}