use crate::types::OrchardStoredBundle;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use thiserror::Error;
#[derive(Debug, Clone)]
pub struct BtcDepositConfigV1 {
pub btc_deposit_address: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ShieldIntentV1 {
pub protocol_version: u32,
pub btc_deposit_address: String,
pub amount_sats: u64,
pub bundle_sha256_hex: String,
pub orchard_cmx_hex: String,
pub operator_reference: Option<String>,
#[serde(default)]
pub btc_txid: Option<String>,
}
#[derive(Debug, Error)]
pub enum BridgeError {
#[error("stored bundle must contain at least one action")]
NoActions,
}
pub fn bundle_content_sha256(bundle: &OrchardStoredBundle) -> [u8; 32] {
let bytes = serde_json::to_vec(bundle).expect("OrchardStoredBundle serializes");
Sha256::digest(bytes).into()
}
pub fn build_shield_intent_v1(
bundle: &OrchardStoredBundle,
cfg: &BtcDepositConfigV1,
amount_sats: u64,
operator_reference: Option<String>,
btc_txid: Option<String>,
) -> Result<ShieldIntentV1, BridgeError> {
let action = bundle.actions.first().ok_or(BridgeError::NoActions)?;
Ok(ShieldIntentV1 {
protocol_version: 1,
btc_deposit_address: cfg.btc_deposit_address.clone(),
amount_sats,
bundle_sha256_hex: hex::encode(bundle_content_sha256(bundle)),
orchard_cmx_hex: hex::encode(action.cmx),
operator_reference,
btc_txid,
})
}