@@ -18,6 +18,7 @@ pub use bridge::{TraceListener, WalletEventListener, WalletListenerBox};
1818pub use database:: { Database , RecentWallet } ;
1919use throttle:: Throttle ;
2020
21+ use std:: io:: Cursor ;
2122use std:: panic:: { catch_unwind, AssertUnwindSafe } ;
2223use std:: sync:: { Arc , Mutex } ;
2324use std:: {
@@ -584,6 +585,59 @@ impl WalletHandle {
584585 . context ( "Couldn't complete wallet call" ) ?
585586 }
586587
588+ /// Get the secret view key of the wallet.
589+ pub async fn secret_view_key ( & self ) -> anyhow:: Result < curve25519_dalek:: scalar:: Scalar > {
590+ let secret_view_key = self
591+ . call ( move |wallet| wallet. secret_view_key ( ) )
592+ . await
593+ . context ( "Couldn't complete wallet call" ) ?
594+ . context ( "Couldn't get secret view key string from wallet2" ) ?;
595+
596+ let secret_view_key_bytes = hex:: decode ( & secret_view_key)
597+ . context ( "Failed to decode secret view key string from wallet2 from hex to bytes" ) ?;
598+
599+ let secret_view_key: [ u8 ; 32 ] =
600+ secret_view_key_bytes. try_into ( ) . map_err ( |v : Vec < u8 > | {
601+ anyhow ! (
602+ "Secret view key has wrong length: expected 32 bytes, got {}" ,
603+ v. len( )
604+ )
605+ } ) ?;
606+
607+ let private_view_key =
608+ curve25519_dalek:: scalar:: Scalar :: from_canonical_bytes ( secret_view_key)
609+ . into_option ( )
610+ . context ( "Failed to convert secret view key bytes to Scalar" ) ?;
611+
612+ Ok ( private_view_key)
613+ }
614+
615+ /// Get the public spend key of the wallet.
616+ pub async fn public_spend_key (
617+ & self ,
618+ ) -> anyhow:: Result < curve25519_dalek:: edwards:: CompressedEdwardsY > {
619+ let public_spend_key = self
620+ . call ( move |wallet| wallet. public_spend_key ( ) )
621+ . await
622+ . context ( "Couldn't complete wallet call" ) ?
623+ . context ( "Couldn't get public spend key string from wallet2" ) ?;
624+
625+ let public_spend_key_bytes = hex:: decode ( & public_spend_key)
626+ . context ( "Failed to decode public spend key string from wallet2 from hex to bytes" ) ?;
627+
628+ let public_spend_key: [ u8 ; 32 ] =
629+ public_spend_key_bytes. try_into ( ) . map_err ( |v : Vec < u8 > | {
630+ anyhow ! (
631+ "Public spend key has wrong length: expected 32 bytes, got {}" ,
632+ v. len( )
633+ )
634+ } ) ?;
635+
636+ Ok ( curve25519_dalek:: edwards:: CompressedEdwardsY (
637+ public_spend_key,
638+ ) )
639+ }
640+
587641 /// Get the creation height of the wallet.
588642 pub async fn creation_height ( & self ) -> anyhow:: Result < u64 > {
589643 self . call ( move |wallet| wallet. creation_height ( ) )
@@ -946,7 +1000,6 @@ impl WalletHandle {
9461000 Ok ( ( ) )
9471001 }
9481002
949-
9501003 /// Wait for an incoming transaction with at least the specified amount.
9511004 ///
9521005 /// This method polls the wallet's transaction history at the specified interval
@@ -985,7 +1038,7 @@ impl WalletHandle {
9851038 confirmations = tx. confirmations,
9861039 "Found incoming transaction that meets the amount lower bound"
9871040 ) ;
988-
1041+
9891042 return Ok ( tx) ;
9901043 }
9911044 }
@@ -2664,6 +2717,32 @@ impl FfiWallet {
26642717 Ok ( seed)
26652718 }
26662719
2720+ /// Get the secret view key of the wallet.
2721+ fn secret_view_key ( & self ) -> anyhow:: Result < String > {
2722+ let key = ffi:: secretViewKey ( & self . inner )
2723+ . context ( "Failed to get secret view key" ) ?
2724+ . to_string ( ) ;
2725+
2726+ if key. is_empty ( ) {
2727+ bail ! ( "Failed to get secret view key" ) ;
2728+ }
2729+
2730+ Ok ( key)
2731+ }
2732+
2733+ /// Get the public spend key of the wallet.
2734+ fn public_spend_key ( & self ) -> anyhow:: Result < String > {
2735+ let key = ffi:: publicSpendKey ( & self . inner )
2736+ . context ( "Failed to get public spend key" ) ?
2737+ . to_string ( ) ;
2738+
2739+ if key. is_empty ( ) {
2740+ bail ! ( "wallet2 returned an empty public spend key" ) ;
2741+ }
2742+
2743+ Ok ( key)
2744+ }
2745+
26672746 /// Sign a message with the wallet's private key.
26682747 ///
26692748 /// # Arguments
0 commit comments