1use std::collections::BTreeMap;
15
16use amplify::DumbDefault;
17#[cfg(feature = "serde")]
18use amplify::ToYamlString;
19use bitcoin::util::bip32::{ChildNumber, ExtendedPrivKey, KeySource};
20use bitcoin_scripts::PubkeyScript;
21use p2p::bolt::{AcceptChannel, ChannelType, OpenChannel};
22use secp256k1::{PublicKey, Secp256k1};
23use wallet::hd::HardenedIndex;
24
25#[derive(Clone, PartialEq, Eq, Debug, StrictEncode, StrictDecode)]
27#[cfg_attr(
28 feature = "serde",
29 derive(Display, Serialize, Deserialize),
30 serde(crate = "serde_crate"),
31 display(LocalPubkey::to_yaml_string)
32)]
33pub struct LocalPubkey {
34 pub key: PublicKey,
35 pub source: KeySource,
36}
37
38impl LocalPubkey {
39 #[inline]
40 pub fn to_bip32_derivation_map(&self) -> BTreeMap<PublicKey, KeySource> {
41 bmap! { self.key => self.source.clone() }
42 }
43
44 #[inline]
45 pub fn to_bitcoin_pk(&self) -> bitcoin::PublicKey {
46 bitcoin::PublicKey::new(self.key)
47 }
48}
49
50#[derive(Clone, PartialEq, Eq, Debug, StrictEncode, StrictDecode)]
53#[cfg_attr(
54 feature = "serde",
55 derive(Display, Serialize, Deserialize),
56 serde(crate = "serde_crate"),
57 display(LocalKeyset::to_yaml_string)
58)]
59pub struct LocalKeyset {
60 pub funding_pubkey: LocalPubkey,
62 pub revocation_basepoint: LocalPubkey,
64 pub payment_basepoint: LocalPubkey,
66 pub delayed_payment_basepoint: LocalPubkey,
68 pub htlc_basepoint: LocalPubkey,
70 pub first_per_commitment_point: LocalPubkey,
72 pub shutdown_scriptpubkey: Option<PubkeyScript>,
76 pub static_remotekey: bool,
80}
81
82#[derive(Clone, PartialEq, Eq, Debug, StrictEncode, StrictDecode)]
85#[cfg_attr(
86 feature = "serde",
87 derive(Display, Serialize, Deserialize),
88 serde(crate = "serde_crate"),
89 display(RemoteKeyset::to_yaml_string)
90)]
91pub struct RemoteKeyset {
92 pub funding_pubkey: PublicKey,
94 pub revocation_basepoint: PublicKey,
96 pub payment_basepoint: PublicKey,
98 pub delayed_payment_basepoint: PublicKey,
100 pub htlc_basepoint: PublicKey,
102 pub first_per_commitment_point: PublicKey,
104 pub shutdown_scriptpubkey: Option<PubkeyScript>,
108 pub static_remotekey: bool,
112}
113
114#[cfg(feature = "serde")]
115impl ToYamlString for LocalPubkey {}
116
117#[cfg(feature = "serde")]
118impl ToYamlString for LocalKeyset {}
119
120#[cfg(feature = "serde")]
121impl ToYamlString for RemoteKeyset {}
122
123impl From<&OpenChannel> for RemoteKeyset {
124 fn from(open_channel: &OpenChannel) -> Self {
125 Self {
126 funding_pubkey: open_channel.funding_pubkey,
127 revocation_basepoint: open_channel.revocation_basepoint,
128 payment_basepoint: open_channel.payment_point,
129 delayed_payment_basepoint: open_channel.delayed_payment_basepoint,
130 htlc_basepoint: open_channel.htlc_basepoint,
131 first_per_commitment_point: open_channel.first_per_commitment_point,
132 shutdown_scriptpubkey: open_channel.shutdown_scriptpubkey.clone(),
133 static_remotekey: false,
134 }
135 }
136}
137
138impl From<&AcceptChannel> for RemoteKeyset {
139 fn from(accept_channel: &AcceptChannel) -> Self {
140 Self {
141 funding_pubkey: accept_channel.funding_pubkey,
142 revocation_basepoint: accept_channel.revocation_basepoint,
143 payment_basepoint: accept_channel.payment_point,
144 delayed_payment_basepoint: accept_channel.delayed_payment_basepoint,
145 htlc_basepoint: accept_channel.htlc_basepoint,
146 first_per_commitment_point: accept_channel
147 .first_per_commitment_point,
148 shutdown_scriptpubkey: accept_channel.shutdown_scriptpubkey.clone(),
149 static_remotekey: accept_channel
150 .channel_type
151 .map(ChannelType::has_static_remotekey)
152 .unwrap_or_default(),
153 }
154 }
155}
156
157impl DumbDefault for LocalPubkey {
158 fn dumb_default() -> Self {
159 LocalPubkey {
160 key: dumb_pubkey!(),
161 source: KeySource::default(),
162 }
163 }
164}
165
166impl DumbDefault for LocalKeyset {
167 fn dumb_default() -> Self {
168 Self {
169 funding_pubkey: DumbDefault::dumb_default(),
170 revocation_basepoint: DumbDefault::dumb_default(),
171 payment_basepoint: DumbDefault::dumb_default(),
172 delayed_payment_basepoint: DumbDefault::dumb_default(),
173 htlc_basepoint: DumbDefault::dumb_default(),
174 first_per_commitment_point: DumbDefault::dumb_default(),
175 shutdown_scriptpubkey: None,
176 static_remotekey: false,
177 }
178 }
179}
180
181impl DumbDefault for RemoteKeyset {
182 fn dumb_default() -> Self {
183 Self {
184 funding_pubkey: dumb_pubkey!(),
185 revocation_basepoint: dumb_pubkey!(),
186 payment_basepoint: dumb_pubkey!(),
187 delayed_payment_basepoint: dumb_pubkey!(),
188 htlc_basepoint: dumb_pubkey!(),
189 first_per_commitment_point: dumb_pubkey!(),
190 shutdown_scriptpubkey: None,
191 static_remotekey: false,
192 }
193 }
194}
195
196impl LocalKeyset {
197 pub fn with<C: secp256k1::Signing>(
199 secp: &Secp256k1<C>,
200 channel_source: KeySource,
201 channel_xpriv: ExtendedPrivKey,
202 shutdown_scriptpubkey: Option<PubkeyScript>,
203 ) -> Self {
204 let fingerpint = channel_source.0;
205
206 let keys = (0u16..=6)
207 .into_iter()
208 .map(HardenedIndex::from)
209 .map(ChildNumber::from)
210 .map(|index| [index])
211 .map(|path| {
212 let derivation_path = channel_source.1.clone().extend(path);
213 let seckey = channel_xpriv
214 .derive_priv(secp, &path)
215 .expect("negligible probability")
216 .private_key;
217 LocalPubkey {
218 key: PublicKey::from_secret_key(secp, &seckey),
219 source: (fingerpint, derivation_path),
220 }
221 })
222 .collect::<Vec<_>>();
223
224 Self {
225 funding_pubkey: keys[0].clone(),
226 revocation_basepoint: keys[3].clone(),
227 payment_basepoint: keys[1].clone(),
228 delayed_payment_basepoint: keys[2].clone(),
229 htlc_basepoint: keys[5].clone(),
230 first_per_commitment_point: keys[4].clone(),
231 shutdown_scriptpubkey,
232 static_remotekey: false,
233 }
234 }
235}