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