@@ -4,9 +4,7 @@ use iced::mouse;
44use iced:: widget:: canvas:: { self , path, Canvas } ;
55use iced:: {
66 executor, theme,
7- widget:: {
8- button, column, container, pick_list, progress_bar, row, svg, text, text_input, Container ,
9- } ,
7+ widget:: { button, column, container, progress_bar, row, svg, text, text_input, Container } ,
108 Alignment , Application , Border , Color , Command , Element , Font , Length , Settings , Size , Theme ,
119} ;
1210use std:: sync:: {
@@ -51,8 +49,8 @@ fn load_logo() -> svg::Handle {
5149}
5250
5351pub struct VanityApp {
54- // 链选择
55- selected_chain : ChainType ,
52+ // 链选择(多选)
53+ selected_chains : Vec < ChainType > ,
5654
5755 // 配置
5856 patterns_input : String ,
@@ -86,7 +84,8 @@ pub struct VanityApp {
8684 pause_signal : Arc < AtomicBool > ,
8785 gen_count : Arc < AtomicU64 > ,
8886 found_count : Arc < AtomicU64 > ,
89- vanity_cache : Arc < Mutex < Option < VanityAddress > > > ,
87+ // 缓存匹配结果,附带完整三链展示文本
88+ vanity_cache : Arc < Mutex < Option < ( VanityAddress , String ) > > > ,
9089
9190 // 最近发现的靓号(用于手动保存)
9291 last_found : Option < VanityAddress > ,
@@ -101,7 +100,7 @@ pub struct VanityApp {
101100impl Default for VanityApp {
102101 fn default ( ) -> Self {
103102 Self {
104- selected_chain : ChainType :: Tron ,
103+ selected_chains : vec ! [ ChainType :: Tron ] ,
105104 batch_size : "1000" . to_string ( ) ,
106105 thread_count : num_cpus:: get ( ) . to_string ( ) ,
107106 patterns_input : "1111,2222,3333,4444,5555,6666,7777,8888,9999,0000" . to_string ( ) ,
@@ -143,7 +142,7 @@ impl VanityApp {
143142
144143#[ derive( Debug , Clone ) ]
145144pub enum Message {
146- ChainChanged ( ChainType ) ,
145+ ChainToggled ( ChainType ) ,
147146 PatternsChanged ( String ) ,
148147 BatchSizeChanged ( String ) ,
149148 ThreadCountChanged ( String ) ,
@@ -172,7 +171,13 @@ impl Application for VanityApp {
172171
173172 fn update ( & mut self , message : Message ) -> Command < Message > {
174173 match message {
175- Message :: ChainChanged ( chain) => self . selected_chain = chain,
174+ Message :: ChainToggled ( chain) => {
175+ if let Some ( pos) = self . selected_chains . iter ( ) . position ( |c| c == & chain) {
176+ self . selected_chains . remove ( pos) ;
177+ } else {
178+ self . selected_chains . push ( chain) ;
179+ }
180+ }
176181 Message :: PatternsChanged ( input) => self . patterns_input = input,
177182 Message :: BatchSizeChanged ( input) => self . batch_size = input,
178183 Message :: ThreadCountChanged ( input) => self . thread_count = input,
@@ -196,7 +201,7 @@ impl Application for VanityApp {
196201 }
197202 }
198203 Message :: StartPressed => {
199- if !self . is_running {
204+ if !self . is_running && ! self . selected_chains . is_empty ( ) {
200205 self . is_running = true ;
201206 self . is_paused = false ;
202207 self . total_generated = 0 ;
@@ -206,16 +211,22 @@ impl Application for VanityApp {
206211 self . start_time = Some ( Instant :: now ( ) ) ;
207212 self . gen_start_time = Some ( Instant :: now ( ) ) ;
208213 self . log_messages . clear ( ) ;
214+
215+ let chains_str = self . selected_chains
216+ . iter ( )
217+ . map ( |c| c. label ( ) )
218+ . collect :: < Vec < _ > > ( )
219+ . join ( " | " ) ;
209220 self . log_messages . push ( format ! (
210- "▶ {} 启动,开始搜索靓号..." ,
211- self . selected_chain . label ( )
221+ "▶ [{}] 启动,开始搜索靓号..." ,
222+ chains_str
212223 ) ) ;
213224
214225 let stop_signal = Arc :: clone ( & self . stop_signal ) ;
215226 let pause_signal = Arc :: clone ( & self . pause_signal ) ;
216227 let gen_count = Arc :: clone ( & self . gen_count ) ;
217228 let found_count = Arc :: clone ( & self . found_count ) ;
218- let chain = self . selected_chain ;
229+ let selected_chains = self . selected_chains . clone ( ) ;
219230
220231 stop_signal. store ( false , Ordering :: Relaxed ) ;
221232 pause_signal. store ( false , Ordering :: Relaxed ) ;
@@ -243,7 +254,7 @@ impl Application for VanityApp {
243254 let found = Arc :: clone ( & found_count) ;
244255 let vanity_cache = Arc :: clone ( & self . vanity_cache ) ;
245256 let patterns_clone = patterns. clone ( ) ;
246- let chain_copy = chain ;
257+ let chains_copy = selected_chains . clone ( ) ;
247258 let save_path = self . save_file_path . clone ( ) ;
248259
249260 thread:: spawn ( move || loop {
@@ -257,16 +268,40 @@ impl Application for VanityApp {
257268 }
258269
259270 for _ in 0 ..batch {
260- let addr = generate_vanity_address ( chain_copy) ;
271+ // 生成单个助记词对应的三种链地址
272+ let mnemonic = generate_mnemonic ( ) ;
273+ let multi_addr = generate_from_mnemonic_all ( & mnemonic) ;
274+
261275 let patterns_refs: Vec < & str > =
262276 patterns_clone. iter ( ) . map ( |s| s. as_str ( ) ) . collect ( ) ;
263- if is_vanity_address ( & addr. address , & patterns_refs) {
264- found. fetch_add ( 1 , Ordering :: Relaxed ) ;
265- // 保存到用户指定的文件
266- let _ = save_address_to_file ( & save_path, & addr, true ) ;
267- // 缓存靓号信息用于 UI 显示
268- if let Ok ( mut cache) = vanity_cache. lock ( ) {
269- * cache = Some ( addr. clone ( ) ) ;
277+
278+ // 对每个选中的链进行匹配
279+ let addresses = vec ! [
280+ ( & multi_addr. tron, ChainType :: Tron ) ,
281+ ( & multi_addr. evm, ChainType :: Evm ) ,
282+ ( & multi_addr. sol, ChainType :: Sol ) ,
283+ ] ;
284+
285+ for ( addr, chain_type) in addresses {
286+ if chains_copy. contains ( & chain_type)
287+ && is_vanity_address ( & addr. address , & patterns_refs)
288+ {
289+ found. fetch_add ( 1 , Ordering :: Relaxed ) ;
290+ let _ =
291+ save_multi_address_to_file ( & save_path, & multi_addr, chain_type) ;
292+
293+ let display = format ! (
294+ "✨ 发现靓号: [{}] {} | TRON: {} | EVM: {} | SOL: {}" ,
295+ chain_type. label( ) ,
296+ addr. address,
297+ multi_addr. tron. address,
298+ multi_addr. evm. address,
299+ multi_addr. sol. address,
300+ ) ;
301+
302+ if let Ok ( mut cache) = vanity_cache. lock ( ) {
303+ * cache = Some ( ( addr. clone ( ) , display) ) ;
304+ }
270305 }
271306 }
272307 gen. fetch_add ( 1 , Ordering :: Relaxed ) ;
@@ -324,15 +359,8 @@ impl Application for VanityApp {
324359
325360 // 检查是否有新的靓号
326361 if let Ok ( mut cache) = self . vanity_cache . lock ( ) {
327- if let Some ( vanity_info) = cache. take ( ) {
328- self . log_messages . insert (
329- 0 ,
330- format ! (
331- "✨ 发现靓号: [{}] {}" ,
332- vanity_info. chain. label( ) ,
333- vanity_info. address
334- ) ,
335- ) ;
362+ if let Some ( ( vanity_info, display) ) = cache. take ( ) {
363+ self . log_messages . insert ( 0 , display) ;
336364 self . last_found = Some ( vanity_info) ;
337365 }
338366 }
@@ -364,6 +392,33 @@ impl Application for VanityApp {
364392 fn view ( & self ) -> Element < ' _ , Message > {
365393 const CHAINS : [ ChainType ; 3 ] = [ ChainType :: Tron , ChainType :: Evm , ChainType :: Sol ] ;
366394
395+ // 构建链选择按钮组(多选)
396+ let chain_buttons = CHAINS
397+ . iter ( )
398+ . fold ( row ! [ ] . spacing ( 8 ) , |row, & chain| {
399+ let is_selected = self . selected_chains . contains ( & chain) ;
400+ let btn = if is_selected {
401+ button (
402+ text ( chain. label ( ) )
403+ . size ( 14 )
404+ . style ( iced:: theme:: Text :: Color ( Color :: from_rgb8 ( 255 , 255 , 255 ) ) ) ,
405+ )
406+ . padding ( 10 )
407+ . style ( iced:: theme:: Button :: Positive )
408+ . on_press ( Message :: ChainToggled ( chain) )
409+ } else {
410+ button (
411+ text ( chain. label ( ) )
412+ . size ( 14 )
413+ . style ( iced:: theme:: Text :: Color ( Color :: from_rgb8 ( 142 , 162 , 185 ) ) ) ,
414+ )
415+ . padding ( 10 )
416+ . style ( iced:: theme:: Button :: Secondary )
417+ . on_press ( Message :: ChainToggled ( chain) )
418+ } ;
419+ row. push ( btn)
420+ } ) ;
421+
367422 let header = row ! [
368423 svg( self . logo_handle. clone( ) )
369424 . width( Length :: Fixed ( 40.0 ) )
@@ -379,10 +434,11 @@ impl Application for VanityApp {
379434 . spacing( 4 )
380435 . width( Length :: Fill )
381436 . align_items( Alignment :: Start ) ,
382- pick_list( CHAINS , Some ( self . selected_chain) , Message :: ChainChanged )
383- . placeholder( "选择链" )
384- . padding( 10 )
385- . width( Length :: Fixed ( 150.0 ) ) ,
437+ column![
438+ text( "选择链" ) . size( 12 ) . style( iced:: theme:: Text :: Color ( accent( ) ) ) ,
439+ chain_buttons,
440+ ]
441+ . spacing( 6 ) ,
386442 ]
387443 . spacing ( 12 )
388444 . align_items ( Alignment :: Center ) ;
@@ -429,13 +485,14 @@ impl Application for VanityApp {
429485
430486 let controls = row ! [
431487 primary_button( "启动" , Message :: StartPressed ) ,
488+ danger_button( "停止" , Message :: StopPressed ) ,
432489 ghost_button(
433490 if self . is_paused { "继续" } else { "暂停" } ,
434491 Message :: PausePressed
435492 ) ,
436- danger_button( "停止" , Message :: StopPressed ) ,
437493 ]
438- . spacing ( 12 ) ;
494+ . spacing ( 14 )
495+ . align_items ( Alignment :: Center ) ;
439496
440497 let uptime = self . start_time . map ( |t| t. elapsed ( ) . as_secs ( ) ) . unwrap_or ( 0 ) ;
441498
0 commit comments