spark_sdk/wallet/utils/
transaction.rs1use crate::wallet::utils::bitcoin::p2tr_script_from_pubkey;
2use crate::wallet::utils::sequence::initial_sequence;
3use bitcoin::{absolute, transaction::Version, Amount, OutPoint, Sequence, Transaction, TxOut};
4
5pub(crate) fn ephemeral_anchor_output() -> bitcoin::TxOut {
7 bitcoin::TxOut {
8 value: bitcoin::Amount::from_sat(0),
9 script_pubkey: bitcoin::ScriptBuf::from_bytes(vec![bitcoin::opcodes::OP_TRUE.to_u8()]),
10 }
11}
12
13pub(crate) fn create_root_tx(deposit_outpoint: OutPoint, deposit_txout: TxOut) -> Transaction {
14 let mut root_tx = Transaction {
15 version: Version::TWO,
16 lock_time: absolute::LockTime::ZERO,
17 input: vec![],
18 output: vec![],
19 };
20
21 root_tx.input.push(bitcoin::TxIn {
22 previous_output: deposit_outpoint,
23 script_sig: bitcoin::Script::new().into(),
24 sequence: bitcoin::Sequence::default(),
25 witness: bitcoin::Witness::new(),
26 });
27
28 root_tx.output.push(deposit_txout);
29 root_tx.output.push(ephemeral_anchor_output());
30
31 root_tx
32}
33
34pub(crate) fn create_split_tx(parent_outpoint: OutPoint, child_txouts: Vec<TxOut>) -> Transaction {
35 let mut split_tx = Transaction {
36 version: Version::TWO,
37 lock_time: absolute::LockTime::ZERO,
38 input: vec![],
39 output: vec![],
40 };
41
42 split_tx.input.push(bitcoin::TxIn {
43 previous_output: parent_outpoint,
44 script_sig: bitcoin::Script::new().into(),
45 sequence: bitcoin::Sequence::default(),
46 witness: bitcoin::Witness::new(),
47 });
48 for txout in child_txouts {
49 split_tx.output.push(txout);
50 }
51 split_tx.output.push(ephemeral_anchor_output());
52
53 split_tx
54}
55
56pub(crate) fn create_node_tx(parent_outpoint: OutPoint, txout: TxOut) -> Transaction {
57 let mut node_tx = Transaction {
58 version: Version::TWO,
59 lock_time: absolute::LockTime::ZERO,
60 input: vec![],
61 output: vec![],
62 };
63
64 node_tx.input.push(bitcoin::TxIn {
65 previous_output: parent_outpoint,
66 script_sig: bitcoin::Script::new().into(),
67 sequence: bitcoin::Sequence::default(),
68 witness: bitcoin::Witness::new(),
69 });
70
71 node_tx.output.push(txout);
72 node_tx.output.push(ephemeral_anchor_output());
73
74 node_tx
75}
76
77pub(crate) fn create_leaf_node_tx(parent_outpoint: OutPoint, txout: TxOut) -> Transaction {
78 let mut new_leaf_tx = Transaction {
79 version: Version::TWO,
80 lock_time: absolute::LockTime::ZERO,
81 input: vec![],
82 output: vec![],
83 };
84
85 new_leaf_tx.input.push(bitcoin::TxIn {
86 previous_output: parent_outpoint,
87 script_sig: bitcoin::Script::new().into(),
88 sequence: initial_sequence(),
89 witness: bitcoin::Witness::new(),
90 });
91
92 new_leaf_tx.output.push(txout);
93 new_leaf_tx.output.push(ephemeral_anchor_output());
94
95 new_leaf_tx
96}
97
98pub(crate) fn create_refund_tx(
99 sequence: u32,
100 node_outpoint: OutPoint,
101 amount_sats: bitcoin::Amount,
102 receiving_pubkey: &bitcoin::secp256k1::PublicKey,
103 network: bitcoin::Network,
104) -> Transaction {
105 let mut new_refund_tx = Transaction {
106 version: Version::TWO,
107 lock_time: absolute::LockTime::ZERO,
108 input: vec![],
109 output: vec![],
110 };
111
112 new_refund_tx.input.push(bitcoin::TxIn {
113 previous_output: node_outpoint,
114 script_sig: bitcoin::Script::new().into(),
115 sequence: Sequence(sequence),
116 witness: bitcoin::Witness::new(),
117 });
118
119 let script_pubkey = p2tr_script_from_pubkey(receiving_pubkey, network);
120 new_refund_tx.output.push(bitcoin::TxOut {
121 value: amount_sats,
122 script_pubkey,
123 });
124 new_refund_tx.output.push(ephemeral_anchor_output());
125
126 new_refund_tx
127}
128
129pub(crate) fn create_connector_refund_tx(
130 sequence: u32,
131 node_outpoint: OutPoint,
132 connector_output: OutPoint,
133 amount_sats: u64,
134 receiver_pubkey: &bitcoin::secp256k1::PublicKey,
135 network: bitcoin::Network,
136) -> Transaction {
137 let mut refund_tx = Transaction {
138 version: Version::TWO,
139 lock_time: absolute::LockTime::ZERO,
140 input: vec![],
141 output: vec![],
142 };
143
144 refund_tx.input.push(bitcoin::TxIn {
145 previous_output: node_outpoint,
146 script_sig: bitcoin::Script::new().into(),
147 sequence: Sequence(sequence),
148 witness: bitcoin::Witness::new(),
149 });
150 refund_tx.input.push(bitcoin::TxIn {
151 previous_output: connector_output,
152 script_sig: bitcoin::Script::new().into(),
153 sequence: bitcoin::Sequence::default(),
154 witness: bitcoin::Witness::new(),
155 });
156
157 let script_pubkey = p2tr_script_from_pubkey(receiver_pubkey, network);
158 refund_tx.output.push(TxOut {
159 value: Amount::from_sat(amount_sats),
160 script_pubkey,
161 });
162 refund_tx.output.push(ephemeral_anchor_output());
163
164 refund_tx
165}