pub mod verifier;
pub mod verification_key;
pub mod proof;
pub mod error;
#[cfg(feature = "oidc")]
pub mod oidc;
pub use verifier::Verifier;
pub use verification_key::VerificationKey;
pub use proof::{Groth16Proof, PublicInputs, VerificationResult};
pub use error::SdkError;
pub const NPUB_PREFIX: &str = "npub";
pub fn hex_to_npub(hex_pubkey: &str) -> Result<String, SdkError> {
use bech32::{Hrp, Bech32m};
let bytes = hex::decode(hex_pubkey)
.map_err(|e| SdkError::InvalidInput(format!("Invalid hex: {}", e)))?;
if bytes.len() != 32 {
return Err(SdkError::InvalidInput("Public key must be 32 bytes".into()));
}
let hrp = Hrp::parse(NPUB_PREFIX)
.map_err(|e| SdkError::InvalidInput(format!("Invalid HRP: {}", e)))?;
bech32::encode::<Bech32m>(hrp, &bytes)
.map_err(|e| SdkError::InvalidInput(format!("Bech32 encode failed: {}", e)))
}
pub fn npub_to_hex(npub: &str) -> Result<String, SdkError> {
use bech32::Hrp;
let (hrp, bytes) = bech32::decode(npub)
.map_err(|e| SdkError::InvalidInput(format!("Invalid bech32: {}", e)))?;
let expected_hrp = Hrp::parse(NPUB_PREFIX).unwrap();
if hrp != expected_hrp {
return Err(SdkError::InvalidInput(format!(
"Expected npub prefix, got: {}", hrp
)));
}
Ok(hex::encode(bytes))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_npub_roundtrip() {
let hex_key = "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
let npub = hex_to_npub(hex_key).unwrap();
assert!(npub.starts_with("npub"));
let recovered = npub_to_hex(&npub).unwrap();
assert_eq!(recovered, hex_key);
}
}