NAC_Blockchain/nac-sdk/src/adapters/l5_application.rs

436 lines
11 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! 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::{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;
/// 列表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 {
/// 创建新的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)))
}
}