vls_proxy/recovery/
direct.rs

1use crate::recovery::{Iter, RecoveryKeys, RecoverySign};
2use lightning_signer::bitcoin::secp256k1::{PublicKey, SecretKey};
3use lightning_signer::bitcoin::{Address, ScriptBuf, Transaction, TxOut};
4use lightning_signer::channel::{Channel, ChannelBase, ChannelSlot};
5use lightning_signer::lightning::chain::transaction::OutPoint;
6use lightning_signer::node::Node;
7use lightning_signer::util::status::Status;
8use lightning_signer::wallet::Wallet;
9use std::sync::{Arc, Mutex, MutexGuard};
10
11/// Recovery keys for an in-process Node
12pub struct DirectRecoveryKeys {
13    pub node: Arc<Node>,
14}
15
16impl RecoveryKeys for DirectRecoveryKeys {
17    type Signer = DirectRecoverySigner;
18
19    fn iter(&self) -> Iter<Self::Signer> {
20        let signers: Vec<_> = self
21            .node
22            .get_channels()
23            .iter()
24            .map(|(_id, channel)| Arc::clone(channel))
25            .filter_map(|channel| {
26                let channel1 = Arc::clone(&channel);
27                let lock = channel1.lock().unwrap();
28                match *lock {
29                    ChannelSlot::Stub(ref c) => {
30                        println!("# channel {} is a stub", c.id0);
31                        None
32                    }
33                    ChannelSlot::Ready(_) => Some(DirectRecoverySigner { channel }),
34                }
35            })
36            .collect();
37        Iter { signers }
38    }
39
40    fn sign_onchain_tx(
41        &self,
42        tx: &Transaction,
43        segwit_flags: &[bool],
44        ipaths: &Vec<Vec<u32>>,
45        prev_outs: &Vec<TxOut>,
46        uniclosekeys: Vec<Option<(SecretKey, Vec<Vec<u8>>)>>,
47        opaths: &Vec<Vec<u32>>,
48    ) -> Result<Vec<Vec<Vec<u8>>>, Status> {
49        self.node.check_onchain_tx(tx, segwit_flags, prev_outs, &uniclosekeys, opaths)?;
50        self.node.unchecked_sign_onchain_tx(tx, ipaths, prev_outs, uniclosekeys)
51    }
52
53    fn wallet_address_native(&self, index: u32) -> Result<Address, Status> {
54        self.node.get_native_address(&[index])
55    }
56
57    fn wallet_address_taproot(&self, index: u32) -> Result<Address, Status> {
58        self.node.get_taproot_address(&[index])
59    }
60}
61
62/// Recovery signer for an in-process Channel
63pub struct DirectRecoverySigner {
64    channel: Arc<Mutex<ChannelSlot>>,
65}
66
67impl RecoverySign for DirectRecoverySigner {
68    fn sign_holder_commitment_tx_for_recovery(
69        &self,
70    ) -> Result<
71        (Transaction, Vec<Transaction>, ScriptBuf, (SecretKey, Vec<Vec<u8>>), PublicKey),
72        Status,
73    > {
74        let mut lock = self.lock();
75        Self::channel(&mut lock).sign_holder_commitment_tx_for_recovery()
76    }
77
78    fn funding_outpoint(&self) -> OutPoint {
79        let mut lock = self.lock();
80        Self::channel(&mut lock).keys.funding_outpoint().unwrap().clone()
81    }
82
83    fn counterparty_selected_contest_delay(&self) -> u16 {
84        let mut lock = self.lock();
85        Self::channel(&mut lock).setup.counterparty_selected_contest_delay
86    }
87
88    fn get_per_commitment_point(&self) -> Result<PublicKey, Status> {
89        let mut lock = self.lock();
90        let channel = Self::channel(&mut lock);
91        channel.get_per_commitment_point(channel.enforcement_state.next_holder_commit_num - 1)
92    }
93}
94
95impl DirectRecoverySigner {
96    fn channel(lock: &mut ChannelSlot) -> &mut Channel {
97        match *lock {
98            ChannelSlot::Stub(_) => {
99                panic!("already checked");
100            }
101            ChannelSlot::Ready(ref mut c) => c,
102        }
103    }
104
105    fn lock(&self) -> MutexGuard<ChannelSlot> {
106        self.channel.lock().unwrap()
107    }
108}