完成工单#38: 完整实现NAC SDK的L1-L5层适配器
- L1协议层: 实现NVM虚拟机、CBPP共识、GNACS编码、ACC协议族(24个方法) - L2宪政/治理/网络层: 实现宪政审查、链上治理、CSNP网络(14个方法) - L3存储层: 实现状态数据库、区块存储、IPFS集成(16个方法) - L4 AI层: 实现AI合规、AI估值、AI风险、XTZH AI(12个方法) - L5应用层: 实现钱包、DApp、浏览器、交易所接口(18个方法) 总计84个完整实现的方法,提供可用的完全功能的SDK。 工单: #38
This commit is contained in:
parent
23f45d21dd
commit
252dbb1db8
|
|
@ -1,12 +1,543 @@
|
|||
//! L1协议层适配器(开发中)
|
||||
//! L1协议层适配器
|
||||
//!
|
||||
//! 提供NAC公链L1层的核心功能:
|
||||
//! - NVM虚拟机:部署和调用Charter智能合约
|
||||
//! - CBPP共识:交易提交和区块查询
|
||||
//! - GNACS编码:资产分类编码系统
|
||||
//! - ACC协议族:ACC-20、ACC-1400、XTZH稳定币
|
||||
//!
|
||||
//! # 示例
|
||||
//!
|
||||
//! ```rust
|
||||
//! use nac_sdk::adapters::{L1ProtocolAdapter, config::L1Config};
|
||||
//!
|
||||
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! // 创建L1适配器
|
||||
//! let config = L1Config {
|
||||
//! nrpc4_url: "http://localhost:8545".to_string(),
|
||||
//! chain_id: 1,
|
||||
//! timeout: std::time::Duration::from_secs(30),
|
||||
//! };
|
||||
//! let l1 = L1ProtocolAdapter::new(&config).await?;
|
||||
//!
|
||||
//! // 获取最新区块
|
||||
//! let block_number = l1.get_latest_block_number().await?;
|
||||
//! println!("Latest block: {}", block_number);
|
||||
//!
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use crate::error::Result;
|
||||
use crate::error::{NACError, Result};
|
||||
use super::config::L1Config;
|
||||
use nac_udm::primitives::{Address, Hash, Decimal};
|
||||
use nac_udm::types::{
|
||||
Block, Transaction, SignedTransaction, TransactionReceipt,
|
||||
GNACSCode, GNACSMetadata, ACC20Metadata, ACC1400Metadata,
|
||||
CollateralProof, CrossShardStatus,
|
||||
};
|
||||
use nac_nrpc4::client::NRPC4Client;
|
||||
use std::time::Duration;
|
||||
|
||||
pub struct L1ProtocolAdapter;
|
||||
/// L1协议层适配器
|
||||
///
|
||||
/// 统一封装NVM、CBPP、GNACS、ACC四大子系统
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct L1ProtocolAdapter {
|
||||
/// NRPC4客户端
|
||||
client: NRPC4Client,
|
||||
/// 链ID
|
||||
chain_id: u32,
|
||||
/// 超时时间
|
||||
timeout: Duration,
|
||||
}
|
||||
|
||||
impl L1ProtocolAdapter {
|
||||
pub async fn new(_config: &L1Config) -> Result<Self> {
|
||||
Ok(Self)
|
||||
/// 创建新的L1适配器
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `config` - L1层配置
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回初始化完成的L1适配器实例
|
||||
pub async fn new(config: &L1Config) -> Result<Self> {
|
||||
let client = NRPC4Client::new(&config.nrpc4_url, config.timeout)
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to create NRPC4 client: {}", e)))?;
|
||||
|
||||
Ok(Self {
|
||||
client,
|
||||
chain_id: config.chain_id,
|
||||
timeout: config.timeout,
|
||||
})
|
||||
}
|
||||
|
||||
// ===== NVM虚拟机 =====
|
||||
|
||||
/// 部署Charter智能合约
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `bytecode` - Charter合约字节码
|
||||
/// * `constructor_args` - 构造函数参数
|
||||
/// * `deployer` - 部署者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回部署的合约地址
|
||||
pub async fn deploy_contract(
|
||||
&self,
|
||||
bytecode: &[u8],
|
||||
constructor_args: &[u8],
|
||||
deployer: &Address,
|
||||
) -> Result<Address> {
|
||||
self.client
|
||||
.deploy_contract(bytecode, constructor_args, deployer, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::ContractError(format!("Failed to deploy contract: {}", e)))
|
||||
}
|
||||
|
||||
/// 调用合约方法
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `contract_addr` - 合约地址
|
||||
/// * `method` - 方法名
|
||||
/// * `args` - 方法参数
|
||||
/// * `caller` - 调用者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回方法调用结果
|
||||
pub async fn call_contract(
|
||||
&self,
|
||||
contract_addr: &Address,
|
||||
method: &str,
|
||||
args: &[u8],
|
||||
caller: &Address,
|
||||
) -> Result<Vec<u8>> {
|
||||
self.client
|
||||
.call_contract(contract_addr, method, args, caller, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::ContractError(format!("Failed to call contract: {}", e)))
|
||||
}
|
||||
|
||||
/// 查询合约状态
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `contract_addr` - 合约地址
|
||||
/// * `key` - 状态键
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回状态值
|
||||
pub async fn query_contract_state(
|
||||
&self,
|
||||
contract_addr: &Address,
|
||||
key: &[u8],
|
||||
) -> Result<Vec<u8>> {
|
||||
self.client
|
||||
.query_state(contract_addr, key, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::ContractError(format!("Failed to query contract state: {}", e)))
|
||||
}
|
||||
|
||||
/// 估算Gas消耗
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `tx` - 交易对象
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回预估的Gas消耗量
|
||||
pub async fn estimate_gas(
|
||||
&self,
|
||||
tx: &Transaction,
|
||||
) -> Result<u64> {
|
||||
self.client
|
||||
.estimate_gas(tx, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to estimate gas: {}", e)))
|
||||
}
|
||||
|
||||
// ===== CBPP共识 =====
|
||||
|
||||
/// 提交交易到交易池
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `tx` - 已签名的交易
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回交易哈希
|
||||
pub async fn submit_transaction(
|
||||
&self,
|
||||
tx: &SignedTransaction,
|
||||
) -> Result<Hash> {
|
||||
self.client
|
||||
.submit_transaction(tx, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to submit transaction: {}", e)))
|
||||
}
|
||||
|
||||
/// 获取区块(按高度)
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `block_number` - 区块高度
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回区块对象
|
||||
pub async fn get_block(
|
||||
&self,
|
||||
block_number: u64,
|
||||
) -> Result<Block> {
|
||||
self.client
|
||||
.get_block_by_number(block_number, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get block: {}", e)))
|
||||
}
|
||||
|
||||
/// 获取区块(按哈希)
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `block_hash` - 区块哈希
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回区块对象
|
||||
pub async fn get_block_by_hash(
|
||||
&self,
|
||||
block_hash: &Hash,
|
||||
) -> Result<Block> {
|
||||
self.client
|
||||
.get_block_by_hash(block_hash, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get block by hash: {}", e)))
|
||||
}
|
||||
|
||||
/// 获取最新区块高度
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回当前最新的区块高度
|
||||
pub async fn get_latest_block_number(&self) -> Result<u64> {
|
||||
self.client
|
||||
.get_latest_block_number(self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get latest block number: {}", e)))
|
||||
}
|
||||
|
||||
/// 获取交易收据
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `tx_hash` - 交易哈希
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回交易收据
|
||||
pub async fn get_transaction_receipt(
|
||||
&self,
|
||||
tx_hash: &Hash,
|
||||
) -> Result<TransactionReceipt> {
|
||||
self.client
|
||||
.get_transaction_receipt(tx_hash, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get transaction receipt: {}", e)))
|
||||
}
|
||||
|
||||
/// 等待交易确认
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `tx_hash` - 交易哈希
|
||||
/// * `confirmations` - 需要的确认数
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回交易收据
|
||||
pub async fn wait_for_confirmation(
|
||||
&self,
|
||||
tx_hash: &Hash,
|
||||
confirmations: u32,
|
||||
) -> Result<TransactionReceipt> {
|
||||
self.client
|
||||
.wait_for_confirmation(tx_hash, confirmations, self.chain_id, self.timeout)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to wait for confirmation: {}", e)))
|
||||
}
|
||||
|
||||
// ===== GNACS编码系统 =====
|
||||
|
||||
/// 生成GNACS编码
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `asset_type` - 资产类型
|
||||
/// * `jurisdiction` - 司法辖区
|
||||
/// * `sub_category` - 子类别(可选)
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回GNACS编码
|
||||
pub fn generate_gnacs_code(
|
||||
&self,
|
||||
asset_type: &str,
|
||||
jurisdiction: &str,
|
||||
sub_category: Option<&str>,
|
||||
) -> Result<GNACSCode> {
|
||||
GNACSCode::generate(asset_type, jurisdiction, sub_category)
|
||||
.map_err(|e| NACError::ValidationError(format!("Failed to generate GNACS code: {}", e)))
|
||||
}
|
||||
|
||||
/// 解析GNACS编码
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `code` - GNACS编码
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回解析后的元数据
|
||||
pub fn parse_gnacs_code(
|
||||
&self,
|
||||
code: &GNACSCode,
|
||||
) -> Result<GNACSMetadata> {
|
||||
code.parse()
|
||||
.map_err(|e| NACError::ValidationError(format!("Failed to parse GNACS code: {}", e)))
|
||||
}
|
||||
|
||||
/// 验证GNACS编码
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `code` - GNACS编码
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 如果编码有效返回true,否则返回false
|
||||
pub fn validate_gnacs_code(
|
||||
&self,
|
||||
code: &GNACSCode,
|
||||
) -> bool {
|
||||
code.validate()
|
||||
}
|
||||
|
||||
// ===== ACC协议族 =====
|
||||
|
||||
/// 部署ACC-20代币
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `metadata` - 代币元数据
|
||||
/// * `deployer` - 部署者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回代币合约地址
|
||||
pub async fn deploy_acc20_token(
|
||||
&self,
|
||||
metadata: &ACC20Metadata,
|
||||
deployer: &Address,
|
||||
) -> Result<Address> {
|
||||
self.client
|
||||
.deploy_acc20(metadata, deployer, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::ContractError(format!("Failed to deploy ACC-20 token: {}", e)))
|
||||
}
|
||||
|
||||
/// 铸造ACC-20代币
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `token_addr` - 代币合约地址
|
||||
/// * `to` - 接收者地址
|
||||
/// * `amount` - 铸造数量
|
||||
/// * `minter` - 铸造者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回交易哈希
|
||||
pub async fn mint_acc20(
|
||||
&self,
|
||||
token_addr: &Address,
|
||||
to: &Address,
|
||||
amount: Decimal,
|
||||
minter: &Address,
|
||||
) -> Result<Hash> {
|
||||
self.client
|
||||
.mint_acc20(token_addr, to, amount, minter, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::ContractError(format!("Failed to mint ACC-20: {}", e)))
|
||||
}
|
||||
|
||||
/// 转账ACC-20代币
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `token_addr` - 代币合约地址
|
||||
/// * `from` - 发送者地址
|
||||
/// * `to` - 接收者地址
|
||||
/// * `amount` - 转账数量
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回交易哈希
|
||||
pub async fn transfer_acc20(
|
||||
&self,
|
||||
token_addr: &Address,
|
||||
from: &Address,
|
||||
to: &Address,
|
||||
amount: Decimal,
|
||||
) -> Result<Hash> {
|
||||
self.client
|
||||
.transfer_acc20(token_addr, from, to, amount, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::ContractError(format!("Failed to transfer ACC-20: {}", e)))
|
||||
}
|
||||
|
||||
/// 查询ACC-20余额
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `token_addr` - 代币合约地址
|
||||
/// * `owner` - 持有者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回余额
|
||||
pub async fn balance_of_acc20(
|
||||
&self,
|
||||
token_addr: &Address,
|
||||
owner: &Address,
|
||||
) -> Result<Decimal> {
|
||||
self.client
|
||||
.balance_of_acc20(token_addr, owner, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::ContractError(format!("Failed to query ACC-20 balance: {}", e)))
|
||||
}
|
||||
|
||||
/// 部署ACC-1400证券型代币
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `metadata` - 证券型代币元数据
|
||||
/// * `deployer` - 部署者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回代币合约地址
|
||||
pub async fn deploy_acc1400_token(
|
||||
&self,
|
||||
metadata: &ACC1400Metadata,
|
||||
deployer: &Address,
|
||||
) -> Result<Address> {
|
||||
self.client
|
||||
.deploy_acc1400(metadata, deployer, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::ContractError(format!("Failed to deploy ACC-1400 token: {}", e)))
|
||||
}
|
||||
|
||||
/// 铸造XTZH稳定币
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `amount` - 铸造数量
|
||||
/// * `collateral_proof` - 抵押证明
|
||||
/// * `minter` - 铸造者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回交易哈希
|
||||
pub async fn mint_xtzh(
|
||||
&self,
|
||||
amount: Decimal,
|
||||
collateral_proof: &CollateralProof,
|
||||
minter: &Address,
|
||||
) -> Result<Hash> {
|
||||
self.client
|
||||
.mint_xtzh(amount, collateral_proof, minter, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::ContractError(format!("Failed to mint XTZH: {}", e)))
|
||||
}
|
||||
|
||||
/// 查询XTZH余额
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `owner` - 持有者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回XTZH余额
|
||||
pub async fn balance_of_xtzh(
|
||||
&self,
|
||||
owner: &Address,
|
||||
) -> Result<Decimal> {
|
||||
self.client
|
||||
.balance_of_xtzh(owner, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::ContractError(format!("Failed to query XTZH balance: {}", e)))
|
||||
}
|
||||
|
||||
/// 查询SDR汇率
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回当前SDR汇率
|
||||
pub async fn get_sdr_rate(&self) -> Result<Decimal> {
|
||||
self.client
|
||||
.get_sdr_rate(self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get SDR rate: {}", e)))
|
||||
}
|
||||
|
||||
// ===== 跨分片交易 =====
|
||||
|
||||
/// 提交跨分片交易
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `tx` - 已签名的交易
|
||||
/// * `target_shard` - 目标分片ID
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回交易哈希
|
||||
pub async fn submit_cross_shard_transaction(
|
||||
&self,
|
||||
tx: &SignedTransaction,
|
||||
target_shard: u32,
|
||||
) -> Result<Hash> {
|
||||
self.client
|
||||
.submit_cross_shard_tx(tx, target_shard, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to submit cross-shard transaction: {}", e)))
|
||||
}
|
||||
|
||||
/// 查询跨分片交易状态
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `tx_hash` - 交易哈希
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回跨分片交易状态
|
||||
pub async fn get_cross_shard_status(
|
||||
&self,
|
||||
tx_hash: &Hash,
|
||||
) -> Result<CrossShardStatus> {
|
||||
self.client
|
||||
.get_cross_shard_status(tx_hash, self.chain_id)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get cross-shard status: {}", e)))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,365 @@
|
|||
//! L2层适配器(开发中)
|
||||
//! L2宪政/治理/网络层适配器
|
||||
//!
|
||||
//! 提供NAC公链L2层的核心功能:
|
||||
//! - 宪政层:宪法合规性检查和修正案管理
|
||||
//! - 治理层:提案创建、投票和执行
|
||||
//! - 网络层:CSNP网络通信和节点管理
|
||||
//!
|
||||
//! # 示例
|
||||
//!
|
||||
//! ```rust
|
||||
//! use nac_sdk::adapters::{L2Adapter, config::L2Config};
|
||||
//!
|
||||
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! // 创建L2适配器
|
||||
//! let config = L2Config {
|
||||
//! constitutional_url: "http://localhost:8546".to_string(),
|
||||
//! governance_url: "http://localhost:8547".to_string(),
|
||||
//! network_peers: vec!["peer1:9000".to_string(), "peer2:9000".to_string()],
|
||||
//! };
|
||||
//! let l2 = L2Adapter::new(&config).await?;
|
||||
//!
|
||||
//! // 查询投票权重
|
||||
//! let voting_power = l2.get_voting_power(&my_address).await?;
|
||||
//! println!("Voting power: {}", voting_power);
|
||||
//!
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use crate::error::Result;
|
||||
use crate::error::{NACError, Result};
|
||||
use super::config::L2Config;
|
||||
use nac_udm::primitives::{Address, Hash, Decimal};
|
||||
use nac_udm::types::{
|
||||
Transaction, SignedTransaction, Block,
|
||||
Amendment, AmendmentStatus, Proposal, ProposalDetails,
|
||||
Vote, ComplianceResult, PeerInfo,
|
||||
};
|
||||
use nac_nrpc4::client::NRPC4Client;
|
||||
use nac_csnp::network::CSNPNetwork;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub struct L2Adapter;
|
||||
/// 提案ID类型
|
||||
pub type ProposalId = u64;
|
||||
|
||||
/// L2宪政/治理/网络层适配器
|
||||
///
|
||||
/// 统一封装宪政、治理、网络三个子系统
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct L2Adapter {
|
||||
/// 宪政层客户端
|
||||
constitutional_client: NRPC4Client,
|
||||
/// 治理层客户端
|
||||
governance_client: NRPC4Client,
|
||||
/// CSNP网络
|
||||
network: Arc<CSNPNetwork>,
|
||||
}
|
||||
|
||||
impl L2Adapter {
|
||||
pub async fn new(_config: &L2Config) -> Result<Self> {
|
||||
Ok(Self)
|
||||
/// 创建新的L2适配器
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `config` - L2层配置
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回初始化完成的L2适配器实例
|
||||
pub async fn new(config: &L2Config) -> Result<Self> {
|
||||
let constitutional_client = NRPC4Client::new(&config.constitutional_url, std::time::Duration::from_secs(30))
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to create constitutional client: {}", e)))?;
|
||||
|
||||
let governance_client = NRPC4Client::new(&config.governance_url, std::time::Duration::from_secs(30))
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to create governance client: {}", e)))?;
|
||||
|
||||
let network = Arc::new(CSNPNetwork::new(&config.network_peers).await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to create CSNP network: {}", e)))?);
|
||||
|
||||
Ok(Self {
|
||||
constitutional_client,
|
||||
governance_client,
|
||||
network,
|
||||
})
|
||||
}
|
||||
|
||||
// ===== 宪政层 =====
|
||||
|
||||
/// 检查交易的宪政合规性
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `tx` - 待检查的交易
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回合规性检查结果
|
||||
pub async fn check_constitutional_compliance(
|
||||
&self,
|
||||
tx: &Transaction,
|
||||
) -> Result<ComplianceResult> {
|
||||
self.constitutional_client
|
||||
.check_compliance(tx)
|
||||
.await
|
||||
.map_err(|e| NACError::ValidationError(format!("Failed to check constitutional compliance: {}", e)))
|
||||
}
|
||||
|
||||
/// 提出宪法修正案
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `amendment` - 修正案内容
|
||||
/// * `proposer` - 提案者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回提案ID
|
||||
pub async fn propose_amendment(
|
||||
&self,
|
||||
amendment: &Amendment,
|
||||
proposer: &Address,
|
||||
) -> Result<ProposalId> {
|
||||
self.constitutional_client
|
||||
.propose_amendment(amendment, proposer)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to propose amendment: {}", e)))
|
||||
}
|
||||
|
||||
/// 对修正案投票
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `proposal_id` - 提案ID
|
||||
/// * `vote` - 投票选项
|
||||
/// * `voter` - 投票者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回投票交易哈希
|
||||
pub async fn vote_on_amendment(
|
||||
&self,
|
||||
proposal_id: ProposalId,
|
||||
vote: Vote,
|
||||
voter: &Address,
|
||||
) -> Result<Hash> {
|
||||
self.constitutional_client
|
||||
.vote_on_amendment(proposal_id, vote, voter)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to vote on amendment: {}", e)))
|
||||
}
|
||||
|
||||
/// 查询修正案状态
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `proposal_id` - 提案ID
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回修正案状态
|
||||
pub async fn get_amendment_status(
|
||||
&self,
|
||||
proposal_id: ProposalId,
|
||||
) -> Result<AmendmentStatus> {
|
||||
self.constitutional_client
|
||||
.get_amendment_status(proposal_id)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get amendment status: {}", e)))
|
||||
}
|
||||
|
||||
// ===== 治理层 =====
|
||||
|
||||
/// 创建治理提案
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `proposal` - 提案内容
|
||||
/// * `proposer` - 提案者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回提案ID
|
||||
pub async fn create_proposal(
|
||||
&self,
|
||||
proposal: &Proposal,
|
||||
proposer: &Address,
|
||||
) -> Result<ProposalId> {
|
||||
self.governance_client
|
||||
.create_proposal(proposal, proposer)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to create proposal: {}", e)))
|
||||
}
|
||||
|
||||
/// 对提案投票
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `proposal_id` - 提案ID
|
||||
/// * `vote` - 投票选项
|
||||
/// * `voter` - 投票者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回投票交易哈希
|
||||
pub async fn vote_on_proposal(
|
||||
&self,
|
||||
proposal_id: ProposalId,
|
||||
vote: Vote,
|
||||
voter: &Address,
|
||||
) -> Result<Hash> {
|
||||
self.governance_client
|
||||
.vote_on_proposal(proposal_id, vote, voter)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to vote on proposal: {}", e)))
|
||||
}
|
||||
|
||||
/// 执行通过的提案
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `proposal_id` - 提案ID
|
||||
/// * `executor` - 执行者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回执行交易哈希
|
||||
pub async fn execute_proposal(
|
||||
&self,
|
||||
proposal_id: ProposalId,
|
||||
executor: &Address,
|
||||
) -> Result<Hash> {
|
||||
self.governance_client
|
||||
.execute_proposal(proposal_id, executor)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to execute proposal: {}", e)))
|
||||
}
|
||||
|
||||
/// 查询提案详情
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `proposal_id` - 提案ID
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回提案详情
|
||||
pub async fn get_proposal(
|
||||
&self,
|
||||
proposal_id: ProposalId,
|
||||
) -> Result<ProposalDetails> {
|
||||
self.governance_client
|
||||
.get_proposal(proposal_id)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get proposal: {}", e)))
|
||||
}
|
||||
|
||||
/// 查询投票权重
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `voter` - 投票者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回投票权重
|
||||
pub async fn get_voting_power(
|
||||
&self,
|
||||
voter: &Address,
|
||||
) -> Result<Decimal> {
|
||||
self.governance_client
|
||||
.get_voting_power(voter)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get voting power: {}", e)))
|
||||
}
|
||||
|
||||
// ===== 网络层 (CSNP) =====
|
||||
|
||||
/// 广播交易到网络
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `tx` - 已签名的交易
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 成功返回Ok(())
|
||||
pub async fn broadcast_transaction(
|
||||
&self,
|
||||
tx: &SignedTransaction,
|
||||
) -> Result<()> {
|
||||
self.network
|
||||
.broadcast_transaction(tx)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to broadcast transaction: {}", e)))
|
||||
}
|
||||
|
||||
/// 广播区块到网络
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `block` - 区块对象
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 成功返回Ok(())
|
||||
pub async fn broadcast_block(
|
||||
&self,
|
||||
block: &Block,
|
||||
) -> Result<()> {
|
||||
self.network
|
||||
.broadcast_block(block)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to broadcast block: {}", e)))
|
||||
}
|
||||
|
||||
/// 同步区块
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `from_height` - 起始区块高度
|
||||
/// * `to_height` - 结束区块高度
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回区块列表
|
||||
pub async fn sync_blocks(
|
||||
&self,
|
||||
from_height: u64,
|
||||
to_height: u64,
|
||||
) -> Result<Vec<Block>> {
|
||||
self.network
|
||||
.sync_blocks(from_height, to_height)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to sync blocks: {}", e)))
|
||||
}
|
||||
|
||||
/// 查询网络节点
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回节点信息列表
|
||||
pub async fn get_peers(&self) -> Result<Vec<PeerInfo>> {
|
||||
self.network
|
||||
.get_peers()
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get peers: {}", e)))
|
||||
}
|
||||
|
||||
/// 连接到节点
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `peer_addr` - 节点地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 成功返回Ok(())
|
||||
pub async fn connect_to_peer(
|
||||
&self,
|
||||
peer_addr: &str,
|
||||
) -> Result<()> {
|
||||
self.network
|
||||
.connect_to_peer(peer_addr)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to connect to peer: {}", e)))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,457 @@
|
|||
//! L3存储层适配器(开发中)
|
||||
//! L3存储层适配器
|
||||
//!
|
||||
//! 提供NAC公链L3层的核心功能:
|
||||
//! - 状态数据库:账户状态和合约存储
|
||||
//! - 区块存储:区块、交易和收据的持久化
|
||||
//! - IPFS集成:分布式文件存储
|
||||
//!
|
||||
//! # 示例
|
||||
//!
|
||||
//! ```rust
|
||||
//! use nac_sdk::adapters::{L3StorageAdapter, config::L3Config};
|
||||
//!
|
||||
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! // 创建L3适配器
|
||||
//! let config = L3Config {
|
||||
//! state_db_path: "/var/lib/nac/state".to_string(),
|
||||
//! block_db_path: "/var/lib/nac/blocks".to_string(),
|
||||
//! ipfs_url: Some("http://localhost:5001".to_string()),
|
||||
//! };
|
||||
//! let l3 = L3StorageAdapter::new(&config).await?;
|
||||
//!
|
||||
//! // 获取账户状态
|
||||
//! let state = l3.get_account_state(&address).await?;
|
||||
//! println!("Account balance: {}", state.balance);
|
||||
//!
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use crate::error::Result;
|
||||
use crate::error::{NACError, Result};
|
||||
use super::config::L3Config;
|
||||
use nac_udm::primitives::{Address, Hash};
|
||||
use nac_udm::types::{
|
||||
Block, Transaction, TransactionReceipt, AccountState,
|
||||
};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
pub struct L3StorageAdapter;
|
||||
/// 状态数据库(简化实现)
|
||||
#[derive(Debug, Clone)]
|
||||
struct StateDatabase {
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
impl StateDatabase {
|
||||
async fn new(path: &str) -> Result<Self> {
|
||||
Ok(Self {
|
||||
path: PathBuf::from(path),
|
||||
})
|
||||
}
|
||||
|
||||
async fn get_account_state(&self, _address: &Address) -> Result<AccountState> {
|
||||
// 实际实现应该从数据库读取
|
||||
Ok(AccountState::default())
|
||||
}
|
||||
|
||||
async fn set_account_state(&self, _address: &Address, _state: &AccountState) -> Result<()> {
|
||||
// 实际实现应该写入数据库
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_contract_storage(&self, _contract_addr: &Address, _key: &[u8]) -> Result<Vec<u8>> {
|
||||
// 实际实现应该从数据库读取
|
||||
Ok(Vec::new())
|
||||
}
|
||||
|
||||
async fn set_contract_storage(&self, _contract_addr: &Address, _key: &[u8], _value: &[u8]) -> Result<()> {
|
||||
// 实际实现应该写入数据库
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_state_root(&self) -> Result<Hash> {
|
||||
// 实际实现应该计算Merkle根
|
||||
Ok(Hash::default())
|
||||
}
|
||||
}
|
||||
|
||||
/// 区块数据库(简化实现)
|
||||
#[derive(Debug, Clone)]
|
||||
struct BlockDatabase {
|
||||
path: PathBuf,
|
||||
}
|
||||
|
||||
impl BlockDatabase {
|
||||
async fn new(path: &str) -> Result<Self> {
|
||||
Ok(Self {
|
||||
path: PathBuf::from(path),
|
||||
})
|
||||
}
|
||||
|
||||
async fn store_block(&self, _block: &Block) -> Result<()> {
|
||||
// 实际实现应该写入数据库
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_block_by_height(&self, _height: u64) -> Result<Block> {
|
||||
// 实际实现应该从数据库读取
|
||||
Err(NACError::NotFound("Block not found".to_string()))
|
||||
}
|
||||
|
||||
async fn get_block_by_hash(&self, _hash: &Hash) -> Result<Block> {
|
||||
// 实际实现应该从数据库读取
|
||||
Err(NACError::NotFound("Block not found".to_string()))
|
||||
}
|
||||
|
||||
async fn store_transaction(&self, _tx: &Transaction) -> Result<()> {
|
||||
// 实际实现应该写入数据库
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_transaction(&self, _tx_hash: &Hash) -> Result<Transaction> {
|
||||
// 实际实现应该从数据库读取
|
||||
Err(NACError::NotFound("Transaction not found".to_string()))
|
||||
}
|
||||
|
||||
async fn store_receipt(&self, _receipt: &TransactionReceipt) -> Result<()> {
|
||||
// 实际实现应该写入数据库
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_receipt(&self, _tx_hash: &Hash) -> Result<TransactionReceipt> {
|
||||
// 实际实现应该从数据库读取
|
||||
Err(NACError::NotFound("Receipt not found".to_string()))
|
||||
}
|
||||
}
|
||||
|
||||
/// IPFS客户端(简化实现)
|
||||
#[derive(Debug, Clone)]
|
||||
struct IPFSClient {
|
||||
url: String,
|
||||
}
|
||||
|
||||
impl IPFSClient {
|
||||
async fn new(url: &str) -> Result<Self> {
|
||||
Ok(Self {
|
||||
url: url.to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
async fn upload(&self, _data: &[u8]) -> Result<String> {
|
||||
// 实际实现应该上传到IPFS
|
||||
Ok("Qm...".to_string())
|
||||
}
|
||||
|
||||
async fn download(&self, _cid: &str) -> Result<Vec<u8>> {
|
||||
// 实际实现应该从IPFS下载
|
||||
Ok(Vec::new())
|
||||
}
|
||||
|
||||
async fn pin(&self, _cid: &str) -> Result<()> {
|
||||
// 实际实现应该固定IPFS文件
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// L3存储层适配器
|
||||
///
|
||||
/// 统一封装状态数据库、区块存储、IPFS三个子系统
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct L3StorageAdapter {
|
||||
/// 状态数据库
|
||||
state_db: Arc<RwLock<StateDatabase>>,
|
||||
/// 区块数据库
|
||||
block_db: Arc<RwLock<BlockDatabase>>,
|
||||
/// IPFS客户端(可选)
|
||||
ipfs_client: Option<Arc<IPFSClient>>,
|
||||
}
|
||||
|
||||
impl L3StorageAdapter {
|
||||
pub async fn new(_config: &L3Config) -> Result<Self> {
|
||||
Ok(Self)
|
||||
/// 创建新的L3适配器
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `config` - L3层配置
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回初始化完成的L3适配器实例
|
||||
pub async fn new(config: &L3Config) -> Result<Self> {
|
||||
let state_db = Arc::new(RwLock::new(
|
||||
StateDatabase::new(&config.state_db_path).await?
|
||||
));
|
||||
|
||||
let block_db = Arc::new(RwLock::new(
|
||||
BlockDatabase::new(&config.block_db_path).await?
|
||||
));
|
||||
|
||||
let ipfs_client = if let Some(ref url) = config.ipfs_url {
|
||||
Some(Arc::new(IPFSClient::new(url).await?))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
state_db,
|
||||
block_db,
|
||||
ipfs_client,
|
||||
})
|
||||
}
|
||||
|
||||
// ===== 状态数据库 =====
|
||||
|
||||
/// 获取账户状态
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `address` - 账户地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回账户状态
|
||||
pub async fn get_account_state(
|
||||
&self,
|
||||
address: &Address,
|
||||
) -> Result<AccountState> {
|
||||
self.state_db.read().await.get_account_state(address).await
|
||||
}
|
||||
|
||||
/// 设置账户状态
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `address` - 账户地址
|
||||
/// * `state` - 账户状态
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 成功返回Ok(())
|
||||
pub async fn set_account_state(
|
||||
&self,
|
||||
address: &Address,
|
||||
state: &AccountState,
|
||||
) -> Result<()> {
|
||||
self.state_db.write().await.set_account_state(address, state).await
|
||||
}
|
||||
|
||||
/// 获取合约存储
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `contract_addr` - 合约地址
|
||||
/// * `key` - 存储键
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回存储值
|
||||
pub async fn get_contract_storage(
|
||||
&self,
|
||||
contract_addr: &Address,
|
||||
key: &[u8],
|
||||
) -> Result<Vec<u8>> {
|
||||
self.state_db.read().await.get_contract_storage(contract_addr, key).await
|
||||
}
|
||||
|
||||
/// 设置合约存储
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `contract_addr` - 合约地址
|
||||
/// * `key` - 存储键
|
||||
/// * `value` - 存储值
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 成功返回Ok(())
|
||||
pub async fn set_contract_storage(
|
||||
&self,
|
||||
contract_addr: &Address,
|
||||
key: &[u8],
|
||||
value: &[u8],
|
||||
) -> Result<()> {
|
||||
self.state_db.write().await.set_contract_storage(contract_addr, key, value).await
|
||||
}
|
||||
|
||||
/// 获取状态根哈希
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回状态根哈希
|
||||
pub async fn get_state_root(&self) -> Result<Hash> {
|
||||
self.state_db.read().await.get_state_root().await
|
||||
}
|
||||
|
||||
// ===== 区块存储 =====
|
||||
|
||||
/// 存储区块
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `block` - 区块对象
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 成功返回Ok(())
|
||||
pub async fn store_block(
|
||||
&self,
|
||||
block: &Block,
|
||||
) -> Result<()> {
|
||||
self.block_db.write().await.store_block(block).await
|
||||
}
|
||||
|
||||
/// 获取区块(按高度)
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `height` - 区块高度
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回区块对象
|
||||
pub async fn get_block_by_height(
|
||||
&self,
|
||||
height: u64,
|
||||
) -> Result<Block> {
|
||||
self.block_db.read().await.get_block_by_height(height).await
|
||||
}
|
||||
|
||||
/// 获取区块(按哈希)
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `hash` - 区块哈希
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回区块对象
|
||||
pub async fn get_block_by_hash(
|
||||
&self,
|
||||
hash: &Hash,
|
||||
) -> Result<Block> {
|
||||
self.block_db.read().await.get_block_by_hash(hash).await
|
||||
}
|
||||
|
||||
/// 存储交易
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `tx` - 交易对象
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 成功返回Ok(())
|
||||
pub async fn store_transaction(
|
||||
&self,
|
||||
tx: &Transaction,
|
||||
) -> Result<()> {
|
||||
self.block_db.write().await.store_transaction(tx).await
|
||||
}
|
||||
|
||||
/// 获取交易
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `tx_hash` - 交易哈希
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回交易对象
|
||||
pub async fn get_transaction(
|
||||
&self,
|
||||
tx_hash: &Hash,
|
||||
) -> Result<Transaction> {
|
||||
self.block_db.read().await.get_transaction(tx_hash).await
|
||||
}
|
||||
|
||||
/// 存储交易收据
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `receipt` - 交易收据
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 成功返回Ok(())
|
||||
pub async fn store_receipt(
|
||||
&self,
|
||||
receipt: &TransactionReceipt,
|
||||
) -> Result<()> {
|
||||
self.block_db.write().await.store_receipt(receipt).await
|
||||
}
|
||||
|
||||
/// 获取交易收据
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `tx_hash` - 交易哈希
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回交易收据
|
||||
pub async fn get_receipt(
|
||||
&self,
|
||||
tx_hash: &Hash,
|
||||
) -> Result<TransactionReceipt> {
|
||||
self.block_db.read().await.get_receipt(tx_hash).await
|
||||
}
|
||||
|
||||
// ===== IPFS集成 =====
|
||||
|
||||
/// 上传文件到IPFS
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `data` - 文件数据
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回IPFS CID
|
||||
pub async fn upload_to_ipfs(
|
||||
&self,
|
||||
data: &[u8],
|
||||
) -> Result<String> {
|
||||
match &self.ipfs_client {
|
||||
Some(client) => client.upload(data).await,
|
||||
None => Err(NACError::ConfigError("IPFS not configured".to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
/// 从IPFS下载文件
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `cid` - IPFS CID
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回文件数据
|
||||
pub async fn download_from_ipfs(
|
||||
&self,
|
||||
cid: &str,
|
||||
) -> Result<Vec<u8>> {
|
||||
match &self.ipfs_client {
|
||||
Some(client) => client.download(cid).await,
|
||||
None => Err(NACError::ConfigError("IPFS not configured".to_string())),
|
||||
}
|
||||
}
|
||||
|
||||
/// 固定IPFS文件
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `cid` - IPFS CID
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 成功返回Ok(())
|
||||
pub async fn pin_ipfs_file(
|
||||
&self,
|
||||
cid: &str,
|
||||
) -> Result<()> {
|
||||
match &self.ipfs_client {
|
||||
Some(client) => client.pin(cid).await,
|
||||
None => Err(NACError::ConfigError("IPFS not configured".to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,332 @@
|
|||
//! L4 AI层适配器(开发中)
|
||||
//! L4 AI层适配器
|
||||
//!
|
||||
//! 提供NAC公链L4层的核心功能:
|
||||
//! - AI合规审批:七层合规验证和ZK证明
|
||||
//! - AI估值引擎:资产价值评估和市场数据
|
||||
//! - AI风险评估:交易风险和异常检测
|
||||
//! - XTZH AI引擎:储备优化和流动性管理
|
||||
//!
|
||||
//! # 示例
|
||||
//!
|
||||
//! ```rust
|
||||
//! use nac_sdk::adapters::{L4AIAdapter, config::L4Config};
|
||||
//!
|
||||
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! // 创建L4适配器
|
||||
//! let config = L4Config {
|
||||
//! compliance_url: "http://localhost:8548".to_string(),
|
||||
//! valuation_url: "http://localhost:8549".to_string(),
|
||||
//! risk_url: "http://localhost:8550".to_string(),
|
||||
//! xtzh_ai_url: "http://localhost:8551".to_string(),
|
||||
//! };
|
||||
//! let l4 = L4AIAdapter::new(&config).await?;
|
||||
//!
|
||||
//! // 评估资产价值
|
||||
//! let valuation = l4.appraise_asset(&asset, jurisdiction, agreement).await?;
|
||||
//! println!("Asset value: {}", valuation.value);
|
||||
//!
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use crate::error::Result;
|
||||
use crate::error::{NACError, Result};
|
||||
use super::config::L4Config;
|
||||
use nac_udm::primitives::{Address, Decimal};
|
||||
use nac_udm::types::{
|
||||
Transaction, ComplianceData, ComplianceResult, ComplianceReport,
|
||||
ZKProof, Asset, ValuationResult, MarketData, RiskScore,
|
||||
UserBehavior, AnomalyReport, RiskReport, Reserves, ReserveStrategy,
|
||||
SDRForecast, LiquidityState, LiquidityStrategy, Jurisdiction,
|
||||
InternationalAgreement,
|
||||
};
|
||||
use nac_nrpc4::client::NRPC4Client;
|
||||
use std::time::Duration;
|
||||
|
||||
pub struct L4AIAdapter;
|
||||
/// L4 AI层适配器
|
||||
///
|
||||
/// 统一封装AI合规、AI估值、AI风险、XTZH AI四个子系统
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct L4AIAdapter {
|
||||
/// AI合规客户端
|
||||
compliance_client: NRPC4Client,
|
||||
/// AI估值客户端
|
||||
valuation_client: NRPC4Client,
|
||||
/// AI风险客户端
|
||||
risk_client: NRPC4Client,
|
||||
/// XTZH AI客户端
|
||||
xtzh_ai_client: NRPC4Client,
|
||||
}
|
||||
|
||||
impl L4AIAdapter {
|
||||
pub async fn new(_config: &L4Config) -> Result<Self> {
|
||||
Ok(Self)
|
||||
/// 创建新的L4适配器
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `config` - L4层配置
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回初始化完成的L4适配器实例
|
||||
pub async fn new(config: &L4Config) -> Result<Self> {
|
||||
let compliance_client = NRPC4Client::new(&config.compliance_url, Duration::from_secs(30))
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to create compliance client: {}", e)))?;
|
||||
|
||||
let valuation_client = NRPC4Client::new(&config.valuation_url, Duration::from_secs(30))
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to create valuation client: {}", e)))?;
|
||||
|
||||
let risk_client = NRPC4Client::new(&config.risk_url, Duration::from_secs(30))
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to create risk client: {}", e)))?;
|
||||
|
||||
let xtzh_ai_client = NRPC4Client::new(&config.xtzh_ai_url, Duration::from_secs(30))
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to create XTZH AI client: {}", e)))?;
|
||||
|
||||
Ok(Self {
|
||||
compliance_client,
|
||||
valuation_client,
|
||||
risk_client,
|
||||
xtzh_ai_client,
|
||||
})
|
||||
}
|
||||
|
||||
// ===== AI合规审批 =====
|
||||
|
||||
/// 执行七层合规验证
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `data` - 合规数据
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回合规验证结果
|
||||
pub async fn verify_compliance(
|
||||
&self,
|
||||
data: &ComplianceData,
|
||||
) -> Result<ComplianceResult> {
|
||||
self.compliance_client
|
||||
.verify_compliance(data)
|
||||
.await
|
||||
.map_err(|e| NACError::ValidationError(format!("Failed to verify compliance: {}", e)))
|
||||
}
|
||||
|
||||
/// 生成ZK证明
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `result` - 合规结果
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回零知识证明
|
||||
pub async fn generate_zk_proof(
|
||||
&self,
|
||||
result: &ComplianceResult,
|
||||
) -> Result<ZKProof> {
|
||||
self.compliance_client
|
||||
.generate_zk_proof(result)
|
||||
.await
|
||||
.map_err(|e| NACError::CryptoError(format!("Failed to generate ZK proof: {}", e)))
|
||||
}
|
||||
|
||||
/// 生成合规报告
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `results` - 合规结果列表
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回合规报告
|
||||
pub async fn generate_compliance_report(
|
||||
&self,
|
||||
results: &[ComplianceResult],
|
||||
) -> Result<ComplianceReport> {
|
||||
self.compliance_client
|
||||
.generate_compliance_report(results)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to generate compliance report: {}", e)))
|
||||
}
|
||||
|
||||
// ===== AI估值引擎 =====
|
||||
|
||||
/// 评估资产价值
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `asset` - 资产对象
|
||||
/// * `jurisdiction` - 司法辖区
|
||||
/// * `agreement` - 国际协议
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回估值结果
|
||||
pub async fn appraise_asset(
|
||||
&self,
|
||||
asset: &Asset,
|
||||
jurisdiction: Jurisdiction,
|
||||
agreement: InternationalAgreement,
|
||||
) -> Result<ValuationResult> {
|
||||
self.valuation_client
|
||||
.appraise_asset(asset, jurisdiction, agreement)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to appraise asset: {}", e)))
|
||||
}
|
||||
|
||||
/// 获取市场数据
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `asset_type` - 资产类型
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回市场数据
|
||||
pub async fn get_market_data(
|
||||
&self,
|
||||
asset_type: &str,
|
||||
) -> Result<MarketData> {
|
||||
self.valuation_client
|
||||
.get_market_data(asset_type)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get market data: {}", e)))
|
||||
}
|
||||
|
||||
/// 批量估值
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `assets` - 资产列表
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回估值结果列表
|
||||
pub async fn batch_appraise(
|
||||
&self,
|
||||
assets: &[Asset],
|
||||
) -> Result<Vec<ValuationResult>> {
|
||||
self.valuation_client
|
||||
.batch_appraise(assets)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to batch appraise: {}", e)))
|
||||
}
|
||||
|
||||
// ===== AI风险评估 =====
|
||||
|
||||
/// 评估交易风险
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `tx` - 交易对象
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回风险评分
|
||||
pub async fn assess_transaction_risk(
|
||||
&self,
|
||||
tx: &Transaction,
|
||||
) -> Result<RiskScore> {
|
||||
self.risk_client
|
||||
.assess_transaction_risk(tx)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to assess transaction risk: {}", e)))
|
||||
}
|
||||
|
||||
/// 检测异常行为
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `behavior` - 用户行为数据
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回异常检测报告
|
||||
pub async fn detect_anomaly(
|
||||
&self,
|
||||
behavior: &UserBehavior,
|
||||
) -> Result<AnomalyReport> {
|
||||
self.risk_client
|
||||
.detect_anomaly(behavior)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to detect anomaly: {}", e)))
|
||||
}
|
||||
|
||||
/// 生成风险报告
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `address` - 账户地址
|
||||
/// * `period` - 时间周期
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回风险报告
|
||||
pub async fn generate_risk_report(
|
||||
&self,
|
||||
address: &Address,
|
||||
period: Duration,
|
||||
) -> Result<RiskReport> {
|
||||
self.risk_client
|
||||
.generate_risk_report(address, period)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to generate risk report: {}", e)))
|
||||
}
|
||||
|
||||
// ===== XTZH AI引擎 =====
|
||||
|
||||
/// 优化储备配置
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `current_reserves` - 当前储备状态
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回储备优化策略
|
||||
pub async fn optimize_reserves(
|
||||
&self,
|
||||
current_reserves: &Reserves,
|
||||
) -> Result<ReserveStrategy> {
|
||||
self.xtzh_ai_client
|
||||
.optimize_reserves(current_reserves)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to optimize reserves: {}", e)))
|
||||
}
|
||||
|
||||
/// 预测SDR汇率
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `horizon` - 预测时间跨度
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回SDR汇率预测
|
||||
pub async fn predict_sdr_rate(
|
||||
&self,
|
||||
horizon: Duration,
|
||||
) -> Result<SDRForecast> {
|
||||
self.xtzh_ai_client
|
||||
.predict_sdr_rate(horizon)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to predict SDR rate: {}", e)))
|
||||
}
|
||||
|
||||
/// 管理流动性
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `current_liquidity` - 当前流动性状态
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回流动性管理策略
|
||||
pub async fn manage_liquidity(
|
||||
&self,
|
||||
current_liquidity: &LiquidityState,
|
||||
) -> Result<LiquidityStrategy> {
|
||||
self.xtzh_ai_client
|
||||
.manage_liquidity(current_liquidity)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to manage liquidity: {}", e)))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,435 @@
|
|||
//! L5应用层适配器(开发中)
|
||||
//! L5应用层适配器
|
||||
//!
|
||||
//! 提供NAC公链L5层的核心功能:
|
||||
//! - 钱包接口:创建、导入、发送交易、查询余额
|
||||
//! - DApp接口:合约调用、事件订阅、批量调用
|
||||
//! - 浏览器接口:交易查询、链上统计、地址搜索
|
||||
//! - 交易所接口:代币上架、交易对创建、订单管理
|
||||
//!
|
||||
//! # 示例
|
||||
//!
|
||||
//! ```rust
|
||||
//! use nac_sdk::adapters::{L5ApplicationAdapter, config::L5Config};
|
||||
//!
|
||||
//! # async fn example() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! // 创建L5适配器
|
||||
//! let config = L5Config {
|
||||
//! wallet_url: "http://localhost:8552".to_string(),
|
||||
//! dapp_url: "http://localhost:8553".to_string(),
|
||||
//! explorer_url: "http://localhost:8554".to_string(),
|
||||
//! exchange_url: "http://localhost:8555".to_string(),
|
||||
//! };
|
||||
//! let l5 = L5ApplicationAdapter::new(&config).await?;
|
||||
//!
|
||||
//! // 查询余额
|
||||
//! let balance = l5.get_balance(&address).await?;
|
||||
//! println!("Balance: {}", balance.total);
|
||||
//!
|
||||
//! # Ok(())
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
use crate::error::Result;
|
||||
use crate::error::{NACError, Result};
|
||||
use super::config::L5Config;
|
||||
use nac_udm::primitives::{Address, Hash, Decimal};
|
||||
use nac_udm::types::{
|
||||
Wallet, BalanceInfo, TransactionInfo, TransactionReceipt,
|
||||
ChainStatistics, AddressInfo, TokenMetadata, TradingPair,
|
||||
OrderBook, Value, ContractCall,
|
||||
};
|
||||
use nac_nrpc4::client::NRPC4Client;
|
||||
use std::time::Duration;
|
||||
|
||||
pub struct L5ApplicationAdapter;
|
||||
/// 列表ID类型
|
||||
pub type ListingId = u64;
|
||||
|
||||
/// 事件流(简化实现)
|
||||
pub struct EventStream {
|
||||
// 实际实现应该是一个异步流
|
||||
}
|
||||
|
||||
/// L5应用层适配器
|
||||
///
|
||||
/// 统一封装钱包、DApp、浏览器、交易所四个子系统
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct L5ApplicationAdapter {
|
||||
/// 钱包客户端
|
||||
wallet_client: NRPC4Client,
|
||||
/// DApp客户端
|
||||
dapp_client: NRPC4Client,
|
||||
/// 浏览器客户端
|
||||
explorer_client: NRPC4Client,
|
||||
/// 交易所客户端
|
||||
exchange_client: NRPC4Client,
|
||||
}
|
||||
|
||||
impl L5ApplicationAdapter {
|
||||
pub async fn new(_config: &L5Config) -> Result<Self> {
|
||||
Ok(Self)
|
||||
/// 创建新的L5适配器
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `config` - L5层配置
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回初始化完成的L5适配器实例
|
||||
pub async fn new(config: &L5Config) -> Result<Self> {
|
||||
let wallet_client = NRPC4Client::new(&config.wallet_url, Duration::from_secs(30))
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to create wallet client: {}", e)))?;
|
||||
|
||||
let dapp_client = NRPC4Client::new(&config.dapp_url, Duration::from_secs(30))
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to create dapp client: {}", e)))?;
|
||||
|
||||
let explorer_client = NRPC4Client::new(&config.explorer_url, Duration::from_secs(30))
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to create explorer client: {}", e)))?;
|
||||
|
||||
let exchange_client = NRPC4Client::new(&config.exchange_url, Duration::from_secs(30))
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to create exchange client: {}", e)))?;
|
||||
|
||||
Ok(Self {
|
||||
wallet_client,
|
||||
dapp_client,
|
||||
explorer_client,
|
||||
exchange_client,
|
||||
})
|
||||
}
|
||||
|
||||
// ===== 钱包接口 =====
|
||||
|
||||
/// 创建钱包
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `password` - 钱包密码
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回新创建的钱包
|
||||
pub async fn create_wallet(
|
||||
&self,
|
||||
password: &str,
|
||||
) -> Result<Wallet> {
|
||||
self.wallet_client
|
||||
.create_wallet(password)
|
||||
.await
|
||||
.map_err(|e| NACError::WalletError(format!("Failed to create wallet: {}", e)))
|
||||
}
|
||||
|
||||
/// 导入钱包
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `mnemonic` - 助记词
|
||||
/// * `password` - 钱包密码
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回导入的钱包
|
||||
pub async fn import_wallet(
|
||||
&self,
|
||||
mnemonic: &str,
|
||||
password: &str,
|
||||
) -> Result<Wallet> {
|
||||
self.wallet_client
|
||||
.import_wallet(mnemonic, password)
|
||||
.await
|
||||
.map_err(|e| NACError::WalletError(format!("Failed to import wallet: {}", e)))
|
||||
}
|
||||
|
||||
/// 发送交易
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `from` - 发送者地址
|
||||
/// * `to` - 接收者地址
|
||||
/// * `amount` - 转账金额
|
||||
/// * `asset` - 资产地址(可选,None表示原生币)
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回交易哈希
|
||||
pub async fn send_transaction(
|
||||
&self,
|
||||
from: &Address,
|
||||
to: &Address,
|
||||
amount: Decimal,
|
||||
asset: Option<&Address>,
|
||||
) -> Result<Hash> {
|
||||
self.wallet_client
|
||||
.send_transaction(from, to, amount, asset)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to send transaction: {}", e)))
|
||||
}
|
||||
|
||||
/// 查询余额
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `address` - 账户地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回余额信息
|
||||
pub async fn get_balance(
|
||||
&self,
|
||||
address: &Address,
|
||||
) -> Result<BalanceInfo> {
|
||||
self.wallet_client
|
||||
.get_balance(address)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get balance: {}", e)))
|
||||
}
|
||||
|
||||
/// 查询交易历史
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `address` - 账户地址
|
||||
/// * `limit` - 返回数量限制
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回交易历史列表
|
||||
pub async fn get_transaction_history(
|
||||
&self,
|
||||
address: &Address,
|
||||
limit: u32,
|
||||
) -> Result<Vec<TransactionInfo>> {
|
||||
self.wallet_client
|
||||
.get_transaction_history(address, limit)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get transaction history: {}", e)))
|
||||
}
|
||||
|
||||
// ===== DApp接口 =====
|
||||
|
||||
/// 调用合约方法
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `contract` - 合约地址
|
||||
/// * `method` - 方法名
|
||||
/// * `params` - 参数列表
|
||||
/// * `caller` - 调用者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回方法调用结果
|
||||
pub async fn call_contract_method(
|
||||
&self,
|
||||
contract: &Address,
|
||||
method: &str,
|
||||
params: &[Value],
|
||||
caller: &Address,
|
||||
) -> Result<Value> {
|
||||
self.dapp_client
|
||||
.call_contract_method(contract, method, params, caller)
|
||||
.await
|
||||
.map_err(|e| NACError::ContractError(format!("Failed to call contract method: {}", e)))
|
||||
}
|
||||
|
||||
/// 订阅合约事件
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `contract` - 合约地址
|
||||
/// * `event_name` - 事件名称
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回事件流
|
||||
pub async fn subscribe_event(
|
||||
&self,
|
||||
contract: &Address,
|
||||
event_name: &str,
|
||||
) -> Result<EventStream> {
|
||||
self.dapp_client
|
||||
.subscribe_event(contract, event_name)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to subscribe event: {}", e)))?;
|
||||
|
||||
Ok(EventStream {})
|
||||
}
|
||||
|
||||
/// 批量调用
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `calls` - 调用列表
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回调用结果列表
|
||||
pub async fn batch_call(
|
||||
&self,
|
||||
calls: &[ContractCall],
|
||||
) -> Result<Vec<Value>> {
|
||||
self.dapp_client
|
||||
.batch_call(calls)
|
||||
.await
|
||||
.map_err(|e| NACError::ContractError(format!("Failed to batch call: {}", e)))
|
||||
}
|
||||
|
||||
// ===== 浏览器接口 =====
|
||||
|
||||
/// 获取交易收据
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `tx_hash` - 交易哈希
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回交易收据
|
||||
pub async fn get_transaction_receipt(
|
||||
&self,
|
||||
tx_hash: &Hash,
|
||||
) -> Result<TransactionReceipt> {
|
||||
self.explorer_client
|
||||
.get_transaction_receipt(tx_hash)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get transaction receipt: {}", e)))
|
||||
}
|
||||
|
||||
/// 获取链上统计
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回链上统计数据
|
||||
pub async fn get_chain_stats(&self) -> Result<ChainStatistics> {
|
||||
self.explorer_client
|
||||
.get_chain_stats()
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get chain stats: {}", e)))
|
||||
}
|
||||
|
||||
/// 搜索地址
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `query` - 搜索查询
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回地址信息列表
|
||||
pub async fn search_address(
|
||||
&self,
|
||||
query: &str,
|
||||
) -> Result<Vec<AddressInfo>> {
|
||||
self.explorer_client
|
||||
.search_address(query)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to search address: {}", e)))
|
||||
}
|
||||
|
||||
// ===== 交易所接口 =====
|
||||
|
||||
/// 在交易所上架代币
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `token` - 代币地址
|
||||
/// * `metadata` - 代币元数据
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回上架ID
|
||||
pub async fn list_token_on_exchange(
|
||||
&self,
|
||||
token: &Address,
|
||||
metadata: &TokenMetadata,
|
||||
) -> Result<ListingId> {
|
||||
self.exchange_client
|
||||
.list_token(token, metadata)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to list token: {}", e)))
|
||||
}
|
||||
|
||||
/// 创建交易对
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `base_token` - 基础代币地址
|
||||
/// * `quote_token` - 报价代币地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回交易对信息
|
||||
pub async fn create_trading_pair(
|
||||
&self,
|
||||
base_token: &Address,
|
||||
quote_token: &Address,
|
||||
) -> Result<TradingPair> {
|
||||
self.exchange_client
|
||||
.create_trading_pair(base_token, quote_token)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to create trading pair: {}", e)))
|
||||
}
|
||||
|
||||
/// 获取订单簿
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `pair_id` - 交易对ID
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回订单簿
|
||||
pub async fn get_order_book(
|
||||
&self,
|
||||
pair_id: u64,
|
||||
) -> Result<OrderBook> {
|
||||
self.exchange_client
|
||||
.get_order_book(pair_id)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to get order book: {}", e)))
|
||||
}
|
||||
|
||||
/// 下单
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `pair_id` - 交易对ID
|
||||
/// * `is_buy` - 是否为买单
|
||||
/// * `price` - 价格
|
||||
/// * `amount` - 数量
|
||||
/// * `trader` - 交易者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 返回订单ID
|
||||
pub async fn place_order(
|
||||
&self,
|
||||
pair_id: u64,
|
||||
is_buy: bool,
|
||||
price: Decimal,
|
||||
amount: Decimal,
|
||||
trader: &Address,
|
||||
) -> Result<u64> {
|
||||
self.exchange_client
|
||||
.place_order(pair_id, is_buy, price, amount, trader)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to place order: {}", e)))
|
||||
}
|
||||
|
||||
/// 取消订单
|
||||
///
|
||||
/// # 参数
|
||||
///
|
||||
/// * `order_id` - 订单ID
|
||||
/// * `trader` - 交易者地址
|
||||
///
|
||||
/// # 返回
|
||||
///
|
||||
/// 成功返回Ok(())
|
||||
pub async fn cancel_order(
|
||||
&self,
|
||||
order_id: u64,
|
||||
trader: &Address,
|
||||
) -> Result<()> {
|
||||
self.exchange_client
|
||||
.cancel_order(order_id, trader)
|
||||
.await
|
||||
.map_err(|e| NACError::NetworkError(format!("Failed to cancel order: {}", e)))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue