-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e4a9b53
commit 5693da5
Showing
4 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
//! Extended Public Key functionality | ||
use derive_more::{From, Into}; | ||
|
||
use ergo_lib::ergotree_ir::chain::address::Address as InnerAddress; | ||
use ergo_lib::wallet::derivation_path::ChildIndexNormal; | ||
use ergo_lib::wallet::ext_pub_key::{ExtPubKey as InnerExtPubKey, PubKeyBytes}; | ||
use ergo_lib::ArrLength; | ||
|
||
use crate::address::{Address, AddressPtr}; | ||
use crate::derivation_path::ConstDerivationPathPtr; | ||
use crate::util::{const_ptr_as_ref, mut_ptr_as_mut}; | ||
use crate::Error; | ||
|
||
#[derive(From, Into)] | ||
pub struct ExtPubKey(pub InnerExtPubKey); | ||
pub type ExtPubKeyPtr = *mut ExtPubKey; | ||
pub type ConstExtPubKeyPtr = *const ExtPubKey; | ||
|
||
/// Create ExtPubKey from public key bytes, chain code and derivation path | ||
pub unsafe fn ext_pub_key_new( | ||
public_key_bytes: *const u8, | ||
chain_code: *const u8, | ||
derivation_path_ptr: ConstDerivationPathPtr, | ||
ext_pub_key_out: *mut ExtPubKeyPtr, | ||
) -> Result<(), Error> { | ||
let ext_pub_key_out = mut_ptr_as_mut(ext_pub_key_out, "ext_pub_key_out")?; | ||
let derivation_path = const_ptr_as_ref(derivation_path_ptr, "derivation_path_ptr")?; | ||
let secret_key_bytes = std::slice::from_raw_parts(public_key_bytes, PubKeyBytes::LEN); | ||
let chain_code = | ||
std::slice::from_raw_parts(chain_code, ergo_lib::wallet::ext_pub_key::ChainCode::LEN); | ||
let key = InnerExtPubKey::new( | ||
secret_key_bytes.try_into().map_err(Error::misc)?, | ||
chain_code.try_into().map_err(Error::misc)?, | ||
derivation_path.0.clone(), | ||
) | ||
.map_err(Error::misc)?; | ||
*ext_pub_key_out = Box::into_raw(Box::new(ExtPubKey(key))); | ||
Ok(()) | ||
} | ||
|
||
/// Derive a new extended public key from the provided index | ||
/// The index is in the form of soft or hardened indices | ||
/// For example: 4 or 4' respectively | ||
pub unsafe fn ext_pub_key_child( | ||
derive_from_key_ptr: ConstExtPubKeyPtr, | ||
child_index: u32, | ||
ext_pub_key_out: *mut ExtPubKeyPtr, | ||
) -> Result<(), Error> { | ||
let ext_pub_key = const_ptr_as_ref(derive_from_key_ptr, "derive_from_key_ptr")?; | ||
let ext_pub_key_out = mut_ptr_as_mut(ext_pub_key_out, "ext_pub_key_out")?; | ||
let index = ChildIndexNormal::normal(child_index).map_err(Error::misc)?; | ||
let key = ext_pub_key.0.child(index); | ||
*ext_pub_key_out = Box::into_raw(Box::new(ExtPubKey(key))); | ||
Ok(()) | ||
} | ||
|
||
/// Derive a new extended public key from the derivation path | ||
pub unsafe fn ext_pub_key_derive( | ||
ext_pub_key_ptr: ConstExtPubKeyPtr, | ||
derivation_path_ptr: ConstDerivationPathPtr, | ||
ext_pub_key_out: *mut ExtPubKeyPtr, | ||
) -> Result<(), Error> { | ||
let ext_pub_key_ptr = const_ptr_as_ref(ext_pub_key_ptr, "ext_pub_key_ptr")?; | ||
let derivation_path = const_ptr_as_ref(derivation_path_ptr, "derivation_path_ptr")?; | ||
let ext_pub_key_out = mut_ptr_as_mut(ext_pub_key_out, "ext_pub_key_out")?; | ||
*ext_pub_key_out = Box::into_raw(Box::new(ExtPubKey( | ||
ext_pub_key_ptr | ||
.0 | ||
.derive(derivation_path.0.clone()) | ||
.map_err(Error::misc)?, | ||
))); | ||
Ok(()) | ||
} | ||
|
||
/// Get address for extended public key | ||
pub unsafe fn ext_pub_key_address( | ||
ext_pub_key_ptr: ConstExtPubKeyPtr, | ||
address_out: *mut AddressPtr, | ||
) -> Result<(), Error> { | ||
let ext_pub_key_ptr = const_ptr_as_ref(ext_pub_key_ptr, "ext_pub_key_ptr")?; | ||
let address_out = mut_ptr_as_mut(address_out, "address_out")?; | ||
let ext_pub_key: InnerExtPubKey = ext_pub_key_ptr.0.clone(); | ||
let address = InnerAddress::from(ext_pub_key); | ||
*address_out = Box::into_raw(Box::new(Address(address))); | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
//! Extended Public Key functionality | ||
use crate::{delete_ptr, ErrorPtr}; | ||
use ergo_lib_c_core::address::AddressPtr; | ||
use ergo_lib_c_core::derivation_path::ConstDerivationPathPtr; | ||
use ergo_lib_c_core::ext_pub_key::{ | ||
ext_pub_key_address, ext_pub_key_child, ext_pub_key_derive, ext_pub_key_new, ConstExtPubKeyPtr, | ||
ExtPubKeyPtr, | ||
}; | ||
use ergo_lib_c_core::Error; | ||
|
||
/// Create ExtPubKey from public key bytes, chain code and derivation path | ||
#[no_mangle] | ||
pub unsafe extern "C" fn ergo_lib_ext_pub_key_new( | ||
public_key_bytes: *const u8, | ||
chain_code_ptr: *const u8, | ||
derivation_path_ptr: ConstDerivationPathPtr, | ||
ext_pub_key_out: *mut ExtPubKeyPtr, | ||
) -> ErrorPtr { | ||
let res = ext_pub_key_new( | ||
public_key_bytes, | ||
chain_code_ptr, | ||
derivation_path_ptr, | ||
ext_pub_key_out, | ||
); | ||
Error::c_api_from(res) | ||
} | ||
|
||
/// Derive a new extended public key from the provided index | ||
/// The index is in the form of soft or hardened indices | ||
/// For example: 4 or 4' respectively | ||
#[no_mangle] | ||
pub unsafe extern "C" fn ergo_lib_ext_pub_key_child( | ||
derive_from_key_ptr: ConstExtPubKeyPtr, | ||
child_index: u32, | ||
ext_pub_key_out: *mut ExtPubKeyPtr, | ||
) -> ErrorPtr { | ||
let res = ext_pub_key_child(derive_from_key_ptr, child_index, ext_pub_key_out); | ||
Error::c_api_from(res) | ||
} | ||
|
||
/// Derive a new extended public key from the derivation path | ||
#[no_mangle] | ||
pub unsafe extern "C" fn ergo_lib_ext_pub_key_derive( | ||
ext_pub_key_ptr: ConstExtPubKeyPtr, | ||
derivation_path_ptr: ConstDerivationPathPtr, | ||
ext_pub_key_out: *mut ExtPubKeyPtr, | ||
) -> ErrorPtr { | ||
let res = ext_pub_key_derive(ext_pub_key_ptr, derivation_path_ptr, ext_pub_key_out); | ||
Error::c_api_from(res) | ||
} | ||
|
||
/// Get address for extended public key | ||
#[no_mangle] | ||
pub unsafe extern "C" fn ergo_lib_ext_pub_key_address( | ||
ext_pub_key_ptr: ConstExtPubKeyPtr, | ||
address_out: *mut AddressPtr, | ||
) { | ||
#[allow(clippy::unwrap_used)] | ||
ext_pub_key_address(ext_pub_key_ptr, address_out).unwrap() | ||
} | ||
|
||
/// Drop `ExtPubKey` | ||
#[no_mangle] | ||
pub extern "C" fn ergo_lib_ext_pub_key_delete(ptr: ExtPubKeyPtr) { | ||
unsafe { delete_ptr(ptr) } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters