Skip to content

Commit a096557

Browse files
authored
Merge pull request #3 from DIG-Network/0.3.0
0.3.0
2 parents 9960b17 + 143d6ac commit a096557

File tree

1 file changed

+160
-47
lines changed

1 file changed

+160
-47
lines changed

src/wallet.rs

Lines changed: 160 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use std::path::PathBuf;
2525
pub static DIG_MIN_HEIGHT: u32 = 5777842;
2626
pub static DIG_COIN_ASSET_ID: Lazy<Bytes32> = Lazy::new(|| {
2727
Bytes32::new(hex!(
28-
"a0eff07522495060c066f66f32acc2a77e3a3e737aca8baea4d1a64ea4cdc13d"
28+
"a406d3a9de984d03c9591c10d917593b434d5263cabe2b42f6b367df16832f81"
2929
))
3030
});
3131
const 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

Comments
 (0)