substrate_api_client/api/rpc_api/
pallet_transaction_payment.rs1use crate::{
14 api::{Api, Error, Result},
15 rpc::Request,
16};
17use ac_compose_macros::rpc_params;
18use ac_primitives::{config::Config, FeeDetails, InclusionFee, NumberOrHex, RuntimeDispatchInfo};
19#[cfg(all(not(feature = "sync-api"), not(feature = "std")))]
20use alloc::boxed::Box;
21use core::str::FromStr;
22use sp_core::Bytes;
23#[maybe_async::maybe_async(?Send)]
25pub trait GetTransactionPayment {
26 type Hash;
27 type Balance;
28
29 async fn get_fee_details(
30 &self,
31 encoded_extrinsic: &Bytes,
32 at_block: Option<Self::Hash>,
33 ) -> Result<Option<FeeDetails<Self::Balance>>>;
34
35 async fn get_payment_info(
36 &self,
37 encoded_extrinsic: &Bytes,
38 at_block: Option<Self::Hash>,
39 ) -> Result<Option<RuntimeDispatchInfo<Self::Balance>>>;
40}
41
42#[maybe_async::maybe_async(?Send)]
43impl<T, Client> GetTransactionPayment for Api<T, Client>
44where
45 T: Config,
46 Client: Request,
47 T::Balance: TryFrom<NumberOrHex> + FromStr,
48{
49 type Hash = T::Hash;
50 type Balance = T::Balance;
51
52 async fn get_fee_details(
53 &self,
54 encoded_extrinsic: &Bytes,
55 at_block: Option<Self::Hash>,
56 ) -> Result<Option<FeeDetails<Self::Balance>>> {
57 let details: Option<FeeDetails<NumberOrHex>> = self
58 .client()
59 .request("payment_queryFeeDetails", rpc_params![encoded_extrinsic, at_block])
60 .await?;
61
62 let details = match details {
63 Some(details) => Some(convert_fee_details(details)?),
64 None => None,
65 };
66 Ok(details)
67 }
68
69 async fn get_payment_info(
70 &self,
71 encoded_extrinsic: &Bytes,
72 at_block: Option<Self::Hash>,
73 ) -> Result<Option<RuntimeDispatchInfo<Self::Balance>>> {
74 let res = self
75 .client()
76 .request("payment_queryInfo", rpc_params![encoded_extrinsic, at_block])
77 .await?;
78 Ok(res)
79 }
80}
81
82fn convert_fee_details<Balance: TryFrom<NumberOrHex>>(
83 details: FeeDetails<NumberOrHex>,
84) -> Result<FeeDetails<Balance>> {
85 let inclusion_fee = if let Some(inclusion_fee) = details.inclusion_fee {
86 Some(inclusion_fee_with_balance(inclusion_fee)?)
87 } else {
88 None
89 };
90 let tip = details.tip.try_into().map_err(|_| Error::TryFromIntError)?;
91 Ok(FeeDetails { inclusion_fee, tip })
92}
93
94fn inclusion_fee_with_balance<Balance: TryFrom<NumberOrHex>>(
95 inclusion_fee: InclusionFee<NumberOrHex>,
96) -> Result<InclusionFee<Balance>> {
97 Ok(InclusionFee {
98 base_fee: inclusion_fee.base_fee.try_into().map_err(|_| Error::TryFromIntError)?,
99 len_fee: inclusion_fee.len_fee.try_into().map_err(|_| Error::TryFromIntError)?,
100 adjusted_weight_fee: inclusion_fee
101 .adjusted_weight_fee
102 .try_into()
103 .map_err(|_| Error::TryFromIntError)?,
104 })
105}