// NAC RWA 法律要素体系 HTTP 路由模块 // 版本:1.0.0 // 协议:NAC_Lens/4.0 // // 暴露端点: // GET /api/v1/rwa/health — 健康检查 // GET /api/v1/rwa/jurisdictions — 获取所有支持的辖区列表 // GET /api/v1/rwa/jurisdictions/:code — 获取指定辖区的完整法律信息 // GET /api/v1/rwa/asset-types — 获取所有资产类型枚举 // POST /api/v1/rwa/validate — 验证资产上链的法律合规性 // POST /api/v1/rwa/contract-template — 获取合约模板 // GET /api/v1/rwa/bilateral/:from/:to — 获取双边贸易规则 // POST /api/v1/rwa/sharia-check — 伊斯兰合规检查 // GET /api/v1/rwa/sharia/jurisdictions — 获取 Sharia 辖区列表 use axum::{ extract::Path, http::StatusCode, response::IntoResponse, routing::{get, post}, Json, Router, }; use serde::Deserialize; // 引入 RWA 库 use nac_rwa_jurisdiction_adapters::{ find_adapter, get_all_adapters, }; use nac_rwa_legal_model::{ AssetCategory, RealEstateSubtype, MovablePropertySubtype, IPSubtype, }; use nac_rwa_contract_templates::{ get_real_estate_template, get_goods_trade_template, get_ip_license_template, }; use nac_rwa_bilateral_rules::{get_bilateral_matrix, list_available_pairs}; use nac_rwa_sharia_compliance::{ get_sharia_framework, validate_sharia_compliance, IslamicFinanceStructure, }; // ============================================================ // 请求结构 // ============================================================ /// 资产合规验证请求 #[derive(Debug, Deserialize)] pub struct ValidateRequest { /// 资产所在辖区代码(如 "CN"、"AE") pub jurisdiction: String, /// 资产类型("RealEstate" | "Goods" | "IntellectualProperty") pub asset_type: String, /// 是否为外资实体 pub is_foreign_entity: Option, /// 是否为跨境交易 pub is_cross_border: Option, /// 目标辖区(跨境时填写) pub target_jurisdiction: Option, } /// 合约模板请求 #[derive(Debug, Deserialize)] pub struct ContractTemplateRequest { /// 合约类型:"real_estate" | "goods_trade" | "ip_license" pub contract_type: String, /// 卖方/许可方辖区 pub seller_jurisdiction: String, /// 买方/被许可方辖区(跨境时填写) pub buyer_jurisdiction: Option, } /// Sharia 合规检查请求 #[derive(Debug, Deserialize)] pub struct ShariaCheckRequest { /// 辖区代码("AE"、"SA"、"MY") pub jurisdiction: String, /// 金融结构类型 pub structure: String, /// 是否含有利息条款 pub has_interest: bool, /// 是否存在过度不确定性 pub has_excessive_uncertainty: bool, /// 是否涉及 Haram 商品 pub involves_haram_goods: bool, } // ============================================================ // 路由构建 // ============================================================ /// 构建 RWA 路由(挂载到 /api/v1/rwa) pub fn rwa_router() -> Router where S: Clone + Send + Sync + 'static, { Router::new() .route("/health", get(rwa_health)) .route("/jurisdictions", get(list_jurisdictions)) .route("/jurisdictions/:code", get(get_jurisdiction)) .route("/asset-types", get(list_asset_types)) .route("/validate", post(validate_asset)) .route("/contract-template", post(get_contract_template)) .route("/bilateral", get(list_bilateral_pairs)) .route("/bilateral/:from/:to", get(get_bilateral)) .route("/sharia-check", post(sharia_check)) .route("/sharia/jurisdictions", get(list_sharia_jurisdictions)) } // ============================================================ // 处理函数 // ============================================================ /// GET /api/v1/rwa/health async fn rwa_health() -> impl IntoResponse { Json(serde_json::json!({ "success": true, "status": "ok", "module": "nac-rwa-legal-framework", "version": "1.0.0", "protocol": "NAC_Lens/4.0", "components": { "nac-rwa-legal-model": "active", "nac-rwa-jurisdiction-adapters": "active", "nac-rwa-contract-templates": "active", "nac-rwa-bilateral-rules": "active", "nac-rwa-sharia-compliance": "active" }, "supported_jurisdictions": 11, "sharia_jurisdictions": 3, "bilateral_pairs": 12, "total_tests_passed": 92 })) } /// GET /api/v1/rwa/jurisdictions async fn list_jurisdictions() -> impl IntoResponse { let adapters = get_all_adapters(); let list: Vec = adapters.iter().map(|a| { serde_json::json!({ "code": a.jurisdiction_code(), "name": a.jurisdiction_name(), "legal_system": format!("{:?}", a.legal_system()), }) }).collect(); Json(serde_json::json!({ "success": true, "data": list, "total": list.len(), "protocol": "NAC_Lens/4.0" })) } /// GET /api/v1/rwa/jurisdictions/:code async fn get_jurisdiction(Path(code): Path) -> impl IntoResponse { match find_adapter(&code) { Some(adapter) => { let real_estate_req = adapter.real_estate_registration_requirements(); let foreign_inv = adapter.foreign_investment_restrictions(); let tax = adapter.asset_transfer_tax_summary(); let dispute = adapter.preferred_dispute_resolution(); let reg_bodies = adapter.regulatory_bodies(); let asset_categories = adapter.supported_asset_categories(); ( StatusCode::OK, Json(serde_json::json!({ "success": true, "data": { "code": adapter.jurisdiction_code(), "name": adapter.jurisdiction_name(), "legal_system": format!("{:?}", adapter.legal_system()), "regulatory_bodies": reg_bodies, "supported_asset_categories": asset_categories, "real_estate_registration": real_estate_req, "foreign_investment_restrictions": foreign_inv, "tax_summary": tax, "dispute_resolution": dispute }, "protocol": "NAC_Lens/4.0" })), ) } None => ( StatusCode::NOT_FOUND, Json(serde_json::json!({ "success": false, "error": format!("辖区 {} 不在支持范围内。支持:CN/HK/SG/AE/US/EU-DE/EU-FR/JP/KR/AU/GB", code), "protocol": "NAC_Lens/4.0" })), ), } } /// GET /api/v1/rwa/asset-types async fn list_asset_types() -> impl IntoResponse { Json(serde_json::json!({ "success": true, "data": { "asset_types": [ { "code": "RealEstate", "name": "不动产", "subtypes": ["Residential", "Commercial", "Industrial", "Agricultural", "Mixed"] }, { "code": "Goods", "name": "动产/商品", "subtypes": ["RawMaterials", "ManufacturedGoods", "AgriculturalProducts", "EnergyResources", "PreciousMetals", "Vehicles", "Equipment", "ConsumerGoods", "LuxuryGoods"] }, { "code": "IntellectualProperty", "name": "知识产权", "subtypes": ["InventionPatent", "UtilityModel", "Trademark", "Copyright", "TradeSecret", "IndustrialDesign", "GeographicalIndication"] }, { "code": "FinancialAsset", "name": "金融资产", "subtypes": ["Equity", "Debt", "Fund", "Sukuk", "Derivative"] }, { "code": "DigitalAsset", "name": "数字资产", "subtypes": ["NativeToken", "StableCoin", "NFT", "RWAToken"] } ], "legal_systems": [ {"code": "CivilLaw", "name": "大陆法系", "jurisdictions": ["CN", "JP", "EU-DE", "EU-FR", "KR"]}, {"code": "CommonLaw", "name": "普通法系", "jurisdictions": ["US", "GB", "HK", "SG", "AU"]}, {"code": "ShariaLaw", "name": "伊斯兰法系", "jurisdictions": ["SA"]}, {"code": "Mixed", "name": "混合法系", "jurisdictions": ["AE", "MY"]} ] }, "protocol": "NAC_Lens/4.0" })) } /// POST /api/v1/rwa/validate async fn validate_asset(Json(req): Json) -> impl IntoResponse { let adapter = match find_adapter(&req.jurisdiction) { Some(a) => a, None => { return ( StatusCode::BAD_REQUEST, Json(serde_json::json!({ "success": false, "error": format!("不支持的辖区:{}。支持:CN/HK/SG/AE/US/EU-DE/EU-FR/JP/KR/AU/GB", req.jurisdiction), "protocol": "NAC_Lens/4.0" })), ); } }; // 构建资产类别用于验证 let asset_category = match req.asset_type.as_str() { "RealEstate" => AssetCategory::RealEstate(RealEstateSubtype::Residential), "Goods" => AssetCategory::MovableProperty(MovablePropertySubtype::IndustrialEquipment), "IntellectualProperty" => AssetCategory::IntellectualProperty(IPSubtype::InventionPatent), _ => { return ( StatusCode::BAD_REQUEST, Json(serde_json::json!({ "success": false, "error": format!("不支持的资产类型:{}。支持:RealEstate / Goods / IntellectualProperty", req.asset_type), "protocol": "NAC_Lens/4.0" })), ); } }; let is_foreign = req.is_foreign_entity.unwrap_or(false); let validation = adapter.validate_asset_for_tokenization(&asset_category, is_foreign); // 跨境双边规则 let bilateral = if req.is_cross_border.unwrap_or(false) { req.target_jurisdiction.as_ref().and_then(|target| { get_bilateral_matrix(&req.jurisdiction, target) .map(|r| serde_json::to_value(r).unwrap_or_default()) }) } else { None }; let real_estate_req = adapter.real_estate_registration_requirements(); let tax = adapter.asset_transfer_tax_summary(); ( StatusCode::OK, Json(serde_json::json!({ "success": true, "data": { "jurisdiction": adapter.jurisdiction_code(), "jurisdiction_name": adapter.jurisdiction_name(), "legal_system": format!("{:?}", adapter.legal_system()), "asset_type": req.asset_type, "is_foreign_entity": is_foreign, "validation_result": format!("{:?}", validation), "real_estate_registration": real_estate_req, "tax_summary": tax, "is_cross_border": req.is_cross_border.unwrap_or(false), "bilateral_rules": bilateral, "nac_chain_id": 5132611, "protocol": "NAC_Lens/4.0" }, "protocol": "NAC_Lens/4.0" })), ) } /// POST /api/v1/rwa/contract-template async fn get_contract_template(Json(req): Json) -> impl IntoResponse { match req.contract_type.as_str() { "real_estate" => { match get_real_estate_template(&req.seller_jurisdiction) { Some(t) => (StatusCode::OK, Json(serde_json::json!({ "success": true, "data": { "contract_type": "real_estate", "template": t }, "protocol": "NAC_Lens/4.0" }))), None => (StatusCode::NOT_FOUND, Json(serde_json::json!({ "success": false, "error": format!("辖区 {} 暂无不动产合约模板", req.seller_jurisdiction), "protocol": "NAC_Lens/4.0" }))), } } "goods_trade" => { let buyer = req.buyer_jurisdiction.as_deref().unwrap_or("INTL"); match get_goods_trade_template(&req.seller_jurisdiction, buyer) { Some(t) => (StatusCode::OK, Json(serde_json::json!({ "success": true, "data": { "contract_type": "goods_trade", "template": t }, "protocol": "NAC_Lens/4.0" }))), None => (StatusCode::NOT_FOUND, Json(serde_json::json!({ "success": false, "error": format!("贸易对 {}-{} 暂无商品合约模板", req.seller_jurisdiction, buyer), "protocol": "NAC_Lens/4.0" }))), } } "ip_license" => { let licensee = req.buyer_jurisdiction.as_deref().unwrap_or("INTL"); match get_ip_license_template(&req.seller_jurisdiction, licensee) { Some(t) => (StatusCode::OK, Json(serde_json::json!({ "success": true, "data": { "contract_type": "ip_license", "template": t }, "protocol": "NAC_Lens/4.0" }))), None => (StatusCode::NOT_FOUND, Json(serde_json::json!({ "success": false, "error": format!("辖区 {} 暂无知识产权许可合约模板", req.seller_jurisdiction), "protocol": "NAC_Lens/4.0" }))), } } _ => (StatusCode::BAD_REQUEST, Json(serde_json::json!({ "success": false, "error": "不支持的合约类型。支持:real_estate / goods_trade / ip_license", "protocol": "NAC_Lens/4.0" }))), } } /// GET /api/v1/rwa/bilateral/:from/:to async fn get_bilateral(Path((from, to)): Path<(String, String)>) -> impl IntoResponse { match get_bilateral_matrix(&from, &to) { Some(rules) => (StatusCode::OK, Json(serde_json::json!({ "success": true, "data": rules, "protocol": "NAC_Lens/4.0" }))), None => { let pairs = list_available_pairs(); let pair_list: Vec = pairs.iter().map(|(a, b)| format!("{}-{}", a, b)).collect(); (StatusCode::NOT_FOUND, Json(serde_json::json!({ "success": false, "error": format!("暂无 {}-{} 双边贸易规则", from, to), "available_pairs": pair_list, "protocol": "NAC_Lens/4.0" }))) } } } /// GET /api/v1/rwa/bilateral — 列出所有可用双边贸易规则对 async fn list_bilateral_pairs() -> impl IntoResponse { let pairs = list_available_pairs(); let pair_list: Vec = pairs.iter().map(|(a, b)| serde_json::json!({ "from": a, "to": b, "pair": format!("{}-{}", a, b) })).collect(); (StatusCode::OK, Json(serde_json::json!({ "success": true, "total": pair_list.len(), "data": { "available_pairs": pair_list }, "protocol": "NAC_Lens/4.0" }))) } /// POST /api/v1/rwa/sharia-check async fn sharia_check(Json(req): Json) -> impl IntoResponse { let structure = match req.structure.as_str() { "Murabaha" => IslamicFinanceStructure::Murabaha, "Ijara" => IslamicFinanceStructure::Ijara, "IjaraWaIqtina" => IslamicFinanceStructure::IjaraWaIqtina, "Musharakah" => IslamicFinanceStructure::Musharakah, "Mudarabah" => IslamicFinanceStructure::Mudarabah, "Sukuk" => IslamicFinanceStructure::Sukuk, "Istisna" => IslamicFinanceStructure::Istisna, "Salam" => IslamicFinanceStructure::Salam, "Wakalah" => IslamicFinanceStructure::Wakalah, "Takaful" => IslamicFinanceStructure::Takaful, _ => return (StatusCode::BAD_REQUEST, Json(serde_json::json!({ "success": false, "error": format!("不支持的金融结构:{}。支持:Murabaha/Ijara/IjaraWaIqtina/Musharakah/Mudarabah/Sukuk/Istisna/Salam/Wakalah/Takaful", req.structure), "protocol": "NAC_Lens/4.0" }))), }; let framework = match get_sharia_framework(&req.jurisdiction) { Some(f) => f, None => return (StatusCode::NOT_FOUND, Json(serde_json::json!({ "success": false, "error": format!("辖区 {} 不在 Sharia 合规覆盖范围内。支持:AE/SA/MY", req.jurisdiction), "protocol": "NAC_Lens/4.0" }))), }; let result = validate_sharia_compliance( &req.jurisdiction, &structure, req.has_interest, req.has_excessive_uncertainty, req.involves_haram_goods, ); (StatusCode::OK, Json(serde_json::json!({ "success": true, "data": { "jurisdiction": req.jurisdiction, "jurisdiction_name": framework.jurisdiction_name, "structure": req.structure, "is_sharia_compliant": result.is_compliant, "violations": result.violations, "recommendations": result.recommendations, "requires_fatwa": result.requires_fatwa, "regulatory_body": framework.regulatory_body, "sharia_board_required": framework.sharia_board.required, "minimum_scholars": framework.sharia_board.minimum_scholars, "supported_structures": framework.supported_structures.iter().map(|s| format!("{:?}", s)).collect::>() }, "protocol": "NAC_Lens/4.0" }))) } /// GET /api/v1/rwa/sharia/jurisdictions async fn list_sharia_jurisdictions() -> impl IntoResponse { let mut result = Vec::new(); for j in &["AE", "SA", "MY"] { if let Some(f) = get_sharia_framework(j) { result.push(serde_json::json!({ "code": f.jurisdiction, "name": f.jurisdiction_name, "regulatory_body": f.regulatory_body, "supported_structures": f.supported_structures.iter().map(|s| format!("{:?}", s)).collect::>(), "sharia_board_required": f.sharia_board.required, "fatwa_required": f.sharia_board.fatwa_required, "minimum_scholars": f.sharia_board.minimum_scholars })); } } Json(serde_json::json!({ "success": true, "data": result, "protocol": "NAC_Lens/4.0" })) }