substrate_api_client/api/rpc_api/
pallet_transaction_payment.rs

1/*
2   Copyright 2019 Supercomputing Systems AG
3   Licensed under the Apache License, Version 2.0 (the "License");
4   you may not use this file except in compliance with the License.
5   You may obtain a copy of the License at
6	   http://www.apache.org/licenses/LICENSE-2.0
7   Unless required by applicable law or agreed to in writing, software
8   distributed under the License is distributed on an "AS IS" BASIS,
9   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10   See the License for the specific language governing permissions and
11   limitations under the License.
12*/
13use 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/// Interface to common calls of the substrate transaction payment pallet.
24#[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}