1use std::any::Any;
2use std::convert::{TryFrom, TryInto};
3use std::sync::atomic::{AtomicU64, Ordering};
4use std::sync::Arc;
5
6use bitcoin::bip32::ChildNumber;
7use bitcoin::bip32::Xpub;
8use bitcoin::hashes::Hash;
9use bitcoin::psbt::Psbt;
10use bitcoin::secp256k1::ecdsa::{RecoverableSignature, RecoveryId};
11use bitcoin::secp256k1::rand::rngs::OsRng;
12use bitcoin::secp256k1::rand::RngCore;
13use bitcoin::secp256k1::{
14 ecdh::SharedSecret, ecdsa::Signature, All, PublicKey, Scalar, Secp256k1, SecretKey,
15};
16use bitcoin::WPubkeyHash;
17use bitcoin::{Transaction, TxOut};
18use lightning::ln::chan_utils::{
19 ChannelPublicKeys, ChannelTransactionParameters, ClosingTransaction, CommitmentTransaction,
20 HTLCOutputInCommitment, HolderCommitmentTransaction,
21};
22use lightning::ln::inbound_payment::ExpandedKey;
23use lightning::ln::msgs::DecodeError;
24use lightning::ln::msgs::UnsignedChannelAnnouncement;
25use lightning::ln::msgs::UnsignedGossipMessage;
26use lightning::ln::script::ShutdownScript;
27use lightning::sign::ecdsa::EcdsaChannelSigner;
28use lightning::sign::{ChannelSigner, NodeSigner};
29use lightning::sign::{EntropySource, SignerProvider};
30use lightning::sign::{Recipient, SpendableOutputDescriptor};
31use lightning::types::payment::PaymentPreimage;
32use lightning::util::ser::Readable;
33use lightning::util::ser::{Writeable, Writer};
34use lightning_signer::bitcoin::absolute::LockTime;
35use lightning_signer::bitcoin::sighash::EcdsaSighashType;
36use lightning_signer::bitcoin::{self, ScriptBuf, Witness};
37use lightning_signer::channel::{ChannelId, CommitmentType};
38use lightning_signer::lightning;
39use lightning_signer::lightning::sign::HTLCDescriptor;
40use lightning_signer::lightning::sign::OutputSpender;
41use lightning_signer::signer::derive::KeyDerivationStyle;
42use lightning_signer::util::transaction_utils::create_spending_transaction;
43use lightning_signer::util::INITIAL_COMMITMENT_NUMBER;
44use log::{debug, error};
45
46use vls_protocol::model::{
47 Basepoints, BitcoinSignature, CloseInfo, DisclosedSecret, Htlc, PubKey, Utxo,
48};
49use vls_protocol::msgs::{
50 DeBolt, Ecdh, EcdhReply, GetChannelBasepoints, GetChannelBasepointsReply,
51 GetPerCommitmentPoint, GetPerCommitmentPoint2, GetPerCommitmentPoint2Reply,
52 GetPerCommitmentPointReply, HsmdInit2, HsmdInit2Reply, NewChannel, NewChannelReply, SerBolt,
53 SetupChannel, SetupChannelReply, SignChannelAnnouncement, SignChannelAnnouncementReply,
54 SignCommitmentTxReply, SignCommitmentTxWithHtlcsReply, SignGossipMessage,
55 SignGossipMessageReply, SignInvoice, SignInvoiceReply, SignLocalCommitmentTx2,
56 SignLocalHtlcTx2, SignMutualCloseTx2, SignRemoteCommitmentTx2, SignTxReply, SignWithdrawal,
57 SignWithdrawalReply, ValidateCommitmentTx2, ValidateCommitmentTxReply, ValidateRevocation,
58 ValidateRevocationReply,
59};
60#[cfg(feature = "developer")]
61use vls_protocol::msgs::{HsmdDevPreinit, HsmdDevPreinitReply};
62use vls_protocol::serde_bolt::{Array, ArrayBE, Octets, WireString, WithSize};
63use vls_protocol::{model, Error as ProtocolError};
64use vls_protocol_signer::util::commitment_type_to_channel_type;
65
66mod dyn_signer;
67pub mod signer_port;
68
69pub use dyn_signer::{DynKeysInterface, DynSigner, InnerSign, SpendableKeysInterface};
70use lightning_signer::bitcoin::secp256k1::Signing;
71use lightning_signer::lightning_invoice::RawBolt11Invoice;
72pub use signer_port::SignerPort;
73use vls_protocol::psbt::StreamedPSBT;
74
75#[derive(Debug, PartialEq)]
76pub enum Error {
77 Protocol(ProtocolError),
78 Transport,
79 TransportTransient,
80}
81
82pub type ClientResult<T> = Result<T, Error>;
83
84impl From<ProtocolError> for Error {
85 fn from(e: ProtocolError) -> Self {
86 Error::Protocol(e)
87 }
88}
89
90pub trait Transport: Send + Sync {
91 fn node_call(&self, message: Vec<u8>) -> Result<Vec<u8>, Error>;
93 fn call(&self, dbid: u64, peer_id: PubKey, message: Vec<u8>) -> Result<Vec<u8>, Error>;
95}
96
97#[derive(Clone)]
98pub struct SignerClient {
99 transport: Arc<dyn Transport>,
100 peer_id: [u8; 33],
101 dbid: u64,
102 channel_keys: ChannelPublicKeys,
103 channel_value: u64,
104}
105
106fn to_pubkey(pubkey: PublicKey) -> PubKey {
107 PubKey(pubkey.serialize())
108}
109
110fn to_bitcoin_sig(sig: &Signature) -> BitcoinSignature {
111 BitcoinSignature {
112 signature: model::Signature(sig.serialize_compact()),
113 sighash: EcdsaSighashType::All as u8,
114 }
115}
116
117pub fn call<T: SerBolt, R: DeBolt>(
118 dbid: u64,
119 peer_id: PubKey,
120 transport: &dyn Transport,
121 message: T,
122) -> Result<R, Error> {
123 assert_ne!(dbid, 0, "dbid 0 is reserved");
124 let message_ser = message.as_vec();
125 debug!("signer call {:?}", message);
126 let result_ser = transport.call(dbid, peer_id, message_ser)?;
127 let result = R::from_vec(result_ser)?;
128 debug!("signer result {:?}", result);
129 Ok(result)
130}
131
132pub fn node_call<T: SerBolt, R: DeBolt>(transport: &dyn Transport, message: T) -> Result<R, Error> {
133 debug!("signer call {:?}", message);
134 let message_ser = message.as_vec();
135 let result_ser = transport.node_call(message_ser)?;
136 let result = R::from_vec(result_ser)?;
137 debug!("signer result {:?}", result);
138 Ok(result)
139}
140
141fn to_htlcs(htlcs: &Vec<HTLCOutputInCommitment>, is_remote: bool) -> Array<Htlc> {
142 let htlcs = htlcs
143 .iter()
144 .map(|h| Htlc {
145 side: if h.offered != is_remote { Htlc::LOCAL } else { Htlc::REMOTE },
146 amount: h.amount_msat,
147 payment_hash: model::Sha256(h.payment_hash.0),
148 ctlv_expiry: h.cltv_expiry,
149 })
150 .collect();
151 Array(htlcs)
152}
153
154fn dest_wallet_path() -> ArrayBE<u32> {
155 let result = vec![1];
156 assert_eq!(result.len(), 1);
158 result.into()
159}
160
161impl SignerClient {
162 fn call<T: SerBolt, R: DeBolt>(&self, message: T) -> Result<R, Error> {
163 call(self.dbid, PubKey(self.peer_id), &*self.transport, message).map_err(|e| {
164 error!("transport error: {:?}", e);
165 e
166 })
167 }
168
169 fn new(
170 transport: Arc<dyn Transport>,
171 peer_id: [u8; 33],
172 dbid: u64,
173 channel_value: u64,
174 channel_keys: ChannelPublicKeys,
175 ) -> Self {
176 SignerClient { transport, peer_id, dbid, channel_keys, channel_value }
177 }
178}
179
180impl Writeable for SignerClient {
181 fn write<W: Writer>(&self, writer: &mut W) -> Result<(), bitcoin::io::Error> {
182 self.peer_id.write(writer)?;
183 self.dbid.write(writer)?;
184 self.channel_keys.write(writer)?;
185 self.channel_value.write(writer)?;
186 Ok(())
187 }
188}
189
190impl EcdsaChannelSigner for SignerClient {
191 fn sign_counterparty_commitment(
192 &self,
193 commitment_tx: &CommitmentTransaction,
194 _preimages: Vec<PaymentPreimage>,
195 _preimages_ount: Vec<PaymentPreimage>,
196 _secp_ctx: &Secp256k1<All>,
197 ) -> Result<(Signature, Vec<Signature>), ()> {
198 let tx = commitment_tx.trust();
200 let htlcs = to_htlcs(tx.htlcs(), true);
201 let message = SignRemoteCommitmentTx2 {
202 remote_per_commitment_point: to_pubkey(tx.keys().per_commitment_point),
203 commitment_number: INITIAL_COMMITMENT_NUMBER - tx.commitment_number(),
204 feerate: tx.feerate_per_kw(),
205 to_local_value_sat: tx.to_countersignatory_value_sat(),
206 to_remote_value_sat: tx.to_broadcaster_value_sat(),
207 htlcs,
208 };
209 let result: SignCommitmentTxWithHtlcsReply = self.call(message).map_err(|_| ())?;
210 let signature = Signature::from_compact(&result.signature.signature.0).map_err(|_| ())?;
211 let htlc_signatures = result
212 .htlc_signatures
213 .iter()
214 .map(|s| Signature::from_compact(&s.signature.0))
215 .collect::<Result<Vec<_>, _>>()
216 .map_err(|_| ())?;
217 Ok((signature, htlc_signatures))
218 }
219
220 fn sign_holder_commitment(
221 &self,
222 commitment_tx: &HolderCommitmentTransaction,
223 _secp_ctx: &Secp256k1<All>,
224 ) -> Result<Signature, ()> {
225 let message = SignLocalCommitmentTx2 {
226 commitment_number: INITIAL_COMMITMENT_NUMBER - commitment_tx.commitment_number(),
227 };
228 let result: SignCommitmentTxReply = self.call(message).map_err(|_| ())?;
229 let signature = Signature::from_compact(&result.signature.signature.0).map_err(|_| ())?;
230 Ok(signature)
231 }
232
233 fn unsafe_sign_holder_commitment(
234 &self,
235 _commitment_tx: &HolderCommitmentTransaction,
236 _secp_ctx: &Secp256k1<All>,
237 ) -> Result<Signature, ()> {
238 unimplemented!()
239 }
240
241 #[allow(unused)]
242 fn sign_justice_revoked_output(
243 &self,
244 justice_tx: &Transaction,
245 input: usize,
246 amount: u64,
247 per_commitment_key: &SecretKey,
248 _secp_ctx: &Secp256k1<All>,
249 ) -> Result<Signature, ()> {
250 todo!()
252 }
253
254 #[allow(unused)]
255 fn sign_justice_revoked_htlc(
256 &self,
257 justice_tx: &Transaction,
258 input: usize,
259 amount: u64,
260 per_commitment_key: &SecretKey,
261 htlc: &HTLCOutputInCommitment,
262 _secp_ctx: &Secp256k1<All>,
263 ) -> Result<Signature, ()> {
264 todo!()
266 }
267
268 fn sign_holder_htlc_transaction(
269 &self,
270 htlc_tx: &Transaction,
271 input: usize,
272 htlc_descriptor: &HTLCDescriptor,
273 _secp_ctx: &Secp256k1<All>,
274 ) -> Result<Signature, ()> {
275 let htlc = &htlc_descriptor.htlc;
276 let message = SignLocalHtlcTx2 {
277 per_commitment_number: htlc_descriptor.per_commitment_number,
278 offered: htlc.offered,
279 cltv_expiry: htlc.cltv_expiry,
280 tx: WithSize(htlc_tx.clone()),
281 input: input as u32,
282 payment_hash: model::Sha256(htlc.payment_hash.0),
283 htlc_amount_msat: htlc_descriptor.htlc.amount_msat,
284 };
285 let result: SignTxReply = self.call(message).map_err(|_| ())?;
286 Ok(Signature::from_compact(&result.signature.signature.0).unwrap())
287 }
288
289 #[allow(unused)]
290 fn sign_counterparty_htlc_transaction(
291 &self,
292 htlc_tx: &Transaction,
293 input: usize,
294 amount: u64,
295 per_commitment_point: &PublicKey,
296 htlc: &HTLCOutputInCommitment,
297 _secp_ctx: &Secp256k1<All>,
298 ) -> Result<Signature, ()> {
299 todo!()
301 }
302
303 fn sign_closing_transaction(
304 &self,
305 tx: &ClosingTransaction,
306 _secp_ctx: &Secp256k1<All>,
307 ) -> Result<Signature, ()> {
308 let message = SignMutualCloseTx2 {
309 to_local_value_sat: tx.to_holder_value_sat(),
310 to_remote_value_sat: tx.to_counterparty_value_sat(),
311 local_script: tx.to_holder_script().to_bytes().into(),
312 remote_script: tx.to_counterparty_script().to_bytes().into(),
313 local_wallet_path_hint: dest_wallet_path(),
314 };
315 let result: SignTxReply = self.call(message).map_err(|_| ())?;
316 Ok(Signature::from_compact(&result.signature.signature.0).unwrap())
317 }
318
319 fn sign_holder_anchor_input(
320 &self,
321 _anchor_tx: &Transaction,
322 _input: usize,
323 _secp_ctx: &Secp256k1<All>,
324 ) -> Result<Signature, ()> {
325 todo!()
326 }
327
328 fn sign_channel_announcement_with_funding_key(
329 &self,
330 msg: &UnsignedChannelAnnouncement,
331 _secp_ctx: &Secp256k1<All>,
332 ) -> Result<Signature, ()> {
333 let mut announcement = [0u8; 258].to_vec();
335 announcement.extend(msg.encode());
336 let message = SignChannelAnnouncement { announcement: announcement.into() };
337 let result: SignChannelAnnouncementReply = self.call(message).map_err(|_| ())?;
338 Ok(Signature::from_compact(&result.bitcoin_signature.0).unwrap())
339 }
340
341 fn sign_splicing_funding_input(
342 &self,
343 _tx: &Transaction,
344 _input_index: usize,
345 _input_value: u64,
346 _secp_ctx: &Secp256k1<All>,
347 ) -> Result<Signature, ()> {
348 todo!("sign_splicing_funding_input - #538")
349 }
350}
351
352impl ChannelSigner for SignerClient {
353 fn get_per_commitment_point(
354 &self,
355 idx: u64,
356 _secp_ctx: &Secp256k1<All>,
357 ) -> Result<PublicKey, ()> {
358 let message = GetPerCommitmentPoint2 { commitment_number: INITIAL_COMMITMENT_NUMBER - idx };
359 let result: GetPerCommitmentPoint2Reply =
360 self.call(message).expect("get_per_commitment_point");
361 Ok(PublicKey::from_slice(&result.point.0).expect("public key"))
362 }
363
364 fn validate_counterparty_revocation(&self, idx: u64, secret: &SecretKey) -> Result<(), ()> {
365 let message = ValidateRevocation {
366 commitment_number: INITIAL_COMMITMENT_NUMBER - idx,
367 commitment_secret: DisclosedSecret(secret[..].try_into().unwrap()),
368 };
369 let _: ValidateRevocationReply = self.call(message).map_err(|_| ())?;
370 Ok(())
371 }
372
373 fn release_commitment_secret(&self, idx: u64) -> Result<[u8; 32], ()> {
374 let message =
376 GetPerCommitmentPoint { commitment_number: INITIAL_COMMITMENT_NUMBER - idx + 2 };
377 let result: GetPerCommitmentPointReply =
378 self.call(message).expect("get_per_commitment_point");
379 let secret = result.secret.expect("secret not released");
380 Ok(secret.0)
381 }
382
383 fn validate_holder_commitment(
384 &self,
385 holder_tx: &HolderCommitmentTransaction,
386 _preimages: Vec<PaymentPreimage>,
387 ) -> Result<(), ()> {
388 let tx = holder_tx.trust();
390 let htlcs = to_htlcs(tx.htlcs(), false);
391 let message = ValidateCommitmentTx2 {
392 commitment_number: INITIAL_COMMITMENT_NUMBER - tx.commitment_number(),
393 feerate: tx.feerate_per_kw(),
394 to_local_value_sat: tx.to_broadcaster_value_sat(),
395 to_remote_value_sat: tx.to_countersignatory_value_sat(),
396 htlcs,
397 signature: to_bitcoin_sig(&holder_tx.counterparty_sig),
398 htlc_signatures: Array(
399 holder_tx.counterparty_htlc_sigs.iter().map(|s| to_bitcoin_sig(s)).collect(),
400 ),
401 };
402 let _: ValidateCommitmentTxReply = self.call(message).map_err(|_| ())?;
403 Ok(())
404 }
405
406 fn pubkeys(&self) -> &ChannelPublicKeys {
407 &self.channel_keys
408 }
409
410 fn channel_keys_id(&self) -> [u8; 32] {
411 ChannelId::new_from_oid(self.dbid).ldk_channel_keys_id()
412 }
413
414 fn provide_channel_parameters(&mut self, p: &ChannelTransactionParameters) {
415 let funding = p.funding_outpoint.expect("funding should exist at this point");
416 let cp = p
417 .counterparty_parameters
418 .as_ref()
419 .expect("counterparty params should exist at this point");
420
421 let features = &p.channel_type_features;
422 let commitment_type = if features.supports_anchors_zero_fee_htlc_tx() {
423 CommitmentType::AnchorsZeroFeeHtlc
424 } else if features.supports_anchors_nonzero_fee_htlc_tx() {
425 CommitmentType::Anchors
426 } else {
427 CommitmentType::StaticRemoteKey
428 };
429
430 let ser_channel_type = commitment_type_to_channel_type(commitment_type);
431 let message = SetupChannel {
432 is_outbound: p.is_outbound_from_holder,
433 channel_value: self.channel_value,
434 push_value: 0, funding_txid: funding.txid,
436 funding_txout: funding.index,
437 to_self_delay: p.holder_selected_contest_delay,
438 local_shutdown_script: Octets::EMPTY, local_shutdown_wallet_index: None,
440 remote_basepoints: Basepoints {
441 revocation: to_pubkey(cp.pubkeys.revocation_basepoint.0),
442 payment: to_pubkey(cp.pubkeys.payment_point),
443 htlc: to_pubkey(cp.pubkeys.htlc_basepoint.0),
444 delayed_payment: to_pubkey(cp.pubkeys.delayed_payment_basepoint.0),
445 },
446 remote_funding_pubkey: to_pubkey(cp.pubkeys.funding_pubkey),
447 remote_to_self_delay: cp.selected_contest_delay,
448 remote_shutdown_script: Octets::EMPTY, channel_type: ser_channel_type.into(),
450 };
451
452 let _: SetupChannelReply = self.call(message).expect("setup channel");
453 }
454}
455
456pub struct KeysManagerClient {
457 transport: Arc<dyn Transport>,
458 next_dbid: AtomicU64,
459 key_material: ExpandedKey,
460 xpub: Xpub,
461 node_id: PublicKey,
462}
463
464impl KeysManagerClient {
465 pub fn new(
467 transport: Arc<dyn Transport>,
468 network: String,
469 key_derivation_style: Option<KeyDerivationStyle>,
470 dev_allowlist: Option<Array<WireString>>,
471 ) -> Self {
472 let mut rng = OsRng;
473 let mut key_material_bytes = [0; 32];
474 rng.fill_bytes(&mut key_material_bytes);
475
476 let key_derivation_style = key_derivation_style.unwrap_or(KeyDerivationStyle::Native);
477
478 #[cfg(not(feature = "developer"))]
479 assert!(dev_allowlist.is_none(), "dev_allowlist is only available in developer mode");
480
481 #[cfg(feature = "developer")]
482 if let Some(allowlist) = dev_allowlist {
483 let preinit_message = HsmdDevPreinit {
484 derivation_style: key_derivation_style as u8,
485 network_name: WireString(network.clone().into_bytes()),
486 seed: None,
487 allowlist,
488 };
489 let _: HsmdDevPreinitReply =
490 node_call(&*transport, preinit_message).expect("HsmdDevPreinit should succeed");
491 }
492
493 let init_message = HsmdInit2 {
494 derivation_style: key_derivation_style as u8,
495 network_name: WireString(network.into_bytes()),
496 dev_seed: None,
497 dev_allowlist: Array::new(),
498 };
499 let result: HsmdInit2Reply = node_call(&*transport, init_message).expect("HsmdInit");
500 let xpub = Xpub::decode(&result.bip32.0).expect("xpub");
501 let node_id = PublicKey::from_slice(&result.node_id.0).expect("node id");
502
503 Self {
504 transport,
505 next_dbid: AtomicU64::new(1),
506 key_material: ExpandedKey::new(key_material_bytes),
507 xpub,
508 node_id,
509 }
510 }
511
512 pub fn call<T: SerBolt, R: DeBolt>(&self, message: T) -> Result<R, Error> {
513 node_call(&*self.transport, message)
514 }
515
516 fn get_channel_basepoints(&self, dbid: u64, peer_id: [u8; 33]) -> ChannelPublicKeys {
517 let message = GetChannelBasepoints { node_id: PubKey(peer_id), dbid };
518 let result: GetChannelBasepointsReply = self.call(message).expect("pubkeys");
519 let channel_keys = ChannelPublicKeys {
520 funding_pubkey: result.funding.into(),
521 revocation_basepoint: result.basepoints.revocation.into(),
522 payment_point: result.basepoints.payment.into(),
523 delayed_payment_basepoint: result.basepoints.delayed_payment.into(),
524 htlc_basepoint: result.basepoints.htlc.into(),
525 };
526 channel_keys
527 }
528
529 pub fn sign_onchain_tx(
530 &self,
531 tx: &Transaction,
532 descriptors: &[&SpendableOutputDescriptor],
533 ) -> Vec<Vec<Vec<u8>>> {
534 assert_eq!(tx.input.len(), descriptors.len());
535
536 let mut psbt = Psbt::from_unsigned_tx(tx.clone()).expect("create PSBT");
537 for i in 0..psbt.inputs.len() {
538 psbt.inputs[i].witness_utxo = Self::descriptor_to_txout(descriptors[i]);
539 }
540
541 let streamed_psbt = StreamedPSBT::new(psbt).into();
542 let utxos = Array(descriptors.into_iter().map(|d| Self::descriptor_to_utxo(*d)).collect());
543
544 let message = SignWithdrawal { utxos, psbt: streamed_psbt };
545 let result: SignWithdrawalReply = self.call(message).expect("sign failed");
546 let psbt = result.psbt.0.inner;
547 psbt.inputs.into_iter().map(|i| i.final_script_witness.unwrap().to_vec()).collect()
548 }
549
550 fn descriptor_to_txout(d: &SpendableOutputDescriptor) -> Option<TxOut> {
551 match d {
552 SpendableOutputDescriptor::StaticOutput { output, .. } => Some(output.clone()),
553 SpendableOutputDescriptor::DelayedPaymentOutput(o) => Some(o.output.clone()),
554 SpendableOutputDescriptor::StaticPaymentOutput(o) => Some(o.output.clone()),
555 }
556 }
557
558 fn descriptor_to_utxo(d: &SpendableOutputDescriptor) -> Utxo {
559 let (outpoint, amount, keyindex, close_info) = match d {
560 SpendableOutputDescriptor::StaticOutput { output, outpoint, .. } =>
562 (outpoint.clone(), output.value, dest_wallet_path()[0], None), SpendableOutputDescriptor::DelayedPaymentOutput(o) => (
565 o.outpoint,
566 o.output.value,
567 0,
568 Some(CloseInfo {
569 channel_id: ChannelId::new(&o.channel_keys_id).oid(),
570 peer_id: PubKey([0; 33]),
571 commitment_point: Some(to_pubkey(o.per_commitment_point)),
572 is_anchors: false,
573 csv: o.to_self_delay as u32,
574 }),
575 ),
576 SpendableOutputDescriptor::StaticPaymentOutput(o) => (
578 o.outpoint,
579 o.output.value,
580 0,
581 Some(CloseInfo {
582 channel_id: ChannelId::new(&o.channel_keys_id).oid(),
583 peer_id: PubKey([0; 33]),
584 commitment_point: None,
585 is_anchors: false,
586 csv: 0,
587 }),
588 ),
589 };
590 let is_in_coinbase = false; Utxo {
592 txid: outpoint.txid,
593 outnum: outpoint.index as u32,
594 amount: amount.to_sat(),
595 keyindex,
596 is_p2sh: false,
597 script: Octets::EMPTY,
598 close_info,
599 is_in_coinbase,
600 }
601 }
602}
603
604impl EntropySource for KeysManagerClient {
605 fn get_secure_random_bytes(&self) -> [u8; 32] {
606 let mut rng = OsRng;
607 let mut bytes = [0; 32];
608 rng.fill_bytes(&mut bytes);
609 bytes
610 }
611}
612
613impl NodeSigner for KeysManagerClient {
614 fn get_inbound_payment_key(&self) -> ExpandedKey {
615 self.key_material
616 }
617 fn get_node_id(&self, recipient: Recipient) -> Result<PublicKey, ()> {
618 match recipient {
619 Recipient::Node => {}
620 Recipient::PhantomNode => {
621 unimplemented!("phantom nodes not supported")
622 }
623 }
624 Ok(self.node_id)
625 }
626
627 fn ecdh(
628 &self,
629 recipient: Recipient,
630 other_key: &PublicKey,
631 tweak: Option<&Scalar>,
632 ) -> Result<SharedSecret, ()> {
633 match recipient {
634 Recipient::Node => {}
635 Recipient::PhantomNode => unimplemented!("PhantomNode"),
636 }
637
638 if tweak.is_some() {
639 unimplemented!("tweak is not supported");
640 }
641 let message = Ecdh { point: PubKey(other_key.serialize()) };
642 let result: EcdhReply = self.call(message).expect("ecdh");
643 Ok(SharedSecret::from_bytes(result.secret.0))
644 }
645
646 fn sign_invoice(
647 &self,
648 invoice: &RawBolt11Invoice,
649 recipient: Recipient,
650 ) -> Result<RecoverableSignature, ()> {
651 match recipient {
652 Recipient::Node => {}
653 Recipient::PhantomNode => {
654 unimplemented!("phantom nodes not supported")
655 }
656 }
657 let (hrp, invoice_data) = invoice.to_raw();
658 let hrp_bytes = hrp.into_bytes();
659
660 let message = SignInvoice {
661 u5bytes: Octets(invoice_data.iter().map(|u| u.to_u8()).collect()),
662 hrp: hrp_bytes.into(),
663 };
664 let result: SignInvoiceReply = self.call(message).expect("sign_invoice");
665 let rid = RecoveryId::from_i32(result.signature.0[64] as i32).expect("recovery ID");
666 let sig = &result.signature.0[0..64];
667 RecoverableSignature::from_compact(sig, rid).map_err(|_| ())
668 }
669
670 fn sign_bolt12_invoice(
671 &self,
672 _invoice: &lightning::offers::invoice::UnsignedBolt12Invoice,
673 ) -> Result<bitcoin::secp256k1::schnorr::Signature, ()> {
674 unimplemented!()
675 }
676
677 fn sign_gossip_message(&self, msg: UnsignedGossipMessage) -> Result<Signature, ()> {
678 let message = SignGossipMessage { message: Octets(msg.encode()) };
679 let result: SignGossipMessageReply = self.call(message).expect("sign_gossip_message");
680 Ok(Signature::from_compact(&result.signature.0).expect("signature"))
681 }
682}
683
684impl SignerProvider for KeysManagerClient {
685 type EcdsaSigner = SignerClient;
686
687 fn generate_channel_keys_id(
688 &self,
689 _inbound: bool,
690 _channel_value_satoshis: u64,
691 _user_channel_id: u128,
692 ) -> [u8; 32] {
693 let dbid = self.next_dbid.fetch_add(1, Ordering::AcqRel);
694 ChannelId::new_from_oid(dbid).ldk_channel_keys_id()
695 }
696
697 fn derive_channel_signer(
698 &self,
699 channel_value_satoshis: u64,
700 channel_keys_id: [u8; 32],
701 ) -> Self::EcdsaSigner {
702 let peer_id = [0u8; 33];
705 let dbid = ChannelId::new(&channel_keys_id).oid();
706
707 let message = NewChannel { peer_id: PubKey(peer_id.clone()), dbid };
708 let _: NewChannelReply = self.call(message).expect("NewChannel");
709
710 let channel_keys = self.get_channel_basepoints(dbid, peer_id);
711
712 SignerClient::new(
713 self.transport.clone(),
714 peer_id,
715 dbid,
716 channel_value_satoshis,
717 channel_keys,
718 )
719 }
720
721 fn read_chan_signer(&self, mut reader: &[u8]) -> Result<Self::EcdsaSigner, DecodeError> {
722 let peer_id = Readable::read(&mut reader)?;
723 let dbid = Readable::read(&mut reader)?;
724 let channel_keys = Readable::read(&mut reader)?;
725 let channel_value = Readable::read(&mut reader)?;
726
727 Ok(SignerClient {
728 transport: self.transport.clone(),
729 peer_id,
730 dbid,
731 channel_keys,
732 channel_value,
733 })
734 }
735
736 fn get_destination_script(&self, _: [u8; 32]) -> Result<ScriptBuf, ()> {
737 let secp_ctx = Secp256k1::new();
738 let wallet_path = dest_wallet_path();
739 let mut key = self.xpub;
740 for i in wallet_path.iter() {
741 key = key.ckd_pub(&secp_ctx, ChildNumber::from_normal_idx(*i).unwrap()).unwrap();
742 }
743 let pubkey = key.public_key;
744 Ok(ScriptBuf::new_p2wpkh(&WPubkeyHash::hash(&pubkey.serialize())))
745 }
746
747 fn get_shutdown_scriptpubkey(&self) -> Result<ShutdownScript, ()> {
748 Ok(ShutdownScript::try_from(self.get_destination_script([0; 32])?).expect("script"))
749 }
750}
751
752impl OutputSpender for KeysManagerClient {
753 fn spend_spendable_outputs<C: Signing>(
754 &self,
755 descriptors: &[&SpendableOutputDescriptor],
756 outputs: Vec<TxOut>,
757 change_destination_script: ScriptBuf,
758 feerate_sat_per_1000_weight: u32,
759 locktime: Option<LockTime>,
760 _secp_ctx: &Secp256k1<C>,
761 ) -> Result<Transaction, ()> {
762 let mut tx = create_spending_transaction(
763 descriptors,
764 outputs,
765 change_destination_script,
766 feerate_sat_per_1000_weight,
767 )
768 .unwrap();
769 tx.lock_time = locktime.unwrap_or(LockTime::ZERO);
770 let witnesses = self.sign_onchain_tx(&tx, descriptors);
771 for (idx, w) in witnesses.into_iter().enumerate() {
772 tx.input[idx].witness = Witness::from_slice(&w);
773 }
774 Ok(tx)
775 }
776}
777
778impl InnerSign for SignerClient {
779 fn box_clone(&self) -> Box<dyn InnerSign> {
780 Box::new(self.clone())
781 }
782
783 fn as_any(&self) -> &dyn Any {
784 self
785 }
786
787 fn vwrite(&self, writer: &mut Vec<u8>) -> Result<(), bitcoin::io::Error> {
788 self.write(writer)
789 }
790}