//! 托管对接适配器 //! //! 调用ACC托管协议对接托管机构 use crate::error::{OnboardingError, Result}; use crate::types::{AssetSubmission, CustodyResult}; use crate::types::{CustodyProtocol, CustodyRequest, CustodyProvider}; use chrono::Utc; use tracing::{info, error}; /// 托管对接适配器 pub struct CustodyAdapter { protocol: CustodyProtocol, } impl CustodyAdapter { /// 创建新的适配器 pub fn new() -> Result { let protocol = CustodyProtocol::new(); Ok(Self { protocol }) } /// 对接托管机构 pub async fn arrange_custody( &self, submission: &AssetSubmission, dna_hash: &str, ) -> Result { info!("开始对接托管机构: {}", submission.asset_name); // 选择托管机构 let provider = self.select_provider(submission)?; // 构建托管请求 let request = CustodyRequest { asset_id: dna_hash.to_string(), asset_name: submission.asset_name.clone(), asset_type: submission.asset_type.clone(), jurisdiction: submission.jurisdiction.clone(), owner_id: submission.user_id.clone(), provider: format!("{:?}", provider), }; // 生成托管协议哈希(在移动 request 之前) let custody_agreement_hash = self.generate_agreement_hash(&request)?; // 提交托管请求 let response = self.protocol.submit_request(request) .await .map_err(|e| OnboardingError::CustodyError(format!("托管失败: {}", e)))?; info!("托管对接完成: provider={:?}, agreement={}", provider, custody_agreement_hash); Ok(CustodyResult { custodian: format!("{:?}", provider), custody_certificate: format!("CERT-{}", submission.asset_name), certificate_hash: custody_agreement_hash, timestamp: Utc::now(), }) } /// 选择托管机构 fn select_provider(&self, submission: &AssetSubmission) -> Result { // 根据辖区和资产类型选择托管机构 match submission.jurisdiction.as_str() { "US" => Ok(CustodyProvider::BankOfNewYorkMellon), "EU" => Ok(CustodyProvider::EuroclearBank), "China" => Ok(CustodyProvider::ChinaSecuritiesDepository), "HK" => Ok(CustodyProvider::HSBCCustody), "Singapore" => Ok(CustodyProvider::DBSCustody), _ => Ok(CustodyProvider::BankOfNewYorkMellon), // 默认 } } /// 生成托管协议哈希 fn generate_agreement_hash(&self, request: &CustodyRequest) -> Result { use sha3::{Digest, Sha3_384}; let mut hasher = Sha3_384::new(); hasher.update(format!("{:?}", request).as_bytes()); let hash = format!("0x{}", hex::encode(hasher.finalize())); Ok(hash) } } impl Default for CustodyAdapter { fn default() -> Self { Self::new().expect("mainnet: handle error") } } #[cfg(test)] mod tests { use super::*; #[test] fn test_adapter_creation() { let adapter = CustodyAdapter::new(); assert!(adapter.is_ok()); } }