rustywallet_coinjoin/
types.rs1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
7pub struct InputRef {
8 pub txid: [u8; 32],
10 pub vout: u32,
12 pub amount: u64,
14 pub script_pubkey: Vec<u8>,
16}
17
18impl InputRef {
19 pub fn new(txid: [u8; 32], vout: u32, amount: u64, script_pubkey: Vec<u8>) -> Self {
21 Self {
22 txid,
23 vout,
24 amount,
25 script_pubkey,
26 }
27 }
28
29 pub fn from_outpoint(txid: [u8; 32], vout: u32, amount: u64) -> Self {
31 Self {
32 txid,
33 vout,
34 amount,
35 script_pubkey: Vec::new(),
36 }
37 }
38}
39
40#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
42pub struct OutputDef {
43 pub amount: u64,
45 pub script_pubkey: Vec<u8>,
47 pub address: Option<String>,
49}
50
51impl OutputDef {
52 pub fn new(amount: u64, script_pubkey: Vec<u8>) -> Self {
54 Self {
55 amount,
56 script_pubkey,
57 address: None,
58 }
59 }
60
61 pub fn with_address(amount: u64, script_pubkey: Vec<u8>, address: String) -> Self {
63 Self {
64 amount,
65 script_pubkey,
66 address: Some(address),
67 }
68 }
69}
70
71#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct Participant {
74 pub id: String,
76 pub inputs: Vec<InputRef>,
78 pub output_script: Vec<u8>,
80 pub change_script: Option<Vec<u8>>,
82}
83
84impl Participant {
85 pub fn new(id: impl Into<String>, inputs: Vec<InputRef>, output_script: Vec<u8>) -> Self {
87 Self {
88 id: id.into(),
89 inputs,
90 output_script,
91 change_script: None,
92 }
93 }
94
95 pub fn with_change(mut self, change_script: Vec<u8>) -> Self {
97 self.change_script = Some(change_script);
98 self
99 }
100
101 pub fn total_input(&self) -> u64 {
103 self.inputs.iter().map(|i| i.amount).sum()
104 }
105}
106
107#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
109pub enum FeeStrategy {
110 #[default]
112 Equal,
113 Proportional,
115 SinglePayer(usize),
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122
123 #[test]
124 fn test_input_ref() {
125 let input = InputRef::new([1u8; 32], 0, 100_000, vec![0x00, 0x14]);
126 assert_eq!(input.amount, 100_000);
127 assert_eq!(input.vout, 0);
128 }
129
130 #[test]
131 fn test_output_def() {
132 let output = OutputDef::with_address(50_000, vec![0x00, 0x14], "bc1q...".into());
133 assert_eq!(output.amount, 50_000);
134 assert!(output.address.is_some());
135 }
136
137 #[test]
138 fn test_participant() {
139 let inputs = vec![InputRef::from_outpoint([1u8; 32], 0, 100_000)];
140 let participant = Participant::new("alice", inputs, vec![0x00, 0x14]);
141 assert_eq!(participant.total_input(), 100_000);
142 }
143}