NAC_Blockchain/nac-asset-onboarding/src/custody.rs

101 lines
3.2 KiB
Rust

//! 托管对接适配器
//!
//! 调用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<Self> {
let protocol = CustodyProtocol::new();
Ok(Self { protocol })
}
/// 对接托管机构
pub async fn arrange_custody(
&self,
submission: &AssetSubmission,
dna_hash: &str,
) -> Result<CustodyResult> {
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<CustodyProvider> {
// 根据辖区和资产类型选择托管机构
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<String> {
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());
}
}