@@ -25,7 +25,7 @@ use std::path::PathBuf;
2525pub static DIG_MIN_HEIGHT : u32 = 5777842 ;
2626pub static DIG_COIN_ASSET_ID : Lazy < Bytes32 > = Lazy :: new ( || {
2727 Bytes32 :: new ( hex ! (
28- "a0eff07522495060c066f66f32acc2a77e3a3e737aca8baea4d1a64ea4cdc13d "
28+ "a406d3a9de984d03c9591c10d917593b434d5263cabe2b42f6b367df16832f81 "
2929 ) )
3030} ) ;
3131const KEYRING_FILE : & str = "keyring.json" ;
@@ -294,12 +294,13 @@ impl Wallet {
294294 . map_err ( |e| WalletError :: CryptoError ( e. to_string ( ) ) )
295295 }
296296
297- /// Select unspent coins for spending
297+ /// Get all unspent DIG Token coins
298298 // todo: this should be moved to the driver
299299 pub async fn get_all_unspent_dig_coins (
300300 & self ,
301301 peer : & Peer ,
302302 omit_coins : Vec < Coin > ,
303+ verbose : bool ,
303304 ) -> Result < Vec < Coin > , WalletError > {
304305 let dig_cat = self . get_cat_coin_outer_puzzle ( ) . await ?;
305306 let dig_cat_ph = self . get_dig_coin_outer_puzzle_hash ( Some ( dig_cat) ) . await ?;
@@ -326,55 +327,148 @@ impl Wallet {
326327
327328 let mut proved_dig_token_coins: Vec < Coin > = vec ! [ ] ;
328329
330+ let mut allocator = Allocator :: new ( ) ;
331+
329332 for coin in & available_coins {
330- let parent_state = peer
333+ let coin_id = coin. coin_id ( ) ;
334+ let parent_state = match peer
331335 . request_coin_state (
332336 vec ! [ coin. parent_coin_info] ,
333337 None ,
334338 MAINNET_CONSTANTS . genesis_challenge ,
335339 false ,
336340 )
337341 . await
338- . map_err ( |e| WalletError :: NetworkError ( format ! ( "Failed to get coin state: {}" , e) ) ) ?
339- . map_err ( |_| WalletError :: CoinSetError ( "Coin state rejected" . to_string ( ) ) ) ?;
340-
341- let parent_puzzle_and_solution = peer
342+ {
343+ Ok ( response) => match response {
344+ Ok ( parent_state) => parent_state,
345+ Err ( _) => {
346+ if verbose {
347+ eprintln ! (
348+ "coin_id {} | {}" ,
349+ coin_id,
350+ WalletError :: CoinSetError ( "Coin state rejected" . to_string( ) )
351+ ) ;
352+ }
353+
354+ continue ;
355+ }
356+ } ,
357+ Err ( error) => {
358+ if verbose {
359+ eprintln ! (
360+ "coin_id {} | {}" ,
361+ coin_id,
362+ WalletError :: NetworkError ( format!(
363+ "Failed to get coin state: {}" ,
364+ error
365+ ) )
366+ ) ;
367+ }
368+
369+ continue ;
370+ }
371+ } ;
372+
373+ let parent_puzzle_and_solution = match peer
342374 . request_puzzle_and_solution ( parent_state. coin_ids [ 0 ] , DIG_MIN_HEIGHT )
343375 . await
344- . map_err ( |e| {
345- WalletError :: NetworkError ( format ! ( "Failed to get puzzle and solution: {}" , e) )
346- } ) ?
347- . map_err ( |_| WalletError :: CoinSetError ( "Coin state rejected" . to_string ( ) ) ) ?;
348-
349- let mut allocator = Allocator :: new ( ) ;
350-
351- let parent_puzzle_ptr = parent_puzzle_and_solution
352- . puzzle
353- . to_clvm ( & mut allocator)
354- . map_err ( |e| {
355- WalletError :: CoinSetError ( format ! ( "Failed to parse puzzle and solution: {}" , e) )
356- } ) ?;
376+ {
377+ Ok ( response) => match response {
378+ Ok ( puzzle_and_solution) => puzzle_and_solution,
379+ Err ( _) => {
380+ if verbose {
381+ eprintln ! (
382+ "coin_id {} | {}" ,
383+ coin_id,
384+ WalletError :: CoinSetError ( "Coin state rejected" . to_string( ) )
385+ ) ;
386+ }
387+
388+ continue ;
389+ }
390+ } ,
391+ Err ( error) => {
392+ if verbose {
393+ eprintln ! (
394+ "coin_id {} | {}" ,
395+ coin_id,
396+ WalletError :: NetworkError ( format!(
397+ "Failed to get puzzle and solution: {}" ,
398+ error
399+ ) )
400+ ) ;
401+ }
402+
403+ continue ;
404+ }
405+ } ;
406+
407+ let parent_puzzle_ptr = match parent_puzzle_and_solution. puzzle . to_clvm ( & mut allocator)
408+ {
409+ Ok ( puzzle_ptr) => puzzle_ptr,
410+ Err ( error) => {
411+ if verbose {
412+ eprintln ! (
413+ "coin_id {} | {}" ,
414+ coin_id,
415+ WalletError :: CoinSetError ( format!(
416+ "Failed to parse puzzle and solution: {}" ,
417+ error
418+ ) )
419+ ) ;
420+ }
421+
422+ continue ;
423+ }
424+ } ;
425+
357426 let parent_puzzle = Puzzle :: parse ( & allocator, parent_puzzle_ptr) ;
358- let parent_solution = parent_puzzle_and_solution
359- . solution
360- . to_clvm ( & mut allocator)
361- . map_err ( |e| {
362- WalletError :: CoinSetError ( format ! ( "Failed to parse puzzle and solution: {}" , e) )
363- } ) ?;
427+ let parent_solution = match parent_puzzle_and_solution. solution . to_clvm ( & mut allocator)
428+ {
429+ Ok ( solution) => solution,
430+ Err ( error) => {
431+ if verbose {
432+ eprintln ! (
433+ "coin_id {} | {}" ,
434+ coin_id,
435+ WalletError :: CoinSetError ( format!(
436+ "Failed to parse puzzle and solution: {}" ,
437+ error
438+ ) )
439+ ) ;
440+ }
441+
442+ continue ;
443+ }
444+ } ;
364445
365446 // this instantiation proves the lineage of the coin. not used beyond that
366- let _parsed_children = Cat :: parse_children (
447+ match Cat :: parse_children (
367448 & mut allocator,
368449 parent_state. coin_states [ 0 ] . coin ,
369450 parent_puzzle,
370451 parent_solution,
371- )
372- . map_err ( |e| {
373- WalletError :: CoinSetError ( format ! ( "Failed to parse puzzle and solution: {}" , e) )
374- } ) ?;
375-
376- // lineage proved. append coin in question
377- proved_dig_token_coins. push ( * coin) ;
452+ ) {
453+ Ok ( _) => {
454+ // lineage proved. append coin in question
455+ proved_dig_token_coins. push ( * coin) ;
456+ }
457+ Err ( error) => {
458+ if verbose {
459+ eprintln ! (
460+ "coin_id {} | {}" ,
461+ coin_id,
462+ WalletError :: CoinSetError ( format!(
463+ "Failed to parse CAT and prove lineage: {}" ,
464+ error
465+ ) )
466+ ) ;
467+ }
468+
469+ continue ;
470+ }
471+ }
378472 }
379473
380474 Ok ( proved_dig_token_coins)
@@ -386,9 +480,12 @@ impl Wallet {
386480 coin_amount : u64 ,
387481 fee : u64 ,
388482 omit_coins : Vec < Coin > ,
483+ verbose : bool ,
389484 ) -> Result < Vec < Coin > , WalletError > {
390485 let total_needed = coin_amount + fee;
391- let available_dig_coins = self . get_all_unspent_dig_coins ( peer, omit_coins) . await ?;
486+ let available_dig_coins = self
487+ . get_all_unspent_dig_coins ( peer, omit_coins, verbose)
488+ . await ?;
392489
393490 // Use the DataLayer-Driver's select_coins function
394491 let selected_coins = datalayer_driver:: select_coins ( & available_dig_coins, total_needed)
@@ -401,24 +498,21 @@ impl Wallet {
401498 Ok ( selected_coins)
402499 }
403500
404- pub async fn get_dig_balance ( & self , peer : & Peer ) -> Result < u64 , WalletError > {
405- let dig_coins = self . get_all_unspent_dig_coins ( peer, vec ! [ ] ) . await ?;
406- let dig_balance_mojos = dig_coins. iter ( ) . map ( |c| c. amount ) . sum :: < u64 > ( ) ;
407- Ok ( dig_balance_mojos)
501+ pub async fn get_dig_balance ( & self , peer : & Peer , verbose : bool ) -> Result < u64 , WalletError > {
502+ let dig_coins = self
503+ . get_all_unspent_dig_coins ( peer, vec ! [ ] , verbose)
504+ . await ?;
505+ let dig_balance = dig_coins. iter ( ) . map ( |c| c. amount ) . sum :: < u64 > ( ) ;
506+ Ok ( dig_balance)
408507 }
409508
410- /// Select unspent coins for spending
411- pub async fn select_unspent_coins (
509+ pub async fn get_all_unspent_xch_coins (
412510 & self ,
413511 peer : & Peer ,
414- coin_amount : u64 ,
415- fee : u64 ,
416512 omit_coins : Vec < Coin > ,
417513 ) -> Result < Vec < Coin > , WalletError > {
418514 let owner_puzzle_hash = self . get_owner_puzzle_hash ( ) . await ?;
419- let total_needed = coin_amount + fee;
420515
421- // Get unspent coin states from the DataLayer-Driver async API
422516 let coin_states = datalayer_driver:: async_api:: get_all_unspent_coins (
423517 peer,
424518 owner_puzzle_hash,
@@ -431,12 +525,25 @@ impl Wallet {
431525 // Convert coin states to coins and filter out omitted coins
432526 let omit_coin_ids: Vec < Bytes32 > = omit_coins. iter ( ) . map ( get_coin_id) . collect ( ) ;
433527
434- let available_coins : Vec < Coin > = coin_states
528+ Ok ( coin_states
435529 . coin_states
436530 . into_iter ( )
437531 . map ( |cs| cs. coin )
438532 . filter ( |coin| !omit_coin_ids. contains ( & get_coin_id ( coin) ) )
439- . collect ( ) ;
533+ . collect ( ) )
534+ }
535+
536+ /// Select unspent coins for spending
537+ pub async fn select_unspent_coins (
538+ & self ,
539+ peer : & Peer ,
540+ coin_amount : u64 ,
541+ fee : u64 ,
542+ omit_coins : Vec < Coin > ,
543+ ) -> Result < Vec < Coin > , WalletError > {
544+ let total_needed = coin_amount + fee;
545+
546+ let available_coins = self . get_all_unspent_xch_coins ( peer, omit_coins) . await ?;
440547
441548 // Use the DataLayer-Driver's select_coins function
442549 let selected_coins = datalayer_driver:: select_coins ( & available_coins, total_needed)
@@ -449,6 +556,12 @@ impl Wallet {
449556 Ok ( selected_coins)
450557 }
451558
559+ pub async fn get_xch_balance ( & self , peer : & Peer ) -> Result < u64 , WalletError > {
560+ let xch_coins = self . get_all_unspent_xch_coins ( peer, vec ! [ ] ) . await ?;
561+ let xch_balance = xch_coins. iter ( ) . map ( |c| c. amount ) . sum :: < u64 > ( ) ;
562+ Ok ( xch_balance)
563+ }
564+
452565 /// Calculate fee for coin spends
453566 pub async fn calculate_fee_for_coin_spends (
454567 _peer : & Peer ,
0 commit comments