chore(#044): 版本整理,归档旧版本,统一使用最新版本
## 变更内容 ### 归档(旧版本 → _archive/v1_legacy_nrpc3/) - nac-sdk/src/client/nrpc3.rs → _archive/v1_legacy_nrpc3/nrpc3_client.rs - nac-nrpc/ (v3.0.0) → _archive/v1_legacy_nrpc3/nac-nrpc-v3.0.0/ - nac-csnp/nac-nrpc/ (v3.0.0) → _archive/v1_legacy_nrpc3/nac-csnp-nac-nrpc-v3.0.0/ - nac-sdk/src/protocols/acc721.rs.bak2 → _archive/v1_legacy_nrpc3/bak_files/ ### 版本更新 - nac-sdk: 2.0.0 → 2.1.0(支持 NAC Lens 协议) - nac-nrpc: 3.0.0 → 4.0.0(与 NAC Lens 对齐) - nac-csnp/nac-nrpc: 3.0.0 → 4.0.0 ### 依赖更新 - nac-sdk/Cargo.toml: nac-nrpc4 → nac-lens - nac-sdk/src/client/mod.rs: 移除 nrpc3 引用,改为 pub use nac_lens::* 关联工单: #042 #043 #044
This commit is contained in:
parent
0f61a40e22
commit
c9570fe2e1
|
|
@ -0,0 +1,20 @@
|
|||
# 归档说明:NRPC 3.0 旧版本
|
||||
|
||||
**归档时间**: 2026-02-22
|
||||
**归档原因**: 工单 #044 - 版本整理
|
||||
**关联工单**: #042(更名)、#043(API统一)、#044(版本整理)
|
||||
|
||||
## 归档内容
|
||||
|
||||
| 文件/目录 | 原路径 | 归档原因 |
|
||||
|---|---|---|
|
||||
| `nrpc3_client.rs` | `nac-sdk/src/client/nrpc3.rs` | 旧版 NRPC3.0 客户端,已被 NAC Lens 替代 |
|
||||
| `nac-nrpc-v3.0.0/` | `nac-nrpc/` | NRPC 3.0 协议实现,已被 `nac-lens/` 替代 |
|
||||
| `nac-csnp-nac-nrpc-v3.0.0/` | `nac-csnp/nac-nrpc/` | CSNP 内嵌的 NRPC3.0,已被 NAC Lens 替代 |
|
||||
| `bak_files/` | 各处 `.bak*` 文件 | 历史备份文件 |
|
||||
|
||||
## 当前最新版本
|
||||
|
||||
- **协议**: `nac-lens/` (NAC Lens, 原 NRPC4.0)
|
||||
- **SDK 客户端**: `nac-sdk/src/client/` (使用 nac-lens 依赖)
|
||||
- **版本**: nac-lens v0.1.0, nac-sdk v2.0.0
|
||||
|
|
@ -0,0 +1,521 @@
|
|||
//! ACC-721: 唯一资产证书协议接口
|
||||
//!
|
||||
//! 提供与NAC区块链上ACC-721证书交互的客户端接口
|
||||
|
||||
use crate::client::NRPC3Client;
|
||||
use crate::error::{NACError, Result};
|
||||
use crate::types::*;
|
||||
use nac_udm::primitives::{Address, Hash, Timestamp};
|
||||
use nac_udm::l1_protocol::gnacs::GNACSCode;
|
||||
use nac_udm::l1_protocol::acc::acc721::{
|
||||
AssetId, SovereigntyType, AssetDNA, AssetValuation,
|
||||
CustodyInfo, InsuranceInfo, CollateralInfo, FragmentationPool,
|
||||
};
|
||||
use serde_json::json;
|
||||
|
||||
/// ACC-721唯一资产证书接口
|
||||
pub struct ACC721 {
|
||||
client: NRPC3Client,
|
||||
}
|
||||
|
||||
impl ACC721 {
|
||||
/// 创建新的ACC-721接口实例
|
||||
pub fn new(client: NRPC3Client) -> Self {
|
||||
Self { client }
|
||||
}
|
||||
|
||||
/// 获取资产持有者
|
||||
///
|
||||
/// # 参数
|
||||
/// * `certificate_address` - 证书地址
|
||||
/// * `asset_id` - 资产ID
|
||||
///
|
||||
/// # 返回
|
||||
/// 资产持有者地址
|
||||
pub async fn get_asset_holder(
|
||||
&self,
|
||||
certificate_address: &Address,
|
||||
asset_id: AssetId,
|
||||
) -> Result<Address> {
|
||||
let params = json!({
|
||||
"certificate_address": certificate_address,
|
||||
"asset_id": asset_id,
|
||||
});
|
||||
|
||||
let response = self.client.call("acc721_getAssetHolder", params).await?;
|
||||
|
||||
let holder_hex = response["result"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing holder address".to_string()))?;
|
||||
|
||||
Address::from_hex(holder_hex)
|
||||
.map_err(|e| NACError::InvalidAddress(format!("Invalid holder address: {}", e)))
|
||||
}
|
||||
|
||||
/// 铸造唯一资产
|
||||
///
|
||||
/// # 参数
|
||||
/// * `certificate_address` - 证书地址
|
||||
/// * `to` - 接收者地址
|
||||
/// * `asset_id` - 资产ID
|
||||
/// * `metadata_uri` - 资产元数据URI
|
||||
/// * `physical_fingerprint` - 物理指纹哈希
|
||||
/// * `legal_document_hash` - 法律文件哈希
|
||||
/// * `custodian` - 托管方地址
|
||||
/// * `insurer` - 保险方地址
|
||||
/// * `insurance_coverage` - 保险金额(XTZH)
|
||||
/// * `insurance_expiry` - 保险到期时间
|
||||
///
|
||||
/// # 返回
|
||||
/// 资产DNA
|
||||
pub async fn mint_asset(
|
||||
&self,
|
||||
certificate_address: &Address,
|
||||
to: &Address,
|
||||
asset_id: AssetId,
|
||||
metadata_uri: String,
|
||||
physical_fingerprint: Hash,
|
||||
legal_document_hash: Hash,
|
||||
custodian: Address,
|
||||
insurer: Address,
|
||||
insurance_coverage: u128,
|
||||
insurance_expiry: Timestamp,
|
||||
) -> Result<AssetDNA> {
|
||||
let params = json!({
|
||||
"certificate_address": certificate_address,
|
||||
"to": to,
|
||||
"asset_id": asset_id,
|
||||
"metadata_uri": metadata_uri,
|
||||
"physical_fingerprint": physical_fingerprint,
|
||||
"legal_document_hash": legal_document_hash,
|
||||
"custodian": custodian,
|
||||
"insurer": insurer,
|
||||
"insurance_coverage": insurance_coverage,
|
||||
"insurance_expiry": insurance_expiry,
|
||||
});
|
||||
|
||||
let response = self.client.call("acc721_mintAsset", params).await?;
|
||||
|
||||
// 解析AssetDNA
|
||||
let dna_data = &response["result"];
|
||||
let asset_dna = AssetDNA {
|
||||
dna_hash: Hash::from_hex(
|
||||
dna_data["dna_hash"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing dna_hash".to_string()))?
|
||||
)?,
|
||||
physical_fingerprint,
|
||||
legal_document_hash,
|
||||
generated_at: Timestamp::from_secs(
|
||||
dna_data["generated_at"]
|
||||
.as_u64()
|
||||
.ok_or(NACError::InvalidResponse("Missing generated_at".to_string()))?
|
||||
),
|
||||
};
|
||||
|
||||
Ok(asset_dna)
|
||||
}
|
||||
|
||||
/// 转移唯一资产
|
||||
///
|
||||
/// # 参数
|
||||
/// * `certificate_address` - 证书地址
|
||||
/// * `from` - 发送者地址
|
||||
/// * `to` - 接收者地址
|
||||
/// * `asset_id` - 资产ID
|
||||
///
|
||||
/// # 返回
|
||||
/// 宪法收据哈希
|
||||
pub async fn transfer_asset(
|
||||
&self,
|
||||
certificate_address: &Address,
|
||||
from: &Address,
|
||||
to: &Address,
|
||||
asset_id: AssetId,
|
||||
) -> Result<Hash> {
|
||||
let params = json!({
|
||||
"certificate_address": certificate_address,
|
||||
"from": from,
|
||||
"to": to,
|
||||
"asset_id": asset_id,
|
||||
});
|
||||
|
||||
let response = self.client.call("acc721_transferAsset", params).await?;
|
||||
|
||||
let receipt_hash = response["result"]["constitutional_receipt"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing constitutional_receipt".to_string()))?;
|
||||
|
||||
Hash::from_hex(receipt_hash)
|
||||
.map_err(|e| NACError::InvalidHash(format!("Invalid receipt hash: {}", e)))
|
||||
}
|
||||
|
||||
/// 授权资产
|
||||
///
|
||||
/// # 参数
|
||||
/// * `certificate_address` - 证书地址
|
||||
/// * `owner` - 资产持有者地址
|
||||
/// * `approved` - 被授权者地址
|
||||
/// * `asset_id` - 资产ID
|
||||
pub async fn approve_asset(
|
||||
&self,
|
||||
certificate_address: &Address,
|
||||
owner: &Address,
|
||||
approved: &Address,
|
||||
asset_id: AssetId,
|
||||
) -> Result<()> {
|
||||
let params = json!({
|
||||
"certificate_address": certificate_address,
|
||||
"owner": owner,
|
||||
"approved": approved,
|
||||
"asset_id": asset_id,
|
||||
});
|
||||
|
||||
self.client.call("acc721_approveAsset", params).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 销毁资产
|
||||
///
|
||||
/// # 参数
|
||||
/// * `certificate_address` - 证书地址
|
||||
/// * `owner` - 资产持有者地址
|
||||
/// * `asset_id` - 资产ID
|
||||
pub async fn burn_asset(
|
||||
&self,
|
||||
certificate_address: &Address,
|
||||
owner: &Address,
|
||||
asset_id: AssetId,
|
||||
) -> Result<()> {
|
||||
let params = json!({
|
||||
"certificate_address": certificate_address,
|
||||
"owner": owner,
|
||||
"asset_id": asset_id,
|
||||
});
|
||||
|
||||
self.client.call("acc721_burnAsset", params).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 碎片化资产
|
||||
///
|
||||
/// 将唯一资产碎片化为多个ACC-20代币
|
||||
///
|
||||
/// # 参数
|
||||
/// * `certificate_address` - 证书地址
|
||||
/// * `owner` - 资产持有者地址
|
||||
/// * `asset_id` - 资产ID
|
||||
/// * `fragment_count` - 碎片总数
|
||||
/// * `fragment_price` - 碎片价格(XTZH)
|
||||
///
|
||||
/// # 返回
|
||||
/// 碎片化池信息
|
||||
pub async fn fragmentize_asset(
|
||||
&self,
|
||||
certificate_address: &Address,
|
||||
owner: &Address,
|
||||
asset_id: AssetId,
|
||||
fragment_count: u64,
|
||||
fragment_price: u128,
|
||||
) -> Result<FragmentationPool> {
|
||||
let params = json!({
|
||||
"certificate_address": certificate_address,
|
||||
"owner": owner,
|
||||
"asset_id": asset_id,
|
||||
"fragment_count": fragment_count,
|
||||
"fragment_price": fragment_price,
|
||||
});
|
||||
|
||||
let response = self.client.call("acc721_fragmentizeAsset", params).await?;
|
||||
|
||||
// 解析FragmentationPool
|
||||
let pool_data = &response["result"];
|
||||
let pool = FragmentationPool {
|
||||
fragment_token_address: Address::from_hex(
|
||||
pool_data["fragment_token_address"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing fragment_token_address".to_string()))?
|
||||
)?,
|
||||
total_fragments: pool_data["total_fragments"]
|
||||
.as_u64()
|
||||
.ok_or(NACError::InvalidResponse("Missing total_fragments".to_string()))?,
|
||||
fragment_price_xtzh: pool_data["fragment_price_xtzh"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing fragment_price_xtzh".to_string()))?
|
||||
.parse()
|
||||
.map_err(|e| NACError::InvalidResponse(format!("Invalid fragment_price: {}", e)))?,
|
||||
fragmentized_at: Timestamp::from_secs(
|
||||
pool_data["fragmentized_at"]
|
||||
.as_u64()
|
||||
.ok_or(NACError::InvalidResponse("Missing fragmentized_at".to_string()))?
|
||||
),
|
||||
is_recomposable: pool_data["is_recomposable"]
|
||||
.as_bool()
|
||||
.ok_or(NACError::InvalidResponse("Missing is_recomposable".to_string()))?,
|
||||
};
|
||||
|
||||
Ok(pool)
|
||||
}
|
||||
|
||||
/// 更新资产估值
|
||||
///
|
||||
/// # 参数
|
||||
/// * `certificate_address` - 证书地址
|
||||
/// * `asset_id` - 资产ID
|
||||
/// * `valuation` - 新的资产估值
|
||||
pub async fn update_valuation(
|
||||
&self,
|
||||
certificate_address: &Address,
|
||||
asset_id: AssetId,
|
||||
valuation: AssetValuation,
|
||||
) -> Result<()> {
|
||||
let params = json!({
|
||||
"certificate_address": certificate_address,
|
||||
"asset_id": asset_id,
|
||||
"valuation": {
|
||||
"value_xtzh": valuation.value_xtzh.to_string(),
|
||||
"valuation_provider": valuation.valuation_provider,
|
||||
"valued_at": valuation.valued_at.as_secs(),
|
||||
"validity_period": valuation.validity_period,
|
||||
},
|
||||
});
|
||||
|
||||
self.client.call("acc721_updateValuation", params).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// 获取资产估值
|
||||
///
|
||||
/// # 参数
|
||||
/// * `certificate_address` - 证书地址
|
||||
/// * `asset_id` - 资产ID
|
||||
///
|
||||
/// # 返回
|
||||
/// 资产估值
|
||||
pub async fn get_asset_valuation(
|
||||
&self,
|
||||
certificate_address: &Address,
|
||||
asset_id: AssetId,
|
||||
) -> Result<AssetValuation> {
|
||||
let params = json!({
|
||||
"certificate_address": certificate_address,
|
||||
"asset_id": asset_id,
|
||||
});
|
||||
|
||||
let response = self.client.call("acc721_getAssetValuation", params).await?;
|
||||
|
||||
// 解析AssetValuation
|
||||
let val_data = &response["result"];
|
||||
let valuation = AssetValuation {
|
||||
value_xtzh: val_data["value_xtzh"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing value_xtzh".to_string()))?
|
||||
.parse()
|
||||
.map_err(|e| NACError::InvalidResponse(format!("Invalid value_xtzh: {}", e)))?,
|
||||
valuation_provider: Address::from_hex(
|
||||
val_data["valuation_provider"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing valuation_provider".to_string()))?
|
||||
)?,
|
||||
valued_at: Timestamp::from_secs(
|
||||
val_data["valued_at"]
|
||||
.as_u64()
|
||||
.ok_or(NACError::InvalidResponse("Missing valued_at".to_string()))?
|
||||
),
|
||||
validity_period: val_data["validity_period"]
|
||||
.as_u64()
|
||||
.ok_or(NACError::InvalidResponse("Missing validity_period".to_string()))?,
|
||||
};
|
||||
|
||||
Ok(valuation)
|
||||
}
|
||||
|
||||
/// 获取资产DNA
|
||||
///
|
||||
/// # 参数
|
||||
/// * `certificate_address` - 证书地址
|
||||
/// * `asset_id` - 资产ID
|
||||
///
|
||||
/// # 返回
|
||||
/// 资产DNA
|
||||
pub async fn get_asset_dna(
|
||||
&self,
|
||||
certificate_address: &Address,
|
||||
asset_id: AssetId,
|
||||
) -> Result<AssetDNA> {
|
||||
let params = json!({
|
||||
"certificate_address": certificate_address,
|
||||
"asset_id": asset_id,
|
||||
});
|
||||
|
||||
let response = self.client.call("acc721_getAssetDNA", params).await?;
|
||||
|
||||
// 解析AssetDNA
|
||||
let dna_data = &response["result"];
|
||||
let asset_dna = AssetDNA {
|
||||
dna_hash: Hash::from_hex(
|
||||
dna_data["dna_hash"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing dna_hash".to_string()))?
|
||||
)?,
|
||||
physical_fingerprint: Hash::from_hex(
|
||||
dna_data["physical_fingerprint"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing physical_fingerprint".to_string()))?
|
||||
)?,
|
||||
legal_document_hash: Hash::from_hex(
|
||||
dna_data["legal_document_hash"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing legal_document_hash".to_string()))?
|
||||
)?,
|
||||
generated_at: Timestamp::from_secs(
|
||||
dna_data["generated_at"]
|
||||
.as_u64()
|
||||
.ok_or(NACError::InvalidResponse("Missing generated_at".to_string()))?
|
||||
),
|
||||
};
|
||||
|
||||
Ok(asset_dna)
|
||||
}
|
||||
|
||||
/// 获取资产元数据
|
||||
///
|
||||
/// # 参数
|
||||
/// * `certificate_address` - 证书地址
|
||||
/// * `asset_id` - 资产ID
|
||||
///
|
||||
/// # 返回
|
||||
/// 资产元数据URI
|
||||
pub async fn get_asset_metadata(
|
||||
&self,
|
||||
certificate_address: &Address,
|
||||
asset_id: AssetId,
|
||||
) -> Result<String> {
|
||||
let params = json!({
|
||||
"certificate_address": certificate_address,
|
||||
"asset_id": asset_id,
|
||||
});
|
||||
|
||||
let response = self.client.call("acc721_getAssetMetadata", params).await?;
|
||||
|
||||
let metadata_uri = response["result"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing metadata URI".to_string()))?
|
||||
.to_string();
|
||||
|
||||
Ok(metadata_uri)
|
||||
}
|
||||
|
||||
/// 获取托管信息
|
||||
///
|
||||
/// # 参数
|
||||
/// * `certificate_address` - 证书地址
|
||||
/// * `asset_id` - 资产ID
|
||||
///
|
||||
/// # 返回
|
||||
/// 托管信息
|
||||
pub async fn get_custody_info(
|
||||
&self,
|
||||
certificate_address: &Address,
|
||||
asset_id: AssetId,
|
||||
) -> Result<CustodyInfo> {
|
||||
let params = json!({
|
||||
"certificate_address": certificate_address,
|
||||
"asset_id": asset_id,
|
||||
});
|
||||
|
||||
let response = self.client.call("acc721_getCustodyInfo", params).await?;
|
||||
|
||||
// 解析CustodyInfo
|
||||
let custody_data = &response["result"];
|
||||
let custody_info = CustodyInfo {
|
||||
custodian: Address::from_hex(
|
||||
custody_data["custodian"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing custodian".to_string()))?
|
||||
)?,
|
||||
custody_start: Timestamp::from_secs(
|
||||
custody_data["custody_start"]
|
||||
.as_u64()
|
||||
.ok_or(NACError::InvalidResponse("Missing custody_start".to_string()))?
|
||||
),
|
||||
is_active: custody_data["is_active"]
|
||||
.as_bool()
|
||||
.ok_or(NACError::InvalidResponse("Missing is_active".to_string()))?,
|
||||
custody_proof: Hash::from_hex(
|
||||
custody_data["custody_proof"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing custody_proof".to_string()))?
|
||||
)?,
|
||||
};
|
||||
|
||||
Ok(custody_info)
|
||||
}
|
||||
|
||||
/// 获取保险信息
|
||||
///
|
||||
/// # 参数
|
||||
/// * `certificate_address` - 证书地址
|
||||
/// * `asset_id` - 资产ID
|
||||
///
|
||||
/// # 返回
|
||||
/// 保险信息
|
||||
pub async fn get_insurance_info(
|
||||
&self,
|
||||
certificate_address: &Address,
|
||||
asset_id: AssetId,
|
||||
) -> Result<InsuranceInfo> {
|
||||
let params = json!({
|
||||
"certificate_address": certificate_address,
|
||||
"asset_id": asset_id,
|
||||
});
|
||||
|
||||
let response = self.client.call("acc721_getInsuranceInfo", params).await?;
|
||||
|
||||
// 解析InsuranceInfo
|
||||
let insurance_data = &response["result"];
|
||||
let insurance_info = InsuranceInfo {
|
||||
insurer: Address::from_hex(
|
||||
insurance_data["insurer"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing insurer".to_string()))?
|
||||
)?,
|
||||
coverage_xtzh: insurance_data["coverage_xtzh"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing coverage_xtzh".to_string()))?
|
||||
.parse()
|
||||
.map_err(|e| NACError::InvalidResponse(format!("Invalid coverage_xtzh: {}", e)))?,
|
||||
insurance_start: Timestamp::from_secs(
|
||||
insurance_data["insurance_start"]
|
||||
.as_u64()
|
||||
.ok_or(NACError::InvalidResponse("Missing insurance_start".to_string()))?
|
||||
),
|
||||
insurance_expiry: Timestamp::from_secs(
|
||||
insurance_data["insurance_expiry"]
|
||||
.as_u64()
|
||||
.ok_or(NACError::InvalidResponse("Missing insurance_expiry".to_string()))?
|
||||
),
|
||||
policy_number: insurance_data["policy_number"]
|
||||
.as_str()
|
||||
.ok_or(NACError::InvalidResponse("Missing policy_number".to_string()))?
|
||||
.to_string(),
|
||||
};
|
||||
|
||||
Ok(insurance_info)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_acc721_interface() {
|
||||
// 这里只是接口测试,实际需要连接到NAC节点
|
||||
let client = NRPC3Client::new("https://rpc.newassetchain.io");
|
||||
let acc721 = ACC721::new(client);
|
||||
|
||||
// 测试将在实际连接到NAC节点后进行
|
||||
assert!(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
[package]
|
||||
name = "nac-nrpc"
|
||||
version = "3.0.0"
|
||||
edition = "2021"
|
||||
authors = ["NAC公链开发小组"]
|
||||
description = "NAC远程过程调用协议(NRPC3.0)"
|
||||
|
||||
[dependencies]
|
||||
tokio = { version = "1.0", features = ["full"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
anyhow = "1.0"
|
||||
thiserror = "1.0"
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
pub fn add(left: u64, right: u64) -> u64 {
|
||||
left + right
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let result = add(2, 2);
|
||||
assert_eq!(result, 4);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
/target
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,58 @@
|
|||
[package]
|
||||
name = "nac-nrpc"
|
||||
version = "3.0.0"
|
||||
edition = "2021"
|
||||
authors = ["NAC Development Team"]
|
||||
description = "NRPC 3.0 - NAC原生RPC协议服务器"
|
||||
license = "MIT"
|
||||
|
||||
[dependencies]
|
||||
nac-upgrade-framework = { path = "../nac-upgrade-framework" }
|
||||
# NAC核心依赖
|
||||
nac-udm = { path = "../nac-udm" }
|
||||
|
||||
# 异步运行时
|
||||
tokio = { version = "1.35", features = ["full"] }
|
||||
async-trait = "0.1"
|
||||
|
||||
# Web框架
|
||||
axum = { version = "0.7", features = ["ws", "macros"] }
|
||||
tower = { version = "0.4", features = ["util"] }
|
||||
tower-http = { version = "0.5", features = ["cors", "trace"] }
|
||||
|
||||
# 序列化
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
||||
# HTTP客户端
|
||||
reqwest = { version = "0.11", features = ["json"] }
|
||||
|
||||
# 日志
|
||||
tracing = "0.1"
|
||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||
|
||||
# 错误处理
|
||||
thiserror = "1.0"
|
||||
anyhow = "1.0"
|
||||
|
||||
# 时间处理
|
||||
chrono = "0.4"
|
||||
|
||||
# 并发
|
||||
futures = "0.3"
|
||||
parking_lot = "0.12"
|
||||
|
||||
# 哈希
|
||||
sha3 = "0.10"
|
||||
blake3 = "1.5"
|
||||
|
||||
[dev-dependencies]
|
||||
tokio-test = "0.4"
|
||||
|
||||
[lib]
|
||||
name = "nac_nrpc"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "nac-nrpc-server"
|
||||
path = "src/bin/server.rs"
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
# nac-nrpc-server
|
||||
|
||||
**模块名称**: nac-nrpc-server
|
||||
**描述**: NRPC 3.0 - NAC原生RPC协议服务器
|
||||
**最后更新**: 2026-02-18
|
||||
|
||||
---
|
||||
|
||||
## 目录结构
|
||||
|
||||
```
|
||||
nac-nrpc/
|
||||
├── Cargo.toml
|
||||
├── README.md (本文件)
|
||||
└── src/
|
||||
├── lib.rs
|
||||
├── protocol.rs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 源文件说明
|
||||
|
||||
### lib.rs
|
||||
- **功能**: 待补充
|
||||
- **依赖**: 待补充
|
||||
|
||||
### protocol.rs
|
||||
- **功能**: 待补充
|
||||
- **依赖**: 待补充
|
||||
|
||||
---
|
||||
|
||||
## 编译和测试
|
||||
|
||||
```bash
|
||||
# 编译
|
||||
cargo build
|
||||
|
||||
# 测试
|
||||
cargo test
|
||||
|
||||
# 运行
|
||||
cargo run
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**维护**: NAC开发团队
|
||||
**创建日期**: 2026-02-18
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
pub fn add(left: u64, right: u64) -> u64 {
|
||||
left + right
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let result = add(2, 2);
|
||||
assert_eq!(result, 4);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,253 @@
|
|||
//! NRPC 3.0协议类型定义
|
||||
//!
|
||||
//! 定义NRPC 3.0协议的核心数据结构
|
||||
|
||||
use nac_udm::primitives::{Hash, Timestamp};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
/// NRPC 3.0请求
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct NRPC3Request {
|
||||
/// JSON-RPC版本(固定为"3.0")
|
||||
pub jsonrpc: String,
|
||||
|
||||
/// 请求ID
|
||||
pub id: RequestId,
|
||||
|
||||
/// 方法名
|
||||
pub method: String,
|
||||
|
||||
/// 参数
|
||||
pub params: Value,
|
||||
|
||||
/// 时间戳(NAC扩展)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub timestamp: Option<Timestamp>,
|
||||
|
||||
/// 资产DNA哈希(NAC扩展)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub dna_hash: Option<Hash>,
|
||||
|
||||
/// 签名(NAC扩展)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub signature: Option<String>,
|
||||
}
|
||||
|
||||
/// NRPC 3.0响应
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct NRPC3Response {
|
||||
/// JSON-RPC版本
|
||||
pub jsonrpc: String,
|
||||
|
||||
/// 请求ID
|
||||
pub id: RequestId,
|
||||
|
||||
/// 结果(成功时)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub result: Option<Value>,
|
||||
|
||||
/// 错误(失败时)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub error: Option<NRPC3Error>,
|
||||
|
||||
/// 时间戳(NAC扩展)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub timestamp: Option<Timestamp>,
|
||||
|
||||
/// 服务器签名(NAC扩展)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub server_signature: Option<String>,
|
||||
}
|
||||
|
||||
/// NRPC 3.0错误
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct NRPC3Error {
|
||||
/// 错误代码
|
||||
pub code: i32,
|
||||
|
||||
/// 错误消息
|
||||
pub message: String,
|
||||
|
||||
/// 错误数据(可选)
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub data: Option<Value>,
|
||||
}
|
||||
|
||||
/// 请求ID类型
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
|
||||
#[serde(untagged)]
|
||||
pub enum RequestId {
|
||||
/// 数字ID
|
||||
Number(u64),
|
||||
|
||||
/// 字符串ID
|
||||
String(String),
|
||||
|
||||
/// 空ID(通知)
|
||||
Null,
|
||||
}
|
||||
|
||||
/// NRPC 3.0批量请求
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct NRPC3BatchRequest {
|
||||
/// 批量请求列表
|
||||
pub requests: Vec<NRPC3Request>,
|
||||
}
|
||||
|
||||
/// NRPC 3.0批量响应
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct NRPC3BatchResponse {
|
||||
/// 批量响应列表
|
||||
pub responses: Vec<NRPC3Response>,
|
||||
}
|
||||
|
||||
/// NRPC 3.0错误代码
|
||||
pub mod error_codes {
|
||||
/// 解析错误
|
||||
pub const PARSE_ERROR: i32 = -32700;
|
||||
|
||||
/// 无效请求
|
||||
pub const INVALID_REQUEST: i32 = -32600;
|
||||
|
||||
/// 方法不存在
|
||||
pub const METHOD_NOT_FOUND: i32 = -32601;
|
||||
|
||||
/// 无效参数
|
||||
pub const INVALID_PARAMS: i32 = -32602;
|
||||
|
||||
/// 内部错误
|
||||
pub const INTERNAL_ERROR: i32 = -32603;
|
||||
|
||||
/// 服务器错误范围
|
||||
pub const SERVER_ERROR_START: i32 = -32000;
|
||||
pub const SERVER_ERROR_END: i32 = -32099;
|
||||
|
||||
// NAC扩展错误代码
|
||||
|
||||
/// 时间戳过期
|
||||
pub const TIMESTAMP_EXPIRED: i32 = -33001;
|
||||
|
||||
/// DNA验证失败
|
||||
pub const DNA_VERIFICATION_FAILED: i32 = -33002;
|
||||
|
||||
/// 签名无效
|
||||
pub const INVALID_SIGNATURE: i32 = -33003;
|
||||
|
||||
/// 合规检查失败
|
||||
pub const COMPLIANCE_CHECK_FAILED: i32 = -33004;
|
||||
|
||||
/// 权限不足
|
||||
pub const INSUFFICIENT_PERMISSIONS: i32 = -33005;
|
||||
}
|
||||
|
||||
impl NRPC3Request {
|
||||
/// 创建新请求
|
||||
pub fn new(id: RequestId, method: impl Into<String>, params: Value) -> Self {
|
||||
Self {
|
||||
jsonrpc: "3.0".to_string(),
|
||||
id,
|
||||
method: method.into(),
|
||||
params,
|
||||
timestamp: Some(Timestamp::now()),
|
||||
dna_hash: None,
|
||||
signature: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// 验证请求
|
||||
pub fn validate(&self) -> Result<(), String> {
|
||||
if self.jsonrpc != "3.0" {
|
||||
return Err("Invalid JSON-RPC version".to_string());
|
||||
}
|
||||
|
||||
if self.method.is_empty() {
|
||||
return Err("Method name cannot be empty".to_string());
|
||||
}
|
||||
|
||||
// 验证时间戳(如果存在)
|
||||
if let Some(ts) = self.timestamp {
|
||||
let now = Timestamp::now();
|
||||
let diff = if now > ts { now - ts } else { ts - now };
|
||||
|
||||
// 允许5分钟的时间偏差
|
||||
if diff > 300 {
|
||||
return Err("Timestamp expired or too far in future".to_string());
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl NRPC3Response {
|
||||
/// 创建成功响应
|
||||
pub fn success(id: RequestId, result: Value) -> Self {
|
||||
Self {
|
||||
jsonrpc: "3.0".to_string(),
|
||||
id,
|
||||
result: Some(result),
|
||||
error: None,
|
||||
timestamp: Some(Timestamp::now()),
|
||||
server_signature: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// 创建错误响应
|
||||
pub fn error(id: RequestId, code: i32, message: impl Into<String>) -> Self {
|
||||
Self {
|
||||
jsonrpc: "3.0".to_string(),
|
||||
id,
|
||||
result: None,
|
||||
error: Some(NRPC3Error {
|
||||
code,
|
||||
message: message.into(),
|
||||
data: None,
|
||||
}),
|
||||
timestamp: Some(Timestamp::now()),
|
||||
server_signature: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use serde_json::json;
|
||||
|
||||
#[test]
|
||||
fn test_request_creation() {
|
||||
let req = NRPC3Request::new(
|
||||
RequestId::Number(1),
|
||||
"test_method",
|
||||
json!({"param": "value"}),
|
||||
);
|
||||
|
||||
assert_eq!(req.jsonrpc, "3.0");
|
||||
assert_eq!(req.method, "test_method");
|
||||
assert!(req.timestamp.is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_request_validation() {
|
||||
let req = NRPC3Request::new(
|
||||
RequestId::Number(1),
|
||||
"test_method",
|
||||
json!({}),
|
||||
);
|
||||
|
||||
assert!(req.validate().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_response_creation() {
|
||||
let resp = NRPC3Response::success(
|
||||
RequestId::Number(1),
|
||||
json!({"result": "success"}),
|
||||
);
|
||||
|
||||
assert_eq!(resp.jsonrpc, "3.0");
|
||||
assert!(resp.result.is_some());
|
||||
assert!(resp.error.is_none());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
//! 模块升级实现
|
||||
|
||||
use nac_upgrade_framework::{
|
||||
traits::Upgradeable, UpgradeData, UpgradeRecord, Version, Result, UpgradeError,
|
||||
};
|
||||
|
||||
// 注意:需要在主结构体中添加以下字段:
|
||||
// - version: Version
|
||||
// - upgrade_history: Vec<UpgradeRecord>
|
||||
//
|
||||
// 并实现 do_upgrade 方法来执行实际的升级逻辑
|
||||
|
||||
// 使用宏快速实现Upgradeable trait:
|
||||
// nac_upgrade_framework::impl_upgradeable!(YourStruct, "module-name", Version::new(1, 0, 0));
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "nac-nrpc"
|
||||
version = "3.0.0"
|
||||
version = "4.0.0"
|
||||
edition = "2021"
|
||||
authors = ["NAC公链开发小组"]
|
||||
description = "NAC远程过程调用协议(NRPC3.0)"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "nac-nrpc"
|
||||
version = "3.0.0"
|
||||
version = "4.0.0"
|
||||
edition = "2021"
|
||||
authors = ["NAC Development Team"]
|
||||
description = "NRPC 3.0 - NAC原生RPC协议服务器"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "nac-sdk"
|
||||
version = "2.0.0"
|
||||
version = "2.1.0"
|
||||
edition = "2021"
|
||||
authors = ["NAC Team"]
|
||||
description = "NAC (NewAssetChain) SDK - Native Rust Implementation for RWA Blockchain"
|
||||
|
|
@ -14,7 +14,7 @@ nac-upgrade-framework = { path = "../nac-upgrade-framework" }
|
|||
nac-udm = { path = "../nac-udm" }
|
||||
nac-nvm = { path = "../nac-nvm" }
|
||||
nac-cbpp = { path = "../nac-cbpp" }
|
||||
nac-nrpc4 = { path = "../nac-nrpc4" }
|
||||
nac-lens = { path = "../nac-lens" }
|
||||
|
||||
# Cryptography
|
||||
blake3 = "1.5"
|
||||
|
|
|
|||
|
|
@ -1,24 +1,14 @@
|
|||
/*!
|
||||
# NAC SDK Client Module
|
||||
|
||||
NAC SDK的客户端模块,提供NRPC3.0协议客户端。
|
||||
NAC SDK 的客户端模块,提供 NAC Lens 协议客户端。
|
||||
|
||||
## 核心组件
|
||||
- NacLensClient - NAC Lens 协议 RPC 客户端(原 NRPC4.0,工单 #042 更名)
|
||||
|
||||
- `NRPC3Client` - NRPC3.0 RPC客户端
|
||||
- `NRPC3Request` - NRPC3.0请求
|
||||
- `NRPC3Response` - NRPC3.0响应
|
||||
- `NRPC3Error` - NRPC3.0错误
|
||||
|
||||
## NAC原生设计
|
||||
|
||||
- ✅ 使用NRPC3.0协议(而非JSON-RPC)
|
||||
- ✅ 支持量子DNA编码
|
||||
- ✅ 支持时空路由
|
||||
- ✅ 支持批量请求
|
||||
|
||||
## 版本历史
|
||||
- v1.x: NRPC3.0 客户端(已归档至 _archive/v1_legacy_nrpc3/)
|
||||
- v2.x: NAC Lens 客户端(当前版本)
|
||||
*/
|
||||
|
||||
mod nrpc3;
|
||||
|
||||
pub use nrpc3::*;
|
||||
pub use nac_lens::*;
|
||||
|
|
|
|||
Loading…
Reference in New Issue