1use std::any::Any;
2use std::io::Read;
3
4use delegate::delegate;
5
6use crate::HTLCDescriptor;
7use bitcoin::bech32::u5;
8use bitcoin::{secp256k1, Transaction, TxOut};
9use lightning::ln::chan_utils::{
10 ChannelPublicKeys, ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction,
11 HTLCOutputInCommitment, HolderCommitmentTransaction,
12};
13use lightning::ln::msgs::{DecodeError, UnsignedChannelAnnouncement, UnsignedGossipMessage};
14use lightning::ln::script::ShutdownScript;
15use lightning::ln::PaymentPreimage;
16use lightning::sign::ecdsa::EcdsaChannelSigner;
17use lightning::sign::ecdsa::WriteableEcdsaChannelSigner;
18use lightning::sign::ChannelSigner;
19use lightning::sign::InMemorySigner;
20use lightning::sign::{
21 KeyMaterial, NodeSigner, Recipient, SignerProvider, SpendableOutputDescriptor,
22};
23use lightning::util::ser::Readable;
24use lightning::util::ser::{Writeable, Writer};
25use lightning_signer::bitcoin::secp256k1::All;
26use lightning_signer::bitcoin::{self, ScriptBuf};
27use lightning_signer::lightning;
28use secp256k1::ecdsa::RecoverableSignature;
29use secp256k1::{ecdh::SharedSecret, ecdsa::Signature, PublicKey, Scalar, Secp256k1, SecretKey};
30
31use crate::bitcoin::Address;
32use lightning_signer::util::loopback::LoopbackChannelSigner;
33
34pub trait InnerSign: EcdsaChannelSigner + Send + Sync {
36 fn box_clone(&self) -> Box<dyn InnerSign>;
37 fn as_any(&self) -> &dyn Any;
38 fn vwrite(&self, writer: &mut Vec<u8>) -> Result<(), std::io::Error>;
39}
40
41pub struct DynSigner {
43 pub inner: Box<dyn InnerSign>,
44}
45
46impl DynSigner {
47 pub fn new<S: InnerSign + 'static>(inner: S) -> Self {
48 DynSigner { inner: Box::new(inner) }
49 }
50}
51
52impl WriteableEcdsaChannelSigner for DynSigner {}
53
54impl Clone for DynSigner {
55 fn clone(&self) -> Self {
56 DynSigner { inner: self.inner.box_clone() }
57 }
58}
59
60impl Readable for DynSigner {
62 fn read<R: Read>(_reader: &mut R) -> Result<Self, DecodeError> {
63 unimplemented!()
64 }
65}
66
67impl EcdsaChannelSigner for DynSigner {
68 delegate! {
69 to self.inner {
70 fn sign_counterparty_commitment(
71 &self,
72 commitment_tx: &CommitmentTransaction,
73 inbound_htlc_preimages: Vec<PaymentPreimage>,
74 outbound_htlc_preimages: Vec<PaymentPreimage>,
75 secp_ctx: &Secp256k1<secp256k1::All>,
76 ) -> Result<(Signature, Vec<Signature>), ()>;
77
78 fn sign_holder_commitment(
79 &self,
80 commitment_tx: &HolderCommitmentTransaction,
81 secp_ctx: &Secp256k1<secp256k1::All>,
82 ) -> Result<Signature, ()>;
83
84 fn unsafe_sign_holder_commitment(
85 &self,
86 commitment_tx: &HolderCommitmentTransaction,
87 secp_ctx: &Secp256k1<secp256k1::All>,
88 ) -> Result<Signature, ()>;
89
90 fn sign_justice_revoked_output(
91 &self,
92 justice_tx: &Transaction,
93 input: usize,
94 amount: u64,
95 per_commitment_key: &SecretKey,
96 secp_ctx: &Secp256k1<secp256k1::All>,
97 ) -> Result<Signature, ()>;
98
99 fn sign_justice_revoked_htlc(
100 &self,
101 justice_tx: &Transaction,
102 input: usize,
103 amount: u64,
104 per_commitment_key: &SecretKey,
105 htlc: &HTLCOutputInCommitment,
106 secp_ctx: &Secp256k1<secp256k1::All>,
107 ) -> Result<Signature, ()>;
108
109 fn sign_counterparty_htlc_transaction(
110 &self,
111 htlc_tx: &Transaction,
112 input: usize,
113 amount: u64,
114 per_commitment_point: &PublicKey,
115 htlc: &HTLCOutputInCommitment,
116 secp_ctx: &Secp256k1<secp256k1::All>,
117 ) -> Result<Signature, ()>;
118
119 fn sign_closing_transaction(
120 &self,
121 closing_tx: &ClosingTransaction,
122 secp_ctx: &Secp256k1<secp256k1::All>,
123 ) -> Result<Signature, ()>;
124
125 fn sign_channel_announcement_with_funding_key(
126 &self,
127 msg: &UnsignedChannelAnnouncement,
128 secp_ctx: &Secp256k1<secp256k1::All>,
129 ) -> Result<Signature, ()>;
130
131 fn sign_holder_anchor_input(
132 &self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1<secp256k1::All>,
133 ) -> Result<Signature, ()>;
134
135 fn sign_holder_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, htlc_descriptor: &HTLCDescriptor, secp_ctx: &Secp256k1<All>) -> Result<Signature, ()>;
136 }
137 }
138}
139
140impl ChannelSigner for DynSigner {
141 delegate! {
142 to self.inner {
143 fn validate_counterparty_revocation(&self, idx: u64, sk: &SecretKey) -> Result<(), ()>;
144
145 fn get_per_commitment_point(
146 &self,
147 idx: u64,
148 secp_ctx: &Secp256k1<secp256k1::All>,
149 ) -> PublicKey;
150
151 fn release_commitment_secret(&self, idx: u64) -> [u8; 32];
152
153 fn validate_holder_commitment(
154 &self,
155 holder_tx: &HolderCommitmentTransaction,
156 preimages: Vec<PaymentPreimage>,
157 ) -> Result<(), ()>;
158
159 fn pubkeys(&self) -> &ChannelPublicKeys;
160
161 fn channel_keys_id(&self) -> [u8; 32];
162
163 fn provide_channel_parameters(&mut self, channel_parameters: &ChannelTransactionParameters);
164 }
165 }
166}
167
168impl Writeable for DynSigner {
169 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), std::io::Error> {
170 let inner = self.inner.as_ref();
171 let mut buf = Vec::new();
172 inner.vwrite(&mut buf)?;
173 writer.write_all(&buf)
174 }
175}
176
177impl InnerSign for InMemorySigner {
178 fn box_clone(&self) -> Box<dyn InnerSign> {
179 Box::new(self.clone())
180 }
181
182 fn as_any(&self) -> &dyn Any {
183 self
184 }
185
186 fn vwrite(&self, writer: &mut Vec<u8>) -> Result<(), std::io::Error> {
187 self.write(writer)
188 }
189}
190
191impl InnerSign for LoopbackChannelSigner {
192 fn box_clone(&self) -> Box<dyn InnerSign> {
193 Box::new(self.clone())
194 }
195
196 fn as_any(&self) -> &dyn Any {
197 self
198 }
199
200 fn vwrite(&self, writer: &mut Vec<u8>) -> Result<(), std::io::Error> {
201 self.write(writer)
202 }
203}
204
205pub struct DynKeysInterface {
206 pub inner: Box<dyn SpendableKeysInterface<EcdsaSigner = DynSigner>>,
207}
208
209impl DynKeysInterface {
210 pub fn new(inner: Box<dyn SpendableKeysInterface<EcdsaSigner = DynSigner>>) -> Self {
211 DynKeysInterface { inner }
212 }
213}
214
215impl NodeSigner for DynKeysInterface {
216 delegate! {
217 to self.inner {
218 fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()>;
219 fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()>;
220 fn ecdh(&self, recipient: Recipient, other_key: &PublicKey, tweak: Option<&Scalar>) -> Result<SharedSecret, ()>;
221
222 fn sign_invoice(
223 &self,
224 hrp_bytes: &[u8],
225 invoice_data: &[u5],
226 recipient: Recipient,
227 ) -> Result<RecoverableSignature, ()>;
228
229 fn sign_bolt12_invoice(
230 &self, invoice: &lightning::offers::invoice::UnsignedBolt12Invoice
231 ) -> Result<bitcoin::secp256k1::schnorr::Signature, ()>;
232
233 fn sign_bolt12_invoice_request(
234 &self, invoice_request: &lightning::offers::invoice_request::UnsignedInvoiceRequest
235 ) -> Result<bitcoin::secp256k1::schnorr::Signature, ()>;
236
237 fn get_inbound_payment_key_material(&self) -> KeyMaterial;
238 }
239 }
240}
241
242impl SignerProvider for DynKeysInterface {
243 type EcdsaSigner = DynSigner;
244
245 delegate! {
246 to self.inner {
247 fn get_destination_script(&self, buf: [u8; 32]) -> Result<ScriptBuf, ()>;
248
249 fn get_shutdown_scriptpubkey(&self) -> Result<ShutdownScript, ()>;
250
251 fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32];
252
253 fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::EcdsaSigner;
254
255 fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::EcdsaSigner, DecodeError>;
256 }
257 }
258}
259
260pub trait SpendableKeysInterface: NodeSigner + SignerProvider + Send + Sync {
262 fn spend_spendable_outputs(
263 &self,
264 descriptors: &[&SpendableOutputDescriptor],
265 outputs: Vec<TxOut>,
266 change_destination_script: ScriptBuf,
267 feerate_sat_per_1000_weight: u32,
268 secp_ctx: &Secp256k1<All>,
269 ) -> anyhow::Result<Transaction>;
270
271 fn get_sweep_address(&self) -> Address;
274}
275
276impl SpendableKeysInterface for DynKeysInterface {
277 delegate! {
278 to self.inner {
279 fn spend_spendable_outputs(
280 &self,
281 descriptors: &[&SpendableOutputDescriptor],
282 outputs: Vec<TxOut>,
283 change_destination_script: ScriptBuf,
284 feerate_sat_per_1000_weight: u32,
285 secp_ctx: &Secp256k1<All>,
286 ) -> anyhow::Result<Transaction>;
287
288 fn get_sweep_address(&self) -> Address;
289 }
290 }
291}