use ergo_lib::ergotree_interpreter::sigma_protocol::private_input::DlogProverInput;
use ergo_lib::wallet;
use std::convert::TryInto;
use crate::address::{Address, AddressPtr};
use crate::util::{const_ptr_as_ref, mut_ptr_as_mut};
use crate::Error;
#[derive(PartialEq, Eq, Debug, Clone)]
pub struct SecretKey(pub(crate) wallet::secret_key::SecretKey);
pub type SecretKeyPtr = *mut SecretKey;
pub type ConstSecretKeyPtr = *const SecretKey;
pub unsafe fn secret_key_from_bytes(
bytes_ptr: *const u8,
secret_key_out: *mut SecretKeyPtr,
) -> Result<(), Error> {
if bytes_ptr.is_null() {
return Err(Error::Misc("bytes_ptr is null".into()));
}
let bytes = std::slice::from_raw_parts(bytes_ptr, DlogProverInput::SIZE_BYTES);
let sized_bytes: &[u8; DlogProverInput::SIZE_BYTES] = bytes.try_into()?;
if let Some(k) = wallet::secret_key::SecretKey::dlog_from_bytes(sized_bytes).map(SecretKey) {
*secret_key_out = Box::into_raw(Box::new(k));
Ok(())
} else {
Err(Error::Misc("failed to parse scalar".into()))
}
}
pub unsafe fn secret_key_generate_random(secret_key_out: *mut SecretKeyPtr) -> Result<(), Error> {
*secret_key_out = Box::into_raw(Box::new(SecretKey(
wallet::secret_key::SecretKey::random_dlog(),
)));
Ok(())
}
pub unsafe fn secret_key_get_address(
secret_key_ptr: ConstSecretKeyPtr,
address_out: *mut AddressPtr,
) -> Result<(), Error> {
let secret_key = const_ptr_as_ref(secret_key_ptr, "secret_key_ptr")?;
let address_out = mut_ptr_as_mut(address_out, "address_out")?;
*address_out = Box::into_raw(Box::new(Address(
secret_key.0.get_address_from_public_image(),
)));
Ok(())
}
pub unsafe fn secret_key_to_bytes(
secret_key_ptr: ConstSecretKeyPtr,
output: *mut u8,
) -> Result<(), Error> {
let secret_key = const_ptr_as_ref(secret_key_ptr, "secret_key_ptr")?;
let src = secret_key.0.to_bytes();
std::ptr::copy_nonoverlapping(src.as_ptr(), output, DlogProverInput::SIZE_BYTES);
Ok(())
}