1use std::any::Any;
2
3use delegate::delegate;
4
5use crate::bitcoin::Address;
6use crate::HTLCDescriptor;
7use bitcoin::{secp256k1, Transaction, TxOut};
8use lightning::ln::chan_utils::{
9 ChannelPublicKeys, ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction,
10 HTLCOutputInCommitment, HolderCommitmentTransaction,
11};
12use lightning::ln::msgs::{DecodeError, UnsignedChannelAnnouncement, UnsignedGossipMessage};
13use lightning::ln::script::ShutdownScript;
14use lightning::sign::ecdsa::EcdsaChannelSigner;
15use lightning::sign::ChannelSigner;
16use lightning::sign::InMemorySigner;
17use lightning::sign::{NodeSigner, Recipient, SignerProvider, SpendableOutputDescriptor};
18use lightning::types::payment::PaymentPreimage;
19use lightning::util::ser::Readable;
20use lightning::util::ser::{Writeable, Writer};
21use lightning_invoice::RawBolt11Invoice;
22use lightning_signer::bitcoin::secp256k1::All;
23use lightning_signer::bitcoin::{self, ScriptBuf};
24use lightning_signer::lightning;
25use lightning_signer::lightning::ln::inbound_payment::ExpandedKey;
26use lightning_signer::lightning_invoice;
27use lightning_signer::util::loopback::LoopbackChannelSigner;
28use secp256k1::ecdsa::RecoverableSignature;
29use secp256k1::{ecdh::SharedSecret, ecdsa::Signature, PublicKey, Scalar, Secp256k1, SecretKey};
30
31pub trait InnerSign: EcdsaChannelSigner + Send + Sync {
33 fn box_clone(&self) -> Box<dyn InnerSign>;
34 fn as_any(&self) -> &dyn Any;
35 fn vwrite(&self, writer: &mut Vec<u8>) -> Result<(), bitcoin::io::Error>;
36}
37
38pub struct DynSigner {
40 pub inner: Box<dyn InnerSign>,
41}
42
43impl DynSigner {
44 pub fn new<S: InnerSign + 'static>(inner: S) -> Self {
45 DynSigner { inner: Box::new(inner) }
46 }
47}
48
49impl Clone for DynSigner {
50 fn clone(&self) -> Self {
51 DynSigner { inner: self.inner.box_clone() }
52 }
53}
54
55impl Readable for DynSigner {
57 fn read<R: bitcoin::io::Read>(_reader: &mut R) -> Result<Self, DecodeError> {
58 unimplemented!()
59 }
60}
61
62impl EcdsaChannelSigner for DynSigner {
63 delegate! {
64 to self.inner {
65 fn sign_counterparty_commitment(
66 &self,
67 commitment_tx: &CommitmentTransaction,
68 inbound_htlc_preimages: Vec<PaymentPreimage>,
69 outbound_htlc_preimages: Vec<PaymentPreimage>,
70 secp_ctx: &Secp256k1<secp256k1::All>,
71 ) -> Result<(Signature, Vec<Signature>), ()>;
72
73 fn sign_holder_commitment(
74 &self,
75 commitment_tx: &HolderCommitmentTransaction,
76 secp_ctx: &Secp256k1<secp256k1::All>,
77 ) -> Result<Signature, ()>;
78
79 fn unsafe_sign_holder_commitment(
80 &self,
81 commitment_tx: &HolderCommitmentTransaction,
82 secp_ctx: &Secp256k1<secp256k1::All>,
83 ) -> Result<Signature, ()>;
84
85 fn sign_justice_revoked_output(
86 &self,
87 justice_tx: &Transaction,
88 input: usize,
89 amount: u64,
90 per_commitment_key: &SecretKey,
91 secp_ctx: &Secp256k1<secp256k1::All>,
92 ) -> Result<Signature, ()>;
93
94 fn sign_justice_revoked_htlc(
95 &self,
96 justice_tx: &Transaction,
97 input: usize,
98 amount: u64,
99 per_commitment_key: &SecretKey,
100 htlc: &HTLCOutputInCommitment,
101 secp_ctx: &Secp256k1<secp256k1::All>,
102 ) -> Result<Signature, ()>;
103
104 fn sign_counterparty_htlc_transaction(
105 &self,
106 htlc_tx: &Transaction,
107 input: usize,
108 amount: u64,
109 per_commitment_point: &PublicKey,
110 htlc: &HTLCOutputInCommitment,
111 secp_ctx: &Secp256k1<secp256k1::All>,
112 ) -> Result<Signature, ()>;
113
114 fn sign_closing_transaction(
115 &self,
116 closing_tx: &ClosingTransaction,
117 secp_ctx: &Secp256k1<secp256k1::All>,
118 ) -> Result<Signature, ()>;
119
120 fn sign_channel_announcement_with_funding_key(
121 &self,
122 msg: &UnsignedChannelAnnouncement,
123 secp_ctx: &Secp256k1<secp256k1::All>,
124 ) -> Result<Signature, ()>;
125
126 fn sign_holder_anchor_input(
127 &self, anchor_tx: &Transaction, input: usize, secp_ctx: &Secp256k1<secp256k1::All>,
128 ) -> Result<Signature, ()>;
129
130 fn sign_holder_htlc_transaction(&self, htlc_tx: &Transaction, input: usize, htlc_descriptor: &HTLCDescriptor, secp_ctx: &Secp256k1<All>) -> Result<Signature, ()>;
131
132 fn sign_splicing_funding_input(
133 &self, tx: &Transaction, input_index: usize, input_value: u64,
134 secp_ctx: &Secp256k1<secp256k1::All>,
135 ) -> 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 ) -> Result<PublicKey, ()>;
150
151 fn release_commitment_secret(&self, idx: u64) -> Result<[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<(), bitcoin::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<(), bitcoin::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<(), bitcoin::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 invoice: &RawBolt11Invoice,
225 recipient: Recipient,
226 ) -> Result<RecoverableSignature, ()>;
227
228 fn sign_bolt12_invoice(
229 &self, invoice: &lightning::offers::invoice::UnsignedBolt12Invoice
230 ) -> Result<bitcoin::secp256k1::schnorr::Signature, ()>;
231
232 fn get_inbound_payment_key(&self) -> ExpandedKey;
233 }
234 }
235}
236
237impl SignerProvider for DynKeysInterface {
238 type EcdsaSigner = DynSigner;
239
240 delegate! {
241 to self.inner {
242 fn get_destination_script(&self, buf: [u8; 32]) -> Result<ScriptBuf, ()>;
243
244 fn get_shutdown_scriptpubkey(&self) -> Result<ShutdownScript, ()>;
245
246 fn generate_channel_keys_id(&self, _inbound: bool, _channel_value_satoshis: u64, _user_channel_id: u128) -> [u8; 32];
247
248 fn derive_channel_signer(&self, _channel_value_satoshis: u64, _channel_keys_id: [u8; 32]) -> Self::EcdsaSigner;
249
250 fn read_chan_signer(&self, reader: &[u8]) -> Result<Self::EcdsaSigner, DecodeError>;
251 }
252 }
253}
254
255pub trait SpendableKeysInterface: NodeSigner + SignerProvider + Send + Sync {
257 fn spend_spendable_outputs(
258 &self,
259 descriptors: &[&SpendableOutputDescriptor],
260 outputs: Vec<TxOut>,
261 change_destination_script: ScriptBuf,
262 feerate_sat_per_1000_weight: u32,
263 secp_ctx: &Secp256k1<All>,
264 ) -> anyhow::Result<Transaction>;
265
266 fn get_sweep_address(&self) -> Address;
269}
270
271impl SpendableKeysInterface for DynKeysInterface {
272 delegate! {
273 to self.inner {
274 fn spend_spendable_outputs(
275 &self,
276 descriptors: &[&SpendableOutputDescriptor],
277 outputs: Vec<TxOut>,
278 change_destination_script: ScriptBuf,
279 feerate_sat_per_1000_weight: u32,
280 secp_ctx: &Secp256k1<All>,
281 ) -> anyhow::Result<Transaction>;
282
283 fn get_sweep_address(&self) -> Address;
284 }
285 }
286}