Added tests for DescriptorSecretKey and DescriptorPublicKey
This commit is contained in:
		
							parent
							
								
									58fea6b205
								
							
						
					
					
						commit
						5944756b78
					
				
							
								
								
									
										23
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @ -5,6 +5,29 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | |||||||
| and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||||||
| 
 | 
 | ||||||
| ## [Unreleased] | ## [Unreleased] | ||||||
|  | - APIs Added [#154] | ||||||
|  |   - `generate_mnemonic()`, returns string mnemonic | ||||||
|  |   - `interface DescriptorSecretKey` | ||||||
|  |     - `new(Network, string_mnenoinc, password)`, contructs DescriptorSecretKey | ||||||
|  |     - `derive(DerivationPath)`, derives and returns child DescriptorSecretKey | ||||||
|  |     - `extend(DerivationPath)`, extends and returns DescriptorSecretKey | ||||||
|  |     - `as_public()`, returns DescriptorSecretKey as DescriptorPublicKey | ||||||
|  |     - `as_string()`, returns DescriptorSecretKey as String | ||||||
|  |   - `interface DescriptorPublicKey` | ||||||
|  |     - `derive(DerivationPath)` derives and returns child DescriptorPublicKey | ||||||
|  |     - `extend(DerivationPath)` extends and returns DescriptorPublicKey | ||||||
|  |     - `as_string()` returns DescriptorPublicKey as String | ||||||
|  | - Interfaces Added [#154] | ||||||
|  |   - `DescriptorSecretKey` | ||||||
|  |   - `DescriptorPublicKey` | ||||||
|  |   - `DerivationPath` | ||||||
|  | - Dictionary Removed [#154] | ||||||
|  |   - `ExtendedKeyInfo {mnenonic, xprv, fingerprint}`  | ||||||
|  | - APIs Removed [#154] | ||||||
|  |   - `generate_extended_key`, returned ExtendedKeyInfo | ||||||
|  |   - `restore_extended_key`, returned ExtendedKeyInfo | ||||||
|  | 
 | ||||||
|  | [#154]: https://github.com/bitcoindevkit/bdk-ffi/pull/154 | ||||||
| 
 | 
 | ||||||
| ## [v0.8.0] | ## [v0.8.0] | ||||||
| - Update BDK to version 0.20.0 [#169] | - Update BDK to version 0.20.0 [#169] | ||||||
|  | |||||||
							
								
								
									
										145
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										145
									
								
								src/lib.rs
									
									
									
									
									
								
							| @ -676,11 +676,8 @@ impl DescriptorSecretKey { | |||||||
|         let secp = Secp256k1::new(); |         let secp = Secp256k1::new(); | ||||||
|         let descriptor_secret_key = self.descriptor_secret_key_mutex.lock().unwrap(); |         let descriptor_secret_key = self.descriptor_secret_key_mutex.lock().unwrap(); | ||||||
|         let path = path.derivation_path_mutex.lock().unwrap().deref().clone(); |         let path = path.derivation_path_mutex.lock().unwrap().deref().clone(); | ||||||
|         let descriptor_x_key = match descriptor_secret_key.deref() { |         match descriptor_secret_key.deref() { | ||||||
|             BdkDescriptorSecretKey::XPrv(descriptor_x_key) => Some(descriptor_x_key), |             BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { | ||||||
|             _ => None, |  | ||||||
|         } |  | ||||||
|         .unwrap(); |  | ||||||
|                 let derived_xprv = descriptor_x_key.xkey.derive_priv(&secp, &path)?; |                 let derived_xprv = descriptor_x_key.xkey.derive_priv(&secp, &path)?; | ||||||
|                 let key_source = match descriptor_x_key.origin.clone() { |                 let key_source = match descriptor_x_key.origin.clone() { | ||||||
|                     Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(path)), |                     Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(path)), | ||||||
| @ -696,15 +693,17 @@ impl DescriptorSecretKey { | |||||||
|                     descriptor_secret_key_mutex: Mutex::new(derived_descriptor_secret_key), |                     descriptor_secret_key_mutex: Mutex::new(derived_descriptor_secret_key), | ||||||
|                 })) |                 })) | ||||||
|             } |             } | ||||||
|  |             BdkDescriptorSecretKey::SinglePriv(_) => { | ||||||
|  |                 unreachable!() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     fn extend(&self, path: Arc<DerivationPath>) -> Arc<Self> { |     fn extend(&self, path: Arc<DerivationPath>) -> Arc<Self> { | ||||||
|         let descriptor_secret_key = self.descriptor_secret_key_mutex.lock().unwrap(); |         let descriptor_secret_key = self.descriptor_secret_key_mutex.lock().unwrap(); | ||||||
|         let path = path.derivation_path_mutex.lock().unwrap().deref().clone(); |         let path = path.derivation_path_mutex.lock().unwrap().deref().clone(); | ||||||
|         let descriptor_x_key = match descriptor_secret_key.deref() { |         match descriptor_secret_key.deref() { | ||||||
|             BdkDescriptorSecretKey::XPrv(descriptor_x_key) => Some(descriptor_x_key), |             BdkDescriptorSecretKey::XPrv(descriptor_x_key) => { | ||||||
|             _ => None, |  | ||||||
|         } |  | ||||||
|         .unwrap(); |  | ||||||
|                 let extended_path = descriptor_x_key.derivation_path.extend(path); |                 let extended_path = descriptor_x_key.derivation_path.extend(path); | ||||||
|                 let extended_descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey { |                 let extended_descriptor_secret_key = BdkDescriptorSecretKey::XPrv(DescriptorXKey { | ||||||
|                     origin: descriptor_x_key.origin.clone(), |                     origin: descriptor_x_key.origin.clone(), | ||||||
| @ -716,6 +715,11 @@ impl DescriptorSecretKey { | |||||||
|                     descriptor_secret_key_mutex: Mutex::new(extended_descriptor_secret_key), |                     descriptor_secret_key_mutex: Mutex::new(extended_descriptor_secret_key), | ||||||
|                 }) |                 }) | ||||||
|             } |             } | ||||||
|  |             BdkDescriptorSecretKey::SinglePriv(_) => { | ||||||
|  |                 unreachable!() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     fn as_public(&self) -> Arc<DescriptorPublicKey> { |     fn as_public(&self) -> Arc<DescriptorPublicKey> { | ||||||
|         let secp = Secp256k1::new(); |         let secp = Secp256k1::new(); | ||||||
| @ -744,11 +748,9 @@ impl DescriptorPublicKey { | |||||||
|         let secp = Secp256k1::new(); |         let secp = Secp256k1::new(); | ||||||
|         let descriptor_public_key = self.descriptor_public_key_mutex.lock().unwrap(); |         let descriptor_public_key = self.descriptor_public_key_mutex.lock().unwrap(); | ||||||
|         let path = path.derivation_path_mutex.lock().unwrap().deref().clone(); |         let path = path.derivation_path_mutex.lock().unwrap().deref().clone(); | ||||||
|         let descriptor_x_key = match descriptor_public_key.deref() { | 
 | ||||||
|             BdkDescriptorPublicKey::XPub(descriptor_x_key) => Some(descriptor_x_key), |         match descriptor_public_key.deref() { | ||||||
|             _ => None, |             BdkDescriptorPublicKey::XPub(descriptor_x_key) => { | ||||||
|         } |  | ||||||
|         .unwrap(); |  | ||||||
|                 let derived_xpub = descriptor_x_key.xkey.derive_pub(&secp, &path)?; |                 let derived_xpub = descriptor_x_key.xkey.derive_pub(&secp, &path)?; | ||||||
|                 let key_source = match descriptor_x_key.origin.clone() { |                 let key_source = match descriptor_x_key.origin.clone() { | ||||||
|                     Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(path)), |                     Some((fingerprint, origin_path)) => (fingerprint, origin_path.extend(path)), | ||||||
| @ -764,15 +766,17 @@ impl DescriptorPublicKey { | |||||||
|                     descriptor_public_key_mutex: Mutex::new(derived_descriptor_public_key), |                     descriptor_public_key_mutex: Mutex::new(derived_descriptor_public_key), | ||||||
|                 })) |                 })) | ||||||
|             } |             } | ||||||
|  |             BdkDescriptorPublicKey::SinglePub(_) => { | ||||||
|  |                 unreachable!() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     fn extend(&self, path: Arc<DerivationPath>) -> Arc<Self> { |     fn extend(&self, path: Arc<DerivationPath>) -> Arc<Self> { | ||||||
|         let descriptor_secret_key = self.descriptor_public_key_mutex.lock().unwrap(); |         let descriptor_public_key = self.descriptor_public_key_mutex.lock().unwrap(); | ||||||
|         let path = path.derivation_path_mutex.lock().unwrap().deref().clone(); |         let path = path.derivation_path_mutex.lock().unwrap().deref().clone(); | ||||||
|         let descriptor_x_key = match descriptor_secret_key.deref() { |         match descriptor_public_key.deref() { | ||||||
|             BdkDescriptorPublicKey::XPub(descriptor_x_key) => Some(descriptor_x_key), |             BdkDescriptorPublicKey::XPub(descriptor_x_key) => { | ||||||
|             _ => None, |  | ||||||
|         } |  | ||||||
|         .unwrap(); |  | ||||||
|                 let extended_path = descriptor_x_key.derivation_path.extend(path); |                 let extended_path = descriptor_x_key.derivation_path.extend(path); | ||||||
|                 let extended_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey { |                 let extended_descriptor_public_key = BdkDescriptorPublicKey::XPub(DescriptorXKey { | ||||||
|                     origin: descriptor_x_key.origin.clone(), |                     origin: descriptor_x_key.origin.clone(), | ||||||
| @ -784,6 +788,11 @@ impl DescriptorPublicKey { | |||||||
|                     descriptor_public_key_mutex: Mutex::new(extended_descriptor_public_key), |                     descriptor_public_key_mutex: Mutex::new(extended_descriptor_public_key), | ||||||
|                 }) |                 }) | ||||||
|             } |             } | ||||||
|  |             BdkDescriptorPublicKey::SinglePub(_) => { | ||||||
|  |                 unreachable!() | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     fn as_string(&self) -> String { |     fn as_string(&self) -> String { | ||||||
|         self.descriptor_public_key_mutex.lock().unwrap().to_string() |         self.descriptor_public_key_mutex.lock().unwrap().to_string() | ||||||
| @ -797,7 +806,7 @@ uniffi::deps::static_assertions::assert_impl_all!(Wallet: Sync, Send); | |||||||
| // crate.
 | // crate.
 | ||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| mod test { | mod test { | ||||||
|     use crate::{TxBuilder, Wallet}; |     use crate::*; | ||||||
|     use bdk::bitcoin::Address; |     use bdk::bitcoin::Address; | ||||||
|     use bdk::bitcoin::Network::Testnet; |     use bdk::bitcoin::Network::Testnet; | ||||||
|     use bdk::wallet::get_funded_wallet; |     use bdk::wallet::get_funded_wallet; | ||||||
| @ -857,4 +866,96 @@ mod test { | |||||||
|         let output_value = psbt.unsigned_tx.output.get(0).cloned().unwrap().value; |         let output_value = psbt.unsigned_tx.output.get(0).cloned().unwrap().value; | ||||||
|         assert_eq!(output_value, 49_890_u64); // input - fee
 |         assert_eq!(output_value, 49_890_u64); // input - fee
 | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     fn get_descriptor_secret_key() -> DescriptorSecretKey { | ||||||
|  |         let mnemonic = | ||||||
|  |         "chaos fabric time speed sponsor all flat solution wisdom trophy crack object robot pave observe combine where aware bench orient secret primary cable detect".to_string(); | ||||||
|  |         DescriptorSecretKey::new(Network::Testnet, mnemonic, None).unwrap() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn derive_dsk( | ||||||
|  |         key: &DescriptorSecretKey, | ||||||
|  |         path: &str, | ||||||
|  |     ) -> Result<Arc<DescriptorSecretKey>, BdkError> { | ||||||
|  |         let path = Arc::new(DerivationPath::new(path.to_string()).unwrap()); | ||||||
|  |         key.derive(path) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn extend_dsk(key: &DescriptorSecretKey, path: &str) -> Arc<DescriptorSecretKey> { | ||||||
|  |         let path = Arc::new(DerivationPath::new(path.to_string()).unwrap()); | ||||||
|  |         key.extend(path) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn derive_dpk( | ||||||
|  |         key: &DescriptorPublicKey, | ||||||
|  |         path: &str, | ||||||
|  |     ) -> Result<Arc<DescriptorPublicKey>, BdkError> { | ||||||
|  |         let path = Arc::new(DerivationPath::new(path.to_string()).unwrap()); | ||||||
|  |         key.derive(path) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn extend_dpk(key: &DescriptorPublicKey, path: &str) -> Arc<DescriptorPublicKey> { | ||||||
|  |         let path = Arc::new(DerivationPath::new(path.to_string()).unwrap()); | ||||||
|  |         key.extend(path) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_generate_descriptor_secret_key() { | ||||||
|  |         let master_dsk = get_descriptor_secret_key(); | ||||||
|  |         assert_eq!(master_dsk.as_string(), "tprv8ZgxMBicQKsPdWuqM1t1CDRvQtQuBPyfL6GbhQwtxDKgUAVPbxmj71pRA8raTqLrec5LyTs5TqCxdABcZr77bt2KyWA5bizJHnC4g4ysm4h/*"); | ||||||
|  |         assert_eq!(master_dsk.as_public().as_string(), "tpubD6NzVbkrYhZ4WywdEfYbbd62yuvqLjAZuPsNyvzCNV85JekAEMbKHWSHLF9h3j45SxewXDcLv328B1SEZrxg4iwGfmdt1pDFjZiTkGiFqGa/*"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_derive_self() { | ||||||
|  |         let master_dsk = get_descriptor_secret_key(); | ||||||
|  |         let derived_dsk: &DescriptorSecretKey = &derive_dsk(&master_dsk, "m").unwrap(); | ||||||
|  |         assert_eq!(derived_dsk.as_string(), "[d1d04177]tprv8ZgxMBicQKsPdWuqM1t1CDRvQtQuBPyfL6GbhQwtxDKgUAVPbxmj71pRA8raTqLrec5LyTs5TqCxdABcZr77bt2KyWA5bizJHnC4g4ysm4h/*"); | ||||||
|  | 
 | ||||||
|  |         let master_dpk: &DescriptorPublicKey = &master_dsk.as_public(); | ||||||
|  |         let derived_dpk: &DescriptorPublicKey = &derive_dpk(master_dpk, "m").unwrap(); | ||||||
|  |         assert_eq!(derived_dpk.as_string(), "[d1d04177]tpubD6NzVbkrYhZ4WywdEfYbbd62yuvqLjAZuPsNyvzCNV85JekAEMbKHWSHLF9h3j45SxewXDcLv328B1SEZrxg4iwGfmdt1pDFjZiTkGiFqGa/*"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_derive_descriptors_keys() { | ||||||
|  |         let master_dsk = get_descriptor_secret_key(); | ||||||
|  |         let derived_dsk: &DescriptorSecretKey = &derive_dsk(&master_dsk, "m/0").unwrap(); | ||||||
|  |         assert_eq!(derived_dsk.as_string(), "[d1d04177/0]tprv8d7Y4JLmD25jkKbyDZXcdoPHu1YtMHuH21qeN7mFpjfumtSU7eZimFYUCSa3MYzkEYfSNRBV34GEr2QXwZCMYRZ7M1g6PUtiLhbJhBZEGYJ/*"); | ||||||
|  | 
 | ||||||
|  |         let master_dpk: &DescriptorPublicKey = &master_dsk.as_public(); | ||||||
|  |         let derived_dpk: &DescriptorPublicKey = &derive_dpk(master_dpk, "m/0").unwrap(); | ||||||
|  |         assert_eq!(derived_dpk.as_string(), "[d1d04177/0]tpubD9oaCiP1MPmQdndm7DCD3D3QU34pWd6BbKSRedoZF1UJcNhEk3PJwkALNYkhxeTKL29oGNR7psqvT1KZydCGqUDEKXN6dVQJY2R8ooLPy8m/*"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_extend_descriptor_keys() { | ||||||
|  |         let master_dsk = get_descriptor_secret_key(); | ||||||
|  |         let extended_dsk: &DescriptorSecretKey = &extend_dsk(&master_dsk, "m/0"); | ||||||
|  |         assert_eq!(extended_dsk.as_string(), "tprv8ZgxMBicQKsPdWuqM1t1CDRvQtQuBPyfL6GbhQwtxDKgUAVPbxmj71pRA8raTqLrec5LyTs5TqCxdABcZr77bt2KyWA5bizJHnC4g4ysm4h/0/*"); | ||||||
|  | 
 | ||||||
|  |         let master_dpk: &DescriptorPublicKey = &master_dsk.as_public(); | ||||||
|  |         let extended_dpk: &DescriptorPublicKey = &extend_dpk(master_dpk, "m/0"); | ||||||
|  |         assert_eq!(extended_dpk.as_string(), "tpubD6NzVbkrYhZ4WywdEfYbbd62yuvqLjAZuPsNyvzCNV85JekAEMbKHWSHLF9h3j45SxewXDcLv328B1SEZrxg4iwGfmdt1pDFjZiTkGiFqGa/0/*"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_derive_and_extend_descriptor_secret_key() { | ||||||
|  |         let master_dsk = get_descriptor_secret_key(); | ||||||
|  | 
 | ||||||
|  |         // derive DescriptorSecretKey with path "m/0" from master
 | ||||||
|  |         let derived_dsk: &DescriptorSecretKey = &derive_dsk(&master_dsk, "m/0").unwrap(); | ||||||
|  |         assert_eq!(derived_dsk.as_string(), "[d1d04177/0]tprv8d7Y4JLmD25jkKbyDZXcdoPHu1YtMHuH21qeN7mFpjfumtSU7eZimFYUCSa3MYzkEYfSNRBV34GEr2QXwZCMYRZ7M1g6PUtiLhbJhBZEGYJ/*"); | ||||||
|  | 
 | ||||||
|  |         // extend derived_dsk with path "m/0"
 | ||||||
|  |         let extended_dsk: &DescriptorSecretKey = &extend_dsk(derived_dsk, "m/0"); | ||||||
|  |         assert_eq!(extended_dsk.as_string(), "[d1d04177/0]tprv8d7Y4JLmD25jkKbyDZXcdoPHu1YtMHuH21qeN7mFpjfumtSU7eZimFYUCSa3MYzkEYfSNRBV34GEr2QXwZCMYRZ7M1g6PUtiLhbJhBZEGYJ/0/*"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     #[test] | ||||||
|  |     fn test_derive_hardened_path_using_public() { | ||||||
|  |         let master_dpk = get_descriptor_secret_key().as_public(); | ||||||
|  |         let derived_dpk = &derive_dpk(&master_dpk, "m/84h/1h/0h"); | ||||||
|  |         assert!(derived_dpk.is_err()); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user