use crate::error::{IdentityError, Result};
use std::sync::Arc;
use tenzro_types::primitives::Address;
use tenzro_wallet::{HybridSignatureBytes, TenzroWalletService, WalletId, WalletService};
use tracing::info;
pub struct WalletBinding {
pub wallet_id: String,
pub address: Address,
pub public_key: Vec<u8>,
pub key_type: String,
pub pq_verifying_key: Vec<u8>,
pub bls_verifying_key: Vec<u8>,
}
pub struct WalletBinder {
wallet_service: Arc<TenzroWalletService>,
}
impl WalletBinder {
pub fn new() -> Result<Self> {
let wallet_service =
Arc::new(TenzroWalletService::new().map_err(|e| IdentityError::WalletError(e.to_string()))?);
Ok(Self { wallet_service })
}
pub fn from_service(wallet_service: Arc<TenzroWalletService>) -> Self {
Self { wallet_service }
}
pub async fn provision_wallet(&self, did: &str) -> Result<WalletBinding> {
info!("Provisioning wallet for identity: {}", did);
let wallet = self
.wallet_service
.provision_wallet()
.await
.map_err(|e| IdentityError::WalletError(e.to_string()))?;
let mut addr_bytes = [0u8; 32];
let src = wallet.address.as_bytes();
let len = src.len().min(32);
addr_bytes[..len].copy_from_slice(&src[..len]);
let pq_verifying_key = wallet.pq_verifying_key_bytes();
let bls_verifying_key = wallet.bls_verifying_key_bytes().to_vec();
let public_key = wallet.public_key.to_bytes();
let key_type = match wallet.public_key.key_type() {
tenzro_crypto::KeyType::Ed25519 => "Ed25519".to_string(),
tenzro_crypto::KeyType::Secp256k1 => "Secp256k1".to_string(),
};
Ok(WalletBinding {
wallet_id: wallet.wallet_id.to_string(),
address: Address::new(addr_bytes),
public_key,
key_type,
pq_verifying_key,
bls_verifying_key,
})
}
pub async fn sign(&self, wallet_id: &str, data: &[u8]) -> Result<HybridSignatureBytes> {
let wid = WalletId::from_string(wallet_id.to_string());
self.wallet_service
.sign_data(&wid, data)
.await
.map_err(|e| IdentityError::WalletError(e.to_string()))
}
}