Rust NEAR协议JSON-RPC客户端库near-jsonrpc-client的使用,实现与NEAR区块链节点的高效交互
Rust NEAR协议JSON-RPC客户端库near-jsonrpc-client的使用
near-jsonrpc-client是一个通过JSON-RPC与NEAR协议交互的低级API库。
使用方法
每个有效的JSON-RPC方法都定义在methods
模块中。例如,要创建一个tx
请求,你需要从tx
模块开始,使用methods::tx::RpcTransactionStatusRequest
结构体构建请求。
以下是内容中提供的示例代码:
use near_jsonrpc_client::{methods, JsonRpcClient};
use near_jsonrpc_primitives::types::transactions::TransactionInfo;
let mainnet_client = JsonRpcClient::connect("https://archival-rpc.mainnet.near.org");
let tx_status_request = methods::tx::RpcTransactionStatusRequest {
transaction_info: TransactionInfo::TransactionId {
hash: "9FtHUFBQsZ2MG77K3x3MJ9wjX3UT8zE1TczCrhZEcG8U".parse()?,
account_id: "miraclx.near".parse()?,
},
};
// 通过连接客户端在服务器上调用方法
let tx_status = mainnet_client.call(tx_status_request).await?;
println!("{:?}", tx_status);
完整示例
下面是一个更完整的示例,展示如何使用near-jsonrpc-client与NEAR区块链节点交互:
use near_jsonrpc_client::{methods, JsonRpcClient};
use near_jsonrpc_primitives::types::transactions::TransactionInfo;
use near_primitives::types::AccountId;
use near_primitives::views::QueryRequest;
use std::str::FromStr;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 连接到NEAR主网节点
let client = JsonRpcClient::connect("https://archival-rpc.mainnet.near.org");
// 示例1: 查询交易状态
let tx_request = methods::tx::RpcTransactionStatusRequest {
transaction_info: TransactionInfo::TransactionId {
hash: "9FtHUFBQsZ2MG77K3x3MJ9wjX3UT8zE1TczCrhZEcG8U".parse()?,
account_id: "miraclx.near".parse()?,
},
};
let tx_status = client.call(tx_request).await?;
println!("Transaction status: {:?}", tx_status);
// 示例2: 查询账户信息
let account_id = AccountId::from_str("near")?;
let account_request = methods::query::RpcQueryRequest {
block_reference: near_primitives::types::BlockReference::latest(),
request: QueryRequest::ViewAccount { account_id },
};
let account_info = client.call(account_request).await?;
println!("Account info: {:?}", account_info);
// 示例3: 获取区块状态
let block_request = methods::block::RpcBlockRequest {
block_reference: near_primitives::types::BlockReference::latest(),
};
let block_info = client.call(block_request).await?;
println!("Latest block: {:?}", block_info);
Ok(())
}
特性
- 提供了所有NEAR JSON-RPC方法的低级接口
- 异步支持,适合高性能应用
- 类型安全的请求和响应结构体
- 支持主网和测试网连接
安装
要在项目中使用near-jsonrpc-client,可以运行以下Cargo命令:
cargo add near-jsonrpc-client
或者在Cargo.toml中添加:
near-jsonrpc-client = "0.17.0"
许可证
near-jsonrpc-client采用双重许可:
- Apache License, Version 2.0
- MIT license
你可以选择其中任何一种许可证使用。
1 回复
Rust NEAR协议JSON-RPC客户端库near-jsonrpc-client使用指南
near-jsonrpc-client
是一个Rust库,用于与NEAR区块链节点通过JSON-RPC协议进行交互。它提供了类型安全的接口来调用NEAR节点的各种RPC方法。
安装
在Cargo.toml中添加依赖:
[dependencies]
near-jsonrpc-client = "0.5.0"
tokio = { version = "1.0", features = ["full"] } # 需要异步运行时
完整示例代码
use near_jsonrpc_client::{JsonRpcClient, methods};
use near_jsonrpc_primitives::types::query::QueryResponseKind;
use near_primitives::transaction::Transaction;
use near_crypto::{InMemorySigner, SecretKey};
use futures::StreamExt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// 1. 创建客户端
let client = JsonRpcClient::connect("https://archival-rpc.mainnet.near.org");
// 2. 查询区块信息
get_block_info(&client).await?;
// 3. 查询账户信息
get_account_info(&client).await?;
// 4. 发送交易 (测试网)
// send_transaction(&client).await?;
// 5. 批量请求
batch_requests(&client).await?;
// 6. 订阅区块事件
// subscribe_blocks(&client).await?;
// 7. 错误处理示例
handle_errors(&client).await?;
// 8. 并发请求
concurrent_requests(&client).await?;
Ok(())
}
async fn get_block_info(client: &JsonRpcClient) -> Result<(), Box<dyn std::error::Error>> {
let request = methods::block::RpcBlockRequest {
block_id: near_primitives::types::BlockId::latest(),
};
let response = client.call(request).await?;
println!("Latest block height: {}", response.header.height);
println!("Block hash: {}", response.header.hash);
Ok(())
}
async fn get_account_info(client: &JsonRpcClient) -> Result<(), Box<dyn std::error::Error>> {
let request = methods::query::RpcQueryRequest {
block_reference: near_primitives::types::BlockReference::latest(),
request: near_primitives::views::QueryRequest::ViewAccount {
account_id: "near".parse()?,
},
};
let response = client.call(request).await?;
if let QueryResponseKind::ViewAccount(account_view) = response.kind {
println!("Account ID: {}", account_view.account_id);
println!("Balance: {} yoctoNEAR", account_view.amount);
println!("Storage used: {} bytes", account_view.storage_usage);
}
Ok(())
}
async fn send_transaction(client: &JsonRpcClient) -> Result<(), Box<dyn std::error::Error>> {
// 注意: 实际使用时应从安全存储中获取私钥
let signer = InMemorySigner::from_secret_key(
"your_account.testnet".parse()?,
SecretKey::from_str("ed25519:your_private_key_here")?,
);
let transaction = Transaction {
signer_id: "your_account.testnet".parse()?,
public_key: signer.public_key(),
nonce: 1, // 实际应从账户状态查询当前nonce
receiver_id: "receiver_account.testnet".parse()?,
block_hash: client.call(methods::block::RpcBlockRequest::latest()).await?.header.hash,
actions: vec![
near_primitives::transaction::Action::Transfer(
near_primitives::transaction::TransferAction {
deposit: 1_000_000_000_000_000_000_000_000, // 1 NEAR
}
)
],
};
let request = methods::broadcast_tx_async::RpcBroadcastTxAsyncRequest {
signed_transaction: transaction.sign(&signer),
};
let response = client.call(request).await?;
println!("Transaction sent! Hash: {}", response);
Ok(())
}
async fn batch_requests(client: &JsonRpcClient) -> Result<(), Box<dyn std::error::Error>> {
let batch = vec![
methods::block::RpcBlockRequest::latest().into(),
methods::gas_price::RpcGasPriceRequest { block_id: None }.into(),
];
let responses = client.batch(batch).await?;
for response in responses {
match response {
methods::block::RpcBlockResponse::Ok(block) => {
println!("Block height: {}", block.header.height);
},
methods::gas_price::RpcGasPriceResponse::Ok(gas_price) => {
println!("Gas price: {:?}", gas_price.gas_price);
},
_ => println!("Unexpected response"),
}
}
Ok(())
}
async fn subscribe_blocks(client: &JsonRpcClient) -> Result<(), Box<dyn std::error::Error>> {
let mut stream = client.subscribe(methods::block::RpcBlockRequest::latest()).await?;
while let Some(block) = stream.next().await {
println!("New block: {}", block?.header.height);
}
Ok(())
}
async fn handle_errors(client: &JsonRpcClient) -> Result<(), Box<dyn std::error::Error>> {
let request = methods::query::RpcQueryRequest {
block_reference: near_primitives::types::BlockReference::latest(),
request: near_primitives::views::QueryRequest::ViewAccount {
account_id: "nonexistent-account.testnet".parse()?,
},
};
match client.call(request).await {
Ok(response) => {
println!("Account exists: {:?}", response);
},
Err(near_jsonrpc_client::errors::RpcError::HandlerError(err)) => {
eprintln!("Account does not exist: {}", err);
},
Err(err) => {
eprintln!("RPC error: {}", err);
}
}
Ok(())
}
async fn concurrent_requests(client: &JsonRpcClient) -> Result<(), Box<dyn std::error::Error>> {
let futures = vec![
client.call(methods::block::RpcBlockRequest::latest()),
client.call(methods::gas_price::RpcGasPriceRequest { block_id: None }),
];
let results = futures::future::try_join_all(futures).await?;
if let methods::block::RpcBlockResponse::Ok(block) = &results[0] {
println!("Latest block height: {}", block.header.height);
}
if let methods::gas_price::RpcGasPriceResponse::Ok(gas_price) = &results[1] {
println!("Current gas price: {:?}", gas_price.gas_price);
}
Ok(())
}
near-jsonrpc-client
提供了与NEAR区块链交互的完整功能集,包括查询状态、发送交易、订阅事件等。通过类型安全的API和Rust的强类型系统,可以大大减少运行时错误。