use crate::{
Blockchain,
rpc_server::{RpcServerError, parse_block_hash, parse_hex_bytes, types::HexString},
strings::rpc_server::runtime_api,
};
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
use scale::Encode;
use std::sync::Arc;
#[rpc(server, namespace = "payment")]
pub trait PaymentApi {
#[method(name = "queryInfo")]
async fn query_info(&self, extrinsic: String, at: Option<String>) -> RpcResult<String>;
#[method(name = "queryFeeDetails")]
async fn query_fee_details(&self, extrinsic: String, at: Option<String>) -> RpcResult<String>;
}
pub struct PaymentApi {
blockchain: Arc<Blockchain>,
}
impl PaymentApi {
pub fn new(blockchain: Arc<Blockchain>) -> Self {
Self { blockchain }
}
}
#[async_trait::async_trait]
impl PaymentApiServer for PaymentApi {
async fn query_info(&self, extrinsic: String, at: Option<String>) -> RpcResult<String> {
let ext_bytes = parse_hex_bytes(&extrinsic, "extrinsic")?;
let block_hash = match at {
Some(hash) => parse_block_hash(&hash)?,
None => self.blockchain.head_hash().await,
};
let mut params = ext_bytes.clone();
params.extend((ext_bytes.len() as u32).encode());
match self
.blockchain
.call_at_block(block_hash, runtime_api::QUERY_INFO, ¶ms)
.await
{
Ok(Some(result)) => {
Ok(HexString::from_bytes(&result).into())
},
Ok(None) =>
Err(RpcServerError::Internal("Runtime call returned no result".to_string()).into()),
Err(e) => Err(RpcServerError::Internal(format!("Runtime call failed: {}", e)).into()),
}
}
async fn query_fee_details(&self, extrinsic: String, at: Option<String>) -> RpcResult<String> {
let ext_bytes = parse_hex_bytes(&extrinsic, "extrinsic")?;
let block_hash = match at {
Some(hash) => parse_block_hash(&hash)?,
None => self.blockchain.head_hash().await,
};
let mut params = ext_bytes.clone();
params.extend((ext_bytes.len() as u32).encode());
match self
.blockchain
.call_at_block(block_hash, runtime_api::QUERY_FEE_DETAILS, ¶ms)
.await
{
Ok(Some(result)) => {
Ok(HexString::from_bytes(&result).into())
},
Ok(None) =>
Err(RpcServerError::Internal("Runtime call returned no result".to_string()).into()),
Err(e) => Err(RpcServerError::Internal(format!("Runtime call failed: {}", e)).into()),
}
}
}