rustywallet_vanity/
config.rs1use crate::address_type::AddressType;
4use crate::error::VanityError;
5use crate::pattern::Pattern;
6use std::time::Duration;
7
8#[derive(Debug, Clone)]
10pub struct VanityConfig {
11 pub patterns: Vec<Pattern>,
13 pub address_type: AddressType,
15 pub testnet: bool,
17 pub case_sensitive: bool,
19 pub max_attempts: Option<u64>,
21 pub timeout: Option<Duration>,
23 pub thread_count: Option<usize>,
25 pub batch_size: usize,
27 pub progress_interval: Duration,
29}
30
31impl Default for VanityConfig {
32 fn default() -> Self {
33 Self {
34 patterns: Vec::new(),
35 address_type: AddressType::P2PKH,
36 testnet: false,
37 case_sensitive: true,
38 max_attempts: None,
39 timeout: None,
40 thread_count: None,
41 batch_size: 10_000,
42 progress_interval: Duration::from_secs(1),
43 }
44 }
45}
46
47impl VanityConfig {
48 pub fn new() -> Self {
50 Self::default()
51 }
52
53 pub fn fast() -> Self {
55 Self {
56 batch_size: 50_000,
57 progress_interval: Duration::from_millis(500),
58 ..Default::default()
59 }
60 }
61
62 pub fn thorough() -> Self {
64 Self {
65 batch_size: 10_000,
66 progress_interval: Duration::from_secs(2),
67 ..Default::default()
68 }
69 }
70
71 pub fn with_patterns(mut self, patterns: Vec<Pattern>) -> Self {
73 self.patterns = patterns;
74 self
75 }
76
77 pub fn with_pattern(mut self, pattern: Pattern) -> Self {
79 self.patterns.push(pattern);
80 self
81 }
82
83 pub fn with_address_type(mut self, address_type: AddressType) -> Self {
85 self.address_type = address_type;
86 self
87 }
88
89 pub fn with_testnet(mut self, testnet: bool) -> Self {
91 self.testnet = testnet;
92 self
93 }
94
95 pub fn with_case_sensitive(mut self, case_sensitive: bool) -> Self {
97 self.case_sensitive = case_sensitive;
98 self
99 }
100
101 pub fn with_max_attempts(mut self, max: u64) -> Self {
103 self.max_attempts = Some(max);
104 self
105 }
106
107 pub fn with_timeout(mut self, timeout: Duration) -> Self {
109 self.timeout = Some(timeout);
110 self
111 }
112
113 pub fn with_thread_count(mut self, count: usize) -> Self {
115 self.thread_count = Some(count);
116 self
117 }
118
119 pub fn with_batch_size(mut self, size: usize) -> Self {
121 self.batch_size = size;
122 self
123 }
124
125 pub fn validate(&self) -> Result<(), VanityError> {
127 if self.patterns.is_empty() {
128 return Err(VanityError::InvalidConfig(
129 "At least one pattern is required".to_string(),
130 ));
131 }
132
133 if self.batch_size == 0 {
134 return Err(VanityError::InvalidConfig(
135 "Batch size must be greater than 0".to_string(),
136 ));
137 }
138
139 if let Some(count) = self.thread_count {
140 if count == 0 {
141 return Err(VanityError::InvalidConfig(
142 "Thread count must be greater than 0".to_string(),
143 ));
144 }
145 }
146
147 for pattern in &self.patterns {
149 pattern
150 .validate_for_type(self.address_type, self.testnet)
151 .map_err(VanityError::InvalidPattern)?;
152 }
153
154 Ok(())
155 }
156}
157
158#[cfg(test)]
159mod tests {
160 use super::*;
161
162 #[test]
163 fn test_default_config() {
164 let config = VanityConfig::default();
165 assert!(config.patterns.is_empty());
166 assert_eq!(config.address_type, AddressType::P2PKH);
167 assert!(config.case_sensitive);
168 }
169
170 #[test]
171 fn test_fast_preset() {
172 let config = VanityConfig::fast();
173 assert_eq!(config.batch_size, 50_000);
174 }
175
176 #[test]
177 fn test_validation_no_patterns() {
178 let config = VanityConfig::default();
179 assert!(config.validate().is_err());
180 }
181
182 #[test]
183 fn test_validation_with_pattern() {
184 let config = VanityConfig::default()
185 .with_pattern(Pattern::prefix("1Love").unwrap());
186 assert!(config.validate().is_ok());
187 }
188
189 #[test]
190 fn test_builder_pattern() {
191 let config = VanityConfig::new()
192 .with_address_type(AddressType::P2WPKH)
193 .with_case_sensitive(false)
194 .with_max_attempts(1_000_000)
195 .with_timeout(Duration::from_secs(60));
196
197 assert_eq!(config.address_type, AddressType::P2WPKH);
198 assert!(!config.case_sensitive);
199 assert_eq!(config.max_attempts, Some(1_000_000));
200 }
201}