652 lines
22 KiB
Rust
652 lines
22 KiB
Rust
//! ACC-1155: 多代币证书协议接口
|
||
//!
|
||
//! 提供与NAC区块链上ACC-1155证书交互的客户端接口
|
||
|
||
// NRPC3Client 已更名为 NAC Lens 客户端
|
||
use crate::error::{NACError, Result};
|
||
use crate::adapters::NRPC3Client;
|
||
use nac_udm::primitives::{Address, Hash, Timestamp};
|
||
use nac_udm::l1_protocol::gnacs::GNACSCode;
|
||
use nac_udm::l1_protocol::acc::acc1155::{
|
||
TokenId, TokenType, TokenTypeDNA, TokenTypeMetadata,
|
||
BatchTransfer, BatchMint, BatchBurn, TokenCustodyInfo, TokenInsuranceInfo,
|
||
TokenTypeValuation,
|
||
};
|
||
use nac_udm::l2_governance::sovereignty::SovereigntyRight;
|
||
use serde_json::json;
|
||
|
||
/// ACC-1155多代币证书接口
|
||
pub struct ACC1155 {
|
||
client: NRPC3Client,
|
||
}
|
||
|
||
impl ACC1155 {
|
||
/// 创建新的ACC-1155接口实例
|
||
pub fn new(client: NRPC3Client) -> Self {
|
||
Self { client }
|
||
}
|
||
|
||
/// 获取代币余额
|
||
///
|
||
/// # 参数
|
||
/// * `certificate_address` - 证书地址
|
||
/// * `holder` - 持有者地址
|
||
/// * `token_id` - 代币类型ID
|
||
///
|
||
/// # 返回
|
||
/// 代币余额
|
||
pub async fn balance_of(
|
||
&self,
|
||
certificate_address: &Address,
|
||
holder: &Address,
|
||
token_id: TokenId,
|
||
) -> Result<u128> {
|
||
let params = json!({
|
||
"certificate_address": certificate_address,
|
||
"holder": holder,
|
||
"token_id": token_id,
|
||
});
|
||
|
||
let response = self.client.call("acc1155_balanceOf", params).await?;
|
||
|
||
let balance = response["result"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing balance".to_string()))?
|
||
.parse()
|
||
.map_err(|e| NACError::InvalidResponse(format!("Invalid balance: {}", e)))?;
|
||
|
||
Ok(balance)
|
||
}
|
||
|
||
/// 批量获取代币余额
|
||
///
|
||
/// # 参数
|
||
/// * `certificate_address` - 证书地址
|
||
/// * `holders` - 持有者地址列表
|
||
/// * `token_ids` - 代币类型ID列表
|
||
///
|
||
/// # 返回
|
||
/// 代币余额列表
|
||
pub async fn balance_of_batch(
|
||
&self,
|
||
certificate_address: &Address,
|
||
holders: Vec<Address>,
|
||
token_ids: Vec<TokenId>,
|
||
) -> Result<Vec<u128>> {
|
||
let params = json!({
|
||
"certificate_address": certificate_address,
|
||
"holders": holders,
|
||
"token_ids": token_ids,
|
||
});
|
||
|
||
let response = self.client.call("acc1155_balanceOfBatch", params).await?;
|
||
|
||
let balances: Vec<u128> = response["result"]
|
||
.as_array()
|
||
.ok_or(NACError::InvalidResponse("Missing balances array".to_string()))?
|
||
.iter()
|
||
.map(|v| {
|
||
v.as_str()
|
||
.ok_or(NACError::InvalidResponse("Invalid balance".to_string()))?
|
||
.parse()
|
||
.map_err(|e| NACError::InvalidResponse(format!("Invalid balance: {}", e)))
|
||
})
|
||
.collect::<Result<Vec<u128>>>()?;
|
||
|
||
Ok(balances)
|
||
}
|
||
|
||
/// 创建新的代币类型
|
||
///
|
||
/// # 参数
|
||
/// * `certificate_address` - 证书地址
|
||
/// * `token_id` - 代币类型ID
|
||
/// * `token_type` - 代币类型(可替代性)
|
||
/// * `gnacs_code` - GNACS编码
|
||
/// * `sovereignty_type` - 主权类型
|
||
/// * `metadata` - 代币元数据
|
||
/// * `max_supply` - 最大供应量(None表示无限制)
|
||
///
|
||
/// # 返回
|
||
/// 代币类型DNA
|
||
pub async fn create_token_type(
|
||
&self,
|
||
certificate_address: &Address,
|
||
token_id: TokenId,
|
||
token_type: TokenType,
|
||
gnacs_code: GNACSCode,
|
||
sovereignty_type: SovereigntyRight,
|
||
metadata: TokenTypeMetadata,
|
||
max_supply: Option<u128>,
|
||
) -> Result<TokenTypeDNA> {
|
||
let params = json!({
|
||
"certificate_address": certificate_address,
|
||
"token_id": token_id,
|
||
"token_type": token_type,
|
||
"gnacs_code": gnacs_code,
|
||
"sovereignty_type": sovereignty_type,
|
||
"metadata": {
|
||
"name": metadata.name,
|
||
"symbol": metadata.symbol,
|
||
"uri": metadata.uri,
|
||
},
|
||
"max_supply": max_supply,
|
||
});
|
||
|
||
let response = self.client.call("acc1155_createTokenType", params).await?;
|
||
|
||
// 解析TokenTypeDNA
|
||
let dna_data = &response["result"];
|
||
let token_dna = TokenTypeDNA {
|
||
dna_hash: Hash::from_hex(
|
||
dna_data["dna_hash"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing dna_hash".to_string()))?
|
||
).map_err(|e| NACError::InvalidHash(format!("Invalid dna_hash: {}", e)))?,
|
||
token_id,
|
||
gnacs_code,
|
||
token_type,
|
||
sovereignty_type,
|
||
metadata_hash: Hash::from_hex(
|
||
dna_data["metadata_hash"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing metadata_hash".to_string()))?
|
||
).map_err(|e| NACError::InvalidHash(format!("Invalid metadata_hash: {}", e)))?,
|
||
generated_at: Timestamp::from_secs(
|
||
dna_data["generated_at"]
|
||
.as_u64()
|
||
.ok_or(NACError::InvalidResponse("Missing generated_at".to_string()))?
|
||
),
|
||
};
|
||
|
||
Ok(token_dna)
|
||
}
|
||
|
||
/// 批量铸造代币
|
||
///
|
||
/// # 参数
|
||
/// * `certificate_address` - 证书地址
|
||
/// * `to` - 接收者地址
|
||
/// * `token_ids` - 代币类型ID列表
|
||
/// * `amounts` - 数量列表
|
||
///
|
||
/// # 返回
|
||
/// 批量铸造记录
|
||
pub async fn mint_batch(
|
||
&self,
|
||
certificate_address: &Address,
|
||
to: &Address,
|
||
token_ids: Vec<TokenId>,
|
||
amounts: Vec<u128>,
|
||
) -> Result<BatchMint> {
|
||
let params = json!({
|
||
"certificate_address": certificate_address,
|
||
"to": to,
|
||
"token_ids": token_ids,
|
||
"amounts": amounts.iter().map(|a| a.to_string()).collect::<Vec<_>>(),
|
||
});
|
||
|
||
let response = self.client.call("acc1155_mintBatch", params).await?;
|
||
|
||
let mint_data = &response["result"];
|
||
let batch_mint = BatchMint {
|
||
to: *to,
|
||
token_ids,
|
||
amounts,
|
||
minted_at: Timestamp::from_secs(
|
||
mint_data["minted_at"]
|
||
.as_u64()
|
||
.ok_or(NACError::InvalidResponse("Missing minted_at".to_string()))?
|
||
),
|
||
constitutional_receipt: Hash::from_hex(
|
||
mint_data["constitutional_receipt"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing constitutional_receipt".to_string()))?
|
||
).map_err(|e| NACError::InvalidHash(format!("Invalid receipt hash: {}", e)))?,
|
||
};
|
||
|
||
Ok(batch_mint)
|
||
}
|
||
|
||
/// 批量转移代币
|
||
///
|
||
/// # 参数
|
||
/// * `certificate_address` - 证书地址
|
||
/// * `from` - 发送者地址
|
||
/// * `to` - 接收者地址
|
||
/// * `token_ids` - 代币类型ID列表
|
||
/// * `amounts` - 数量列表
|
||
///
|
||
/// # 返回
|
||
/// 批量转移记录
|
||
pub async fn safe_transfer_batch(
|
||
&self,
|
||
certificate_address: &Address,
|
||
from: &Address,
|
||
to: &Address,
|
||
token_ids: Vec<TokenId>,
|
||
amounts: Vec<u128>,
|
||
) -> Result<BatchTransfer> {
|
||
let params = json!({
|
||
"certificate_address": certificate_address,
|
||
"from": from,
|
||
"to": to,
|
||
"token_ids": token_ids,
|
||
"amounts": amounts.iter().map(|a| a.to_string()).collect::<Vec<_>>(),
|
||
});
|
||
|
||
let response = self.client.call("acc1155_safeTransferBatch", params).await?;
|
||
|
||
let transfer_data = &response["result"];
|
||
let batch_transfer = BatchTransfer {
|
||
from: *from,
|
||
to: *to,
|
||
token_ids,
|
||
amounts,
|
||
transferred_at: Timestamp::from_secs(
|
||
transfer_data["transferred_at"]
|
||
.as_u64()
|
||
.ok_or(NACError::InvalidResponse("Missing transferred_at".to_string()))?
|
||
),
|
||
constitutional_receipt: Hash::from_hex(
|
||
transfer_data["constitutional_receipt"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing constitutional_receipt".to_string()))?
|
||
).map_err(|e| NACError::InvalidHash(format!("Invalid receipt hash: {}", e)))?,
|
||
};
|
||
|
||
Ok(batch_transfer)
|
||
}
|
||
|
||
/// 批量销毁代币
|
||
///
|
||
/// # 参数
|
||
/// * `certificate_address` - 证书地址
|
||
/// * `from` - 持有者地址
|
||
/// * `token_ids` - 代币类型ID列表
|
||
/// * `amounts` - 数量列表
|
||
///
|
||
/// # 返回
|
||
/// 批量销毁记录
|
||
pub async fn burn_batch(
|
||
&self,
|
||
certificate_address: &Address,
|
||
from: &Address,
|
||
token_ids: Vec<TokenId>,
|
||
amounts: Vec<u128>,
|
||
) -> Result<BatchBurn> {
|
||
let params = json!({
|
||
"certificate_address": certificate_address,
|
||
"from": from,
|
||
"token_ids": token_ids,
|
||
"amounts": amounts.iter().map(|a| a.to_string()).collect::<Vec<_>>(),
|
||
});
|
||
|
||
let response = self.client.call("acc1155_burnBatch", params).await?;
|
||
|
||
let burn_data = &response["result"];
|
||
let batch_burn = BatchBurn {
|
||
from: *from,
|
||
token_ids,
|
||
amounts,
|
||
burned_at: Timestamp::from_secs(
|
||
burn_data["burned_at"]
|
||
.as_u64()
|
||
.ok_or(NACError::InvalidResponse("Missing burned_at".to_string()))?
|
||
),
|
||
constitutional_receipt: Hash::from_hex(
|
||
burn_data["constitutional_receipt"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing constitutional_receipt".to_string()))?
|
||
).map_err(|e| NACError::InvalidHash(format!("Invalid receipt hash: {}", e)))?,
|
||
};
|
||
|
||
Ok(batch_burn)
|
||
}
|
||
|
||
/// 设置授权
|
||
///
|
||
/// # 参数
|
||
/// * `certificate_address` - 证书地址
|
||
/// * `owner` - 所有者地址
|
||
/// * `operator` - 操作者地址
|
||
/// * `approved` - 是否授权
|
||
pub async fn set_approval_for_all(
|
||
&self,
|
||
certificate_address: &Address,
|
||
owner: &Address,
|
||
operator: &Address,
|
||
approved: bool,
|
||
) -> Result<()> {
|
||
let params = json!({
|
||
"certificate_address": certificate_address,
|
||
"owner": owner,
|
||
"operator": operator,
|
||
"approved": approved,
|
||
});
|
||
|
||
self.client.call("acc1155_setApprovalForAll", params).await?;
|
||
Ok(())
|
||
}
|
||
|
||
/// 检查授权状态
|
||
///
|
||
/// # 参数
|
||
/// * `certificate_address` - 证书地址
|
||
/// * `owner` - 所有者地址
|
||
/// * `operator` - 操作者地址
|
||
///
|
||
/// # 返回
|
||
/// 是否已授权
|
||
pub async fn is_approved_for_all(
|
||
&self,
|
||
certificate_address: &Address,
|
||
owner: &Address,
|
||
operator: &Address,
|
||
) -> Result<bool> {
|
||
let params = json!({
|
||
"certificate_address": certificate_address,
|
||
"owner": owner,
|
||
"operator": operator,
|
||
});
|
||
|
||
let response = self.client.call("acc1155_isApprovedForAll", params).await?;
|
||
|
||
let approved = response["result"]
|
||
.as_bool()
|
||
.ok_or(NACError::InvalidResponse("Missing approval status".to_string()))?;
|
||
|
||
Ok(approved)
|
||
}
|
||
|
||
/// 获取代币类型元数据
|
||
///
|
||
/// # 参数
|
||
/// * `certificate_address` - 证书地址
|
||
/// * `token_id` - 代币类型ID
|
||
///
|
||
/// # 返回
|
||
/// 代币类型元数据
|
||
pub async fn get_token_metadata(
|
||
&self,
|
||
certificate_address: &Address,
|
||
token_id: TokenId,
|
||
) -> Result<TokenTypeMetadata> {
|
||
let params = json!({
|
||
"certificate_address": certificate_address,
|
||
"token_id": token_id,
|
||
});
|
||
|
||
let response = self.client.call("acc1155_getTokenMetadata", params).await?;
|
||
|
||
let meta_data = &response["result"];
|
||
let metadata = TokenTypeMetadata {
|
||
token_id,
|
||
name: meta_data["name"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing name".to_string()))?
|
||
.to_string(),
|
||
symbol: meta_data["symbol"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing symbol".to_string()))?
|
||
.to_string(),
|
||
token_type: serde_json::from_value(meta_data["token_type"].clone())
|
||
.map_err(|e| NACError::InvalidResponse(format!("Invalid token_type: {}", e)))?,
|
||
uri: meta_data["uri"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing uri".to_string()))?
|
||
.to_string(),
|
||
max_supply: meta_data["max_supply"]
|
||
.as_str()
|
||
.and_then(|s| s.parse().ok()),
|
||
current_supply: meta_data["current_supply"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing current_supply".to_string()))?
|
||
.parse()
|
||
.map_err(|e| NACError::InvalidResponse(format!("Invalid current_supply: {}", e)))?,
|
||
created_at: Timestamp::from_secs(
|
||
meta_data["created_at"]
|
||
.as_u64()
|
||
.ok_or(NACError::InvalidResponse("Missing created_at".to_string()))?
|
||
),
|
||
};
|
||
|
||
Ok(metadata)
|
||
}
|
||
|
||
/// 获取代币类型DNA
|
||
///
|
||
/// # 参数
|
||
/// * `certificate_address` - 证书地址
|
||
/// * `token_id` - 代币类型ID
|
||
///
|
||
/// # 返回
|
||
/// 代币类型DNA
|
||
pub async fn get_token_dna(
|
||
&self,
|
||
certificate_address: &Address,
|
||
token_id: TokenId,
|
||
) -> Result<TokenTypeDNA> {
|
||
let params = json!({
|
||
"certificate_address": certificate_address,
|
||
"token_id": token_id,
|
||
});
|
||
|
||
let response = self.client.call("acc1155_getTokenDNA", params).await?;
|
||
|
||
let dna_data = &response["result"];
|
||
let token_dna = TokenTypeDNA {
|
||
dna_hash: Hash::from_hex(
|
||
dna_data["dna_hash"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing dna_hash".to_string()))?
|
||
).map_err(|e| NACError::InvalidHash(format!("Invalid dna_hash: {}", e)))?,
|
||
token_id,
|
||
gnacs_code: serde_json::from_value(dna_data["gnacs_code"].clone())
|
||
.map_err(|e| NACError::InvalidResponse(format!("Invalid gnacs_code: {}", e)))?,
|
||
token_type: serde_json::from_value(dna_data["token_type"].clone())
|
||
.map_err(|e| NACError::InvalidResponse(format!("Invalid token_type: {}", e)))?,
|
||
sovereignty_type: serde_json::from_value(dna_data["sovereignty_type"].clone())
|
||
.map_err(|e| NACError::InvalidResponse(format!("Invalid sovereignty_type: {}", e)))?,
|
||
metadata_hash: Hash::from_hex(
|
||
dna_data["metadata_hash"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing metadata_hash".to_string()))?
|
||
).map_err(|e| NACError::InvalidHash(format!("Invalid metadata_hash: {}", e)))?,
|
||
generated_at: Timestamp::from_secs(
|
||
dna_data["generated_at"]
|
||
.as_u64()
|
||
.ok_or(NACError::InvalidResponse("Missing generated_at".to_string()))?
|
||
),
|
||
};
|
||
|
||
Ok(token_dna)
|
||
}
|
||
|
||
/// 获取托管信息
|
||
///
|
||
/// # 参数
|
||
/// * `certificate_address` - 证书地址
|
||
/// * `token_id` - 代币类型ID
|
||
///
|
||
/// # 返回
|
||
/// 托管信息
|
||
pub async fn get_custody_info(
|
||
&self,
|
||
certificate_address: &Address,
|
||
token_id: TokenId,
|
||
) -> Result<TokenCustodyInfo> {
|
||
let params = json!({
|
||
"certificate_address": certificate_address,
|
||
"token_id": token_id,
|
||
});
|
||
|
||
let response = self.client.call("acc1155_getCustodyInfo", params).await?;
|
||
|
||
let custody_data = &response["result"];
|
||
let custody_info = TokenCustodyInfo {
|
||
token_id,
|
||
custodian: Address::from_hex(
|
||
custody_data["custodian"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing custodian".to_string()))?
|
||
).map_err(|e| NACError::InvalidAddress(format!("Invalid custodian: {}", e)))?,
|
||
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()))?
|
||
).map_err(|e| NACError::InvalidHash(format!("Invalid custody_proof: {}", e)))?,
|
||
};
|
||
|
||
Ok(custody_info)
|
||
}
|
||
|
||
/// 获取保险信息
|
||
///
|
||
/// # 参数
|
||
/// * `certificate_address` - 证书地址
|
||
/// * `token_id` - 代币类型ID
|
||
///
|
||
/// # 返回
|
||
/// 保险信息
|
||
pub async fn get_insurance_info(
|
||
&self,
|
||
certificate_address: &Address,
|
||
token_id: TokenId,
|
||
) -> Result<TokenInsuranceInfo> {
|
||
let params = json!({
|
||
"certificate_address": certificate_address,
|
||
"token_id": token_id,
|
||
});
|
||
|
||
let response = self.client.call("acc1155_getInsuranceInfo", params).await?;
|
||
|
||
let insurance_data = &response["result"];
|
||
let insurance_info = TokenInsuranceInfo {
|
||
token_id,
|
||
insurer: Address::from_hex(
|
||
insurance_data["insurer"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing insurer".to_string()))?
|
||
).map_err(|e| NACError::InvalidAddress(format!("Invalid insurer: {}", e)))?,
|
||
coverage_per_unit_xtzh: insurance_data["coverage_per_unit_xtzh"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing coverage_per_unit_xtzh".to_string()))?
|
||
.parse()
|
||
.map_err(|e| NACError::InvalidResponse(format!("Invalid coverage: {}", 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)
|
||
}
|
||
|
||
/// 更新代币类型估值
|
||
///
|
||
/// # 参数
|
||
/// * `certificate_address` - 证书地址
|
||
/// * `token_id` - 代币类型ID
|
||
/// * `valuation` - 新的估值
|
||
pub async fn update_token_valuation(
|
||
&self,
|
||
certificate_address: &Address,
|
||
token_id: TokenId,
|
||
valuation: TokenTypeValuation,
|
||
) -> Result<()> {
|
||
let params = json!({
|
||
"certificate_address": certificate_address,
|
||
"token_id": token_id,
|
||
"valuation": {
|
||
"value_per_unit_xtzh": valuation.value_per_unit_xtzh.to_string(),
|
||
"valuation_provider": valuation.valuation_provider,
|
||
"valued_at": valuation.valued_at.as_secs(),
|
||
"validity_period": valuation.validity_period,
|
||
},
|
||
});
|
||
|
||
self.client.call("acc1155_updateTokenValuation", params).await?;
|
||
Ok(())
|
||
}
|
||
|
||
/// 获取代币类型估值
|
||
///
|
||
/// # 参数
|
||
/// * `certificate_address` - 证书地址
|
||
/// * `token_id` - 代币类型ID
|
||
///
|
||
/// # 返回
|
||
/// 代币类型估值
|
||
pub async fn get_token_valuation(
|
||
&self,
|
||
certificate_address: &Address,
|
||
token_id: TokenId,
|
||
) -> Result<TokenTypeValuation> {
|
||
let params = json!({
|
||
"certificate_address": certificate_address,
|
||
"token_id": token_id,
|
||
});
|
||
|
||
let response = self.client.call("acc1155_getTokenValuation", params).await?;
|
||
|
||
let val_data = &response["result"];
|
||
let valuation = TokenTypeValuation {
|
||
token_id,
|
||
value_per_unit_xtzh: val_data["value_per_unit_xtzh"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing value_per_unit_xtzh".to_string()))?
|
||
.parse()
|
||
.map_err(|e| NACError::InvalidResponse(format!("Invalid value: {}", e)))?,
|
||
valuation_provider: Address::from_hex(
|
||
val_data["valuation_provider"]
|
||
.as_str()
|
||
.ok_or(NACError::InvalidResponse("Missing valuation_provider".to_string()))?
|
||
).map_err(|e| NACError::InvalidAddress(format!("Invalid valuation_provider: {}", e)))?,
|
||
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)
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
#[tokio::test]
|
||
async fn test_acc1155_interface() {
|
||
// 这里只是接口测试,实际需要连接到NAC节点
|
||
let client = NRPC3Client::new("https://rpc.newassetchain.io");
|
||
let acc1155 = ACC1155::new(client);
|
||
|
||
// 测试将在实际连接到NAC节点后进行
|
||
assert!(true);
|
||
}
|
||
}
|