Add from_string() methods to DescriptorPrivateKey and DescriptorPublicKey
This commit is contained in:
parent
063f69222a
commit
29614b5b78
@ -304,9 +304,13 @@ interface DerivationPath {
|
|||||||
interface DescriptorSecretKey {
|
interface DescriptorSecretKey {
|
||||||
constructor(Network network, Mnemonic mnemonic, string? password);
|
constructor(Network network, Mnemonic mnemonic, string? password);
|
||||||
|
|
||||||
|
[Name=from_string, Throws=BdkError]
|
||||||
|
constructor(string secret_key);
|
||||||
|
|
||||||
[Throws=BdkError]
|
[Throws=BdkError]
|
||||||
DescriptorSecretKey derive(DerivationPath path);
|
DescriptorSecretKey derive(DerivationPath path);
|
||||||
|
|
||||||
|
[Throws=BdkError]
|
||||||
DescriptorSecretKey extend(DerivationPath path);
|
DescriptorSecretKey extend(DerivationPath path);
|
||||||
|
|
||||||
DescriptorPublicKey as_public();
|
DescriptorPublicKey as_public();
|
||||||
@ -317,9 +321,13 @@ interface DescriptorSecretKey {
|
|||||||
};
|
};
|
||||||
|
|
||||||
interface DescriptorPublicKey {
|
interface DescriptorPublicKey {
|
||||||
|
[Name=from_string, Throws=BdkError]
|
||||||
|
constructor(string public_key);
|
||||||
|
|
||||||
[Throws=BdkError]
|
[Throws=BdkError]
|
||||||
DescriptorPublicKey derive(DerivationPath path);
|
DescriptorPublicKey derive(DerivationPath path);
|
||||||
|
|
||||||
|
[Throws=BdkError]
|
||||||
DescriptorPublicKey extend(DerivationPath path);
|
DescriptorPublicKey extend(DerivationPath path);
|
||||||
|
|
||||||
string as_string();
|
string as_string();
|
||||||
|
@ -924,6 +924,7 @@ impl DerivationPath {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct DescriptorSecretKey {
|
struct DescriptorSecretKey {
|
||||||
descriptor_secret_key_mutex: Mutex<BdkDescriptorSecretKey>,
|
descriptor_secret_key_mutex: Mutex<BdkDescriptorSecretKey>,
|
||||||
}
|
}
|
||||||
@ -943,6 +944,16 @@ impl DescriptorSecretKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn from_string(private_key: String) -> Result<Self, BdkError> {
|
||||||
|
let descriptor_secret_key = BdkDescriptorSecretKey::from_str(private_key.as_str())
|
||||||
|
.map_err(
|
||||||
|
| e | BdkError::Generic(e.to_string())
|
||||||
|
)?;
|
||||||
|
Ok(Self {
|
||||||
|
descriptor_secret_key_mutex: Mutex::new(descriptor_secret_key),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn derive(&self, path: Arc<DerivationPath>) -> Result<Arc<Self>, BdkError> {
|
fn derive(&self, path: Arc<DerivationPath>) -> Result<Arc<Self>, BdkError> {
|
||||||
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();
|
||||||
@ -965,12 +976,12 @@ impl DescriptorSecretKey {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
BdkDescriptorSecretKey::Single(_) => {
|
BdkDescriptorSecretKey::Single(_) => {
|
||||||
unreachable!()
|
Err(BdkError::Generic("Cannot derive from a single key".to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extend(&self, path: Arc<DerivationPath>) -> Arc<Self> {
|
fn extend(&self, path: Arc<DerivationPath>) -> Result<Arc<Self>, BdkError> {
|
||||||
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();
|
||||||
match descriptor_secret_key.deref() {
|
match descriptor_secret_key.deref() {
|
||||||
@ -982,12 +993,12 @@ impl DescriptorSecretKey {
|
|||||||
derivation_path: extended_path,
|
derivation_path: extended_path,
|
||||||
wildcard: descriptor_x_key.wildcard,
|
wildcard: descriptor_x_key.wildcard,
|
||||||
});
|
});
|
||||||
Arc::new(Self {
|
Ok(Arc::new(Self {
|
||||||
descriptor_secret_key_mutex: Mutex::new(extended_descriptor_secret_key),
|
descriptor_secret_key_mutex: Mutex::new(extended_descriptor_secret_key),
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
BdkDescriptorSecretKey::Single(_) => {
|
BdkDescriptorSecretKey::Single(_) => {
|
||||||
unreachable!()
|
Err(BdkError::Generic("Cannot extend from a single key".to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1025,11 +1036,22 @@ impl DescriptorSecretKey {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct DescriptorPublicKey {
|
struct DescriptorPublicKey {
|
||||||
descriptor_public_key_mutex: Mutex<BdkDescriptorPublicKey>,
|
descriptor_public_key_mutex: Mutex<BdkDescriptorPublicKey>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DescriptorPublicKey {
|
impl DescriptorPublicKey {
|
||||||
|
fn from_string(public_key: String) -> Result<Self, BdkError> {
|
||||||
|
let descriptor_public_key = BdkDescriptorPublicKey::from_str(public_key.as_str())
|
||||||
|
.map_err(
|
||||||
|
| e | BdkError::Generic(e.to_string())
|
||||||
|
)?;
|
||||||
|
Ok(Self {
|
||||||
|
descriptor_public_key_mutex: Mutex::new(descriptor_public_key),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn derive(&self, path: Arc<DerivationPath>) -> Result<Arc<Self>, BdkError> {
|
fn derive(&self, path: Arc<DerivationPath>) -> Result<Arc<Self>, BdkError> {
|
||||||
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();
|
||||||
@ -1053,12 +1075,12 @@ impl DescriptorPublicKey {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
BdkDescriptorPublicKey::Single(_) => {
|
BdkDescriptorPublicKey::Single(_) => {
|
||||||
unreachable!()
|
Err(BdkError::Generic("Cannot derive from a single key".to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extend(&self, path: Arc<DerivationPath>) -> Arc<Self> {
|
fn extend(&self, path: Arc<DerivationPath>) -> Result<Arc<Self>, BdkError> {
|
||||||
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();
|
||||||
match descriptor_public_key.deref() {
|
match descriptor_public_key.deref() {
|
||||||
@ -1070,12 +1092,12 @@ impl DescriptorPublicKey {
|
|||||||
derivation_path: extended_path,
|
derivation_path: extended_path,
|
||||||
wildcard: descriptor_x_key.wildcard,
|
wildcard: descriptor_x_key.wildcard,
|
||||||
});
|
});
|
||||||
Arc::new(Self {
|
Ok(Arc::new(Self {
|
||||||
descriptor_public_key_mutex: Mutex::new(extended_descriptor_public_key),
|
descriptor_public_key_mutex: Mutex::new(extended_descriptor_public_key),
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
BdkDescriptorPublicKey::Single(_) => {
|
BdkDescriptorPublicKey::Single(_) => {
|
||||||
unreachable!()
|
Err(BdkError::Generic("Cannot extend from a single key".to_string()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1176,7 +1198,7 @@ mod test {
|
|||||||
key.derive(path)
|
key.derive(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extend_dsk(key: &DescriptorSecretKey, path: &str) -> Arc<DescriptorSecretKey> {
|
fn extend_dsk(key: &DescriptorSecretKey, path: &str) -> Result<Arc<DescriptorSecretKey>, BdkError> {
|
||||||
let path = Arc::new(DerivationPath::new(path.to_string()).unwrap());
|
let path = Arc::new(DerivationPath::new(path.to_string()).unwrap());
|
||||||
key.extend(path)
|
key.extend(path)
|
||||||
}
|
}
|
||||||
@ -1189,7 +1211,7 @@ mod test {
|
|||||||
key.derive(path)
|
key.derive(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extend_dpk(key: &DescriptorPublicKey, path: &str) -> Arc<DescriptorPublicKey> {
|
fn extend_dpk(key: &DescriptorPublicKey, path: &str) -> Result<Arc<DescriptorPublicKey>, BdkError> {
|
||||||
let path = Arc::new(DerivationPath::new(path.to_string()).unwrap());
|
let path = Arc::new(DerivationPath::new(path.to_string()).unwrap());
|
||||||
key.extend(path)
|
key.extend(path)
|
||||||
}
|
}
|
||||||
@ -1226,12 +1248,36 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_extend_descriptor_keys() {
|
fn test_extend_descriptor_keys() {
|
||||||
let master_dsk = get_descriptor_secret_key();
|
let master_dsk = get_descriptor_secret_key();
|
||||||
let extended_dsk: &DescriptorSecretKey = &extend_dsk(&master_dsk, "m/0");
|
let extended_dsk: &DescriptorSecretKey = &extend_dsk(&master_dsk, "m/0").unwrap();
|
||||||
assert_eq!(extended_dsk.as_string(), "tprv8ZgxMBicQKsPdWuqM1t1CDRvQtQuBPyfL6GbhQwtxDKgUAVPbxmj71pRA8raTqLrec5LyTs5TqCxdABcZr77bt2KyWA5bizJHnC4g4ysm4h/0/*");
|
assert_eq!(extended_dsk.as_string(), "tprv8ZgxMBicQKsPdWuqM1t1CDRvQtQuBPyfL6GbhQwtxDKgUAVPbxmj71pRA8raTqLrec5LyTs5TqCxdABcZr77bt2KyWA5bizJHnC4g4ysm4h/0/*");
|
||||||
|
|
||||||
let master_dpk: &DescriptorPublicKey = &master_dsk.as_public();
|
let master_dpk: &DescriptorPublicKey = &master_dsk.as_public();
|
||||||
let extended_dpk: &DescriptorPublicKey = &extend_dpk(master_dpk, "m/0");
|
let extended_dpk: &DescriptorPublicKey = &extend_dpk(master_dpk, "m/0").unwrap();
|
||||||
assert_eq!(extended_dpk.as_string(), "tpubD6NzVbkrYhZ4WywdEfYbbd62yuvqLjAZuPsNyvzCNV85JekAEMbKHWSHLF9h3j45SxewXDcLv328B1SEZrxg4iwGfmdt1pDFjZiTkGiFqGa/0/*");
|
assert_eq!(extended_dpk.as_string(), "tpubD6NzVbkrYhZ4WywdEfYbbd62yuvqLjAZuPsNyvzCNV85JekAEMbKHWSHLF9h3j45SxewXDcLv328B1SEZrxg4iwGfmdt1pDFjZiTkGiFqGa/0/*");
|
||||||
|
|
||||||
|
let wif = "L2wTu6hQrnDMiFNWA5na6jB12ErGQqtXwqpSL7aWquJaZG8Ai3ch";
|
||||||
|
let extended_key = DescriptorSecretKey::from_string(wif.to_string()).unwrap();
|
||||||
|
let result = extended_key.derive(
|
||||||
|
Arc::new(DerivationPath::new("m/0".to_string()).unwrap())
|
||||||
|
);
|
||||||
|
dbg!(&result);
|
||||||
|
assert!(result.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_from_str_descriptor_secret_key() {
|
||||||
|
let key1 = "L2wTu6hQrnDMiFNWA5na6jB12ErGQqtXwqpSL7aWquJaZG8Ai3ch";
|
||||||
|
let key2 = "tprv8ZgxMBicQKsPcwcD4gSnMti126ZiETsuX7qwrtMypr6FBwAP65puFn4v6c3jrN9VwtMRMph6nyT63NrfUL4C3nBzPcduzVSuHD7zbX2JKVc/1/1/1/*";
|
||||||
|
|
||||||
|
let private_descriptor_key1 = DescriptorSecretKey::from_string(key1.to_string()).unwrap();
|
||||||
|
let private_descriptor_key2 = DescriptorSecretKey::from_string(key2.to_string()).unwrap();
|
||||||
|
|
||||||
|
dbg!(private_descriptor_key1);
|
||||||
|
dbg!(private_descriptor_key2);
|
||||||
|
|
||||||
|
// Should error out because you can't produce a DescriptorSecretKey from an xpub
|
||||||
|
let key0 = "tpubDBrgjcxBxnXyL575sHdkpKohWu5qHKoQ7TJXKNrYznh5fVEGBv89hA8ENW7A8MFVpFUSvgLqc4Nj1WZcpePX6rrxviVtPowvMuGF5rdT2Vi";
|
||||||
|
assert!(DescriptorSecretKey::from_string(key0.to_string()).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -1242,7 +1288,7 @@ mod test {
|
|||||||
assert_eq!(derived_dsk.as_string(), "[d1d04177/0]tprv8d7Y4JLmD25jkKbyDZXcdoPHu1YtMHuH21qeN7mFpjfumtSU7eZimFYUCSa3MYzkEYfSNRBV34GEr2QXwZCMYRZ7M1g6PUtiLhbJhBZEGYJ/*");
|
assert_eq!(derived_dsk.as_string(), "[d1d04177/0]tprv8d7Y4JLmD25jkKbyDZXcdoPHu1YtMHuH21qeN7mFpjfumtSU7eZimFYUCSa3MYzkEYfSNRBV34GEr2QXwZCMYRZ7M1g6PUtiLhbJhBZEGYJ/*");
|
||||||
|
|
||||||
// extend derived_dsk with path "m/0"
|
// extend derived_dsk with path "m/0"
|
||||||
let extended_dsk: &DescriptorSecretKey = &extend_dsk(derived_dsk, "m/0");
|
let extended_dsk: &DescriptorSecretKey = &extend_dsk(derived_dsk, "m/0").unwrap();
|
||||||
assert_eq!(extended_dsk.as_string(), "[d1d04177/0]tprv8d7Y4JLmD25jkKbyDZXcdoPHu1YtMHuH21qeN7mFpjfumtSU7eZimFYUCSa3MYzkEYfSNRBV34GEr2QXwZCMYRZ7M1g6PUtiLhbJhBZEGYJ/0/*");
|
assert_eq!(extended_dsk.as_string(), "[d1d04177/0]tprv8d7Y4JLmD25jkKbyDZXcdoPHu1YtMHuH21qeN7mFpjfumtSU7eZimFYUCSa3MYzkEYfSNRBV34GEr2QXwZCMYRZ7M1g6PUtiLhbJhBZEGYJ/0/*");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user