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