1
2use bitcoin::{TapSighash, Witness, taproot};
3use bitcoin::key::Keypair;
4
5use ark::vtxo::{TapScriptClause, VtxoClause};
6use ark::vtxo::policy::signing::VtxoSigner;
7
8use crate::{SECP, Wallet};
9
10impl Wallet {
11 pub (crate) async fn clause_keypair(&self, clause: &VtxoClause) -> Option<Keypair> {
12 let clause_pubkey = clause.pubkey();
13 self.pubkey_keypair(&clause_pubkey).await.ok()
14 .flatten().map(|(_, keypair)| keypair)
15 }
16}
17
18#[async_trait]
19impl VtxoSigner for Wallet {
20 async fn witness(
21 &self,
22 clause: &VtxoClause,
23 control_block: &taproot::ControlBlock,
24 sighash: TapSighash,
25 ) -> Option<Witness> {
26 let signature = match self.clause_keypair(clause).await {
27 Some(keypair) => {
28 SECP.sign_schnorr_with_aux_rand(&sighash.into(), &keypair, &rand::random())
29 },
30 None => return None,
31 };
32
33 let witness = match clause {
34 VtxoClause::DelayedSign(c) => c.witness(&signature, control_block),
35 VtxoClause::DelayedTimelockSign(c) => c.witness(&signature, &control_block),
36 VtxoClause::TimelockSign(c) => c.witness(&signature, &control_block),
37 VtxoClause::HashDelaySign(c) => {
38 let receive = self.db.fetch_lightning_receive_by_payment_hash(c.payment_hash)
39 .await.ok().flatten();
40
41 if let Some(receive) = receive {
42 c.witness(&(signature, receive.payment_preimage), &control_block)
43 } else {
44 return None;
45 }
46 }
47 };
48
49 Some(witness)
50 }
51}