22use  orchard:: note_encryption:: OrchardDomain ; 
33
44use  sapling_crypto:: note_encryption:: SaplingDomain ; 
5+ use  zcash_primitives:: transaction:: fees:: zip317:: MARGINAL_FEE ; 
56
67use  std:: { cmp,  sync:: Arc } ; 
78use  tokio:: sync:: RwLock ; 
@@ -82,6 +83,7 @@ impl LightWallet {
8283    } 
8384
8485    /// TODO: Add Doc Comment Here! 
86+ // TODO: this should minus the fee of sending the confirmed balance! 
8587    pub  async  fn  spendable_orchard_balance ( & self ,  target_addr :  Option < String > )  -> Option < u64 >  { 
8688        if  let  Capability :: Spend ( _)  = self . wallet_capability ( ) . orchard  { 
8789            self . verified_balance :: < OrchardDomain > ( target_addr) . await 
@@ -91,6 +93,7 @@ impl LightWallet {
9193    } 
9294
9395    /// TODO: Add Doc Comment Here! 
96+ // TODO: this should minus the fee of sending the confirmed balance! 
9497    pub  async  fn  spendable_sapling_balance ( & self ,  target_addr :  Option < String > )  -> Option < u64 >  { 
9598        if  let  Capability :: Spend ( _)  = self . wallet_capability ( ) . sapling  { 
9699            self . verified_balance :: < SaplingDomain > ( target_addr) . await 
@@ -161,12 +164,33 @@ impl LightWallet {
161164        self . shielded_balance :: < D > ( target_addr,  filters) . await 
162165    } 
163166
164-     /// TODO: Add Doc Comment Here! 
167+     /// Returns balance for a given shielded pool excluding any notes with value less than marginal fee 
168+ /// that are confirmed on the block chain (the block has at least 1 confirmation) 
169+ pub  async  fn  confirmed_balance_excluding_dust < D :  DomainWalletExt > ( 
170+         & self , 
171+         target_addr :  Option < String > , 
172+     )  -> Option < u64 > 
173+     where 
174+         <D  as  Domain >:: Recipient :  Recipient , 
175+         <D  as  Domain >:: Note :  PartialEq  + Clone , 
176+     { 
177+         #[ allow( clippy:: type_complexity) ]  
178+         let  filters:  & [ Box < dyn  Fn ( & & D :: WalletNote ,  & TransactionRecord )  -> bool > ]  = & [ 
179+             Box :: new ( |_,  transaction| transaction. status . is_confirmed ( ) ) , 
180+             Box :: new ( |note,  _| !note. pending_receipt ( ) ) , 
181+             Box :: new ( |note,  _| note. value ( )  >= MARGINAL_FEE . into_u64 ( ) ) , 
182+         ] ; 
183+         self . shielded_balance :: < D > ( target_addr,  filters) . await 
184+     } 
185+ 
186+     /// Deprecated for `shielded_balance` 
187+ #[ deprecated( note = "deprecated for `shielded_balance` as incorrectly named and unnecessary" ) ]  
165188    pub  async  fn  maybe_verified_orchard_balance ( & self ,  addr :  Option < String > )  -> Option < u64 >  { 
166189        self . shielded_balance :: < OrchardDomain > ( addr,  & [ ] ) . await 
167190    } 
168191
169-     /// TODO: Add Doc Comment Here! 
192+     /// Deprecated for `shielded_balance` 
193+ #[ deprecated( note = "deprecated for `shielded_balance` as incorrectly named and unnecessary" ) ]  
170194    pub  async  fn  maybe_verified_sapling_balance ( & self ,  addr :  Option < String > )  -> Option < u64 >  { 
171195        self . shielded_balance :: < SaplingDomain > ( addr,  & [ ] ) . await 
172196    } 
@@ -203,7 +227,7 @@ impl LightWallet {
203227    /// Get the height of the anchor block 
204228pub  async  fn  get_anchor_height ( & self )  -> u32  { 
205229        match  self . get_target_height_and_anchor_offset ( ) . await  { 
206-             Some ( ( height,  anchor_offset) )  => height - anchor_offset as  u32  - 1 , 
230+             Some ( ( height,  anchor_offset) )  => height - anchor_offset as  u32  - 1 ,   // what is the purpose of this -1 ? 
207231            None  => 0 , 
208232        } 
209233    } 
@@ -290,3 +314,101 @@ impl LightWallet {
290314        self . transaction_context . transaction_metadata_set . clone ( ) 
291315    } 
292316} 
317+ 
318+ #[ cfg( test) ]  
319+ mod  tests { 
320+     use  orchard:: note_encryption:: OrchardDomain ; 
321+     use  sapling_crypto:: note_encryption:: SaplingDomain ; 
322+ 
323+     use  zingo_status:: confirmation_status:: ConfirmationStatus ; 
324+     use  zingoconfig:: ZingoConfigBuilder ; 
325+ 
326+     use  crate :: { 
327+         mocks:: { orchard_note:: OrchardCryptoNoteBuilder ,  SaplingCryptoNoteBuilder } , 
328+         wallet:: { 
329+             notes:: { 
330+                 orchard:: mocks:: OrchardNoteBuilder ,  sapling:: mocks:: SaplingNoteBuilder , 
331+                 transparent:: mocks:: TransparentOutputBuilder , 
332+             } , 
333+             transaction_record:: mocks:: TransactionRecordBuilder , 
334+             LightWallet ,  WalletBase , 
335+         } , 
336+     } ; 
337+ 
338+     #[ tokio:: test]  
339+     async  fn  confirmed_balance_excluding_dust ( )  { 
340+         let  wallet = LightWallet :: new ( 
341+             ZingoConfigBuilder :: default ( ) . create ( ) , 
342+             WalletBase :: FreshEntropy , 
343+             1 , 
344+         ) 
345+         . unwrap ( ) ; 
346+         let  confirmed_tx_record = TransactionRecordBuilder :: default ( ) 
347+             . status ( ConfirmationStatus :: Confirmed ( 80 . into ( ) ) ) 
348+             . transparent_outputs ( TransparentOutputBuilder :: default ( ) ) 
349+             . sapling_notes ( SaplingNoteBuilder :: default ( ) ) 
350+             . sapling_notes ( SaplingNoteBuilder :: default ( ) ) 
351+             . sapling_notes ( 
352+                 SaplingNoteBuilder :: default ( ) 
353+                     . note ( 
354+                         SaplingCryptoNoteBuilder :: default ( ) 
355+                             . value ( sapling_crypto:: value:: NoteValue :: from_raw ( 3_000 ) ) 
356+                             . clone ( ) , 
357+                     ) 
358+                     . clone ( ) , 
359+             ) 
360+             . orchard_notes ( OrchardNoteBuilder :: default ( ) ) 
361+             . orchard_notes ( OrchardNoteBuilder :: default ( ) ) 
362+             . orchard_notes ( 
363+                 OrchardNoteBuilder :: default ( ) 
364+                     . note ( 
365+                         OrchardCryptoNoteBuilder :: default ( ) 
366+                             . value ( orchard:: value:: NoteValue :: from_raw ( 5_000 ) ) 
367+                             . clone ( ) , 
368+                     ) 
369+                     . clone ( ) , 
370+             ) 
371+             . orchard_notes ( 
372+                 OrchardNoteBuilder :: default ( ) 
373+                     . note ( 
374+                         OrchardCryptoNoteBuilder :: default ( ) 
375+                             . value ( orchard:: value:: NoteValue :: from_raw ( 2_000 ) ) 
376+                             . clone ( ) , 
377+                     ) 
378+                     . clone ( ) , 
379+             ) 
380+             . build ( ) ; 
381+         let  pending_tx_record = TransactionRecordBuilder :: default ( ) 
382+             . status ( ConfirmationStatus :: Pending ( 95 . into ( ) ) ) 
383+             . transparent_outputs ( TransparentOutputBuilder :: default ( ) ) 
384+             . sapling_notes ( SaplingNoteBuilder :: default ( ) ) 
385+             . orchard_notes ( OrchardNoteBuilder :: default ( ) ) 
386+             . build ( ) ; 
387+         { 
388+             let  mut  tx_map = wallet
389+                 . transaction_context 
390+                 . transaction_metadata_set 
391+                 . write ( ) 
392+                 . await ; 
393+             tx_map
394+                 . transaction_records_by_id 
395+                 . insert_transaction_record ( confirmed_tx_record) ; 
396+             tx_map
397+                 . transaction_records_by_id 
398+                 . insert_transaction_record ( pending_tx_record) ; 
399+         } 
400+ 
401+         assert_eq ! ( 
402+             wallet
403+                 . confirmed_balance_excluding_dust:: <SaplingDomain >( None ) 
404+                 . await , 
405+             Some ( 400_000 ) 
406+         ) ; 
407+         assert_eq ! ( 
408+             wallet
409+                 . confirmed_balance_excluding_dust:: <OrchardDomain >( None ) 
410+                 . await , 
411+             Some ( 1_605_000 ) 
412+         ) ; 
413+     } 
414+ } 
0 commit comments