1use crate::FullClient;
2use crate::rpc::FullDeps;
3use domain_runtime_primitives::{Balance, Nonce};
4use jsonrpsee::RpcModule;
5use parity_scale_codec::{Decode, Encode};
6use sc_client_api::{AuxStore, Backend, BlockBackend, StorageProvider};
7use sc_consensus::BlockImport;
8use sc_rpc::SubscriptionTaskExecutor;
9use sc_rpc_server::SubscriptionIdProvider;
10use sc_transaction_pool_api::TransactionPool;
11use serde::de::DeserializeOwned;
12use sp_api::{ApiExt, ConstructRuntimeApi, Core, ProvideRuntimeApi};
13use sp_block_builder::BlockBuilder;
14use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
15use sp_core::traits::SpawnEssentialNamed;
16use sp_runtime::traits::Block as BlockT;
17use std::error::Error;
18use std::fmt::{Debug, Display};
19use std::sync::Arc;
20use substrate_frame_rpc_system::AccountNonceApi;
21
22pub trait BlockImportProvider<Block: BlockT, Client>
23where
24 Client: ProvideRuntimeApi<Block>,
25{
26 type BI: BlockImport<Block, Error = sp_consensus::Error> + Send + Sync + 'static;
27 fn block_import(&self, client: Arc<Client>) -> Self::BI;
28}
29
30#[derive(Clone, Default)]
31pub struct DefaultProvider;
32
33impl<Block, RuntimeApi> BlockImportProvider<Block, FullClient<Block, RuntimeApi>>
34 for DefaultProvider
35where
36 Block: BlockT,
37 RuntimeApi: ConstructRuntimeApi<Block, FullClient<Block, RuntimeApi>> + Send + Sync + 'static,
38 RuntimeApi::RuntimeApi: ApiExt<Block> + Core<Block>,
39{
40 type BI = Arc<FullClient<Block, RuntimeApi>>;
41
42 fn block_import(&self, client: Arc<FullClient<Block, RuntimeApi>>) -> Self::BI {
43 client
44 }
45}
46
47pub trait RpcProvider<Block, Client, TxPool, BE, AccountId, CIDP>
49where
50 Block: BlockT,
51 Client: ProvideRuntimeApi<Block> + StorageProvider<Block, BE>,
52 Client::Api: AccountNonceApi<Block, AccountId, Nonce>,
53 TxPool: TransactionPool<Block = Block> + Sync + Send + 'static,
54 BE: Backend<Block> + 'static,
55 AccountId: DeserializeOwned + Encode + Debug + Decode + Display + Clone + Sync + Send + 'static,
56{
57 type Deps: Clone;
58
59 #[expect(clippy::result_large_err, reason = "Comes from Substrate")]
60 fn deps(
61 &self,
62 full_deps: FullDeps<Block, Client, TxPool, BE, CIDP>,
63 ) -> Result<Self::Deps, sc_service::Error>;
64
65 fn rpc_id(&self) -> Option<Box<dyn SubscriptionIdProvider>>;
66
67 fn rpc_builder<SE>(
68 &self,
69 deps: Self::Deps,
70 subscription_task_executor: SubscriptionTaskExecutor,
71 essential_task_spawner: SE,
72 ) -> Result<RpcModule<()>, Box<dyn Error + Send + Sync>>
73 where
74 SE: SpawnEssentialNamed + Clone;
75}
76
77impl<Block, Client, BE, TxPool, AccountId, CIDP>
78 RpcProvider<Block, Client, TxPool, BE, AccountId, CIDP> for DefaultProvider
79where
80 Block: BlockT,
81 Client: ProvideRuntimeApi<Block>
82 + BlockBackend<Block>
83 + HeaderBackend<Block>
84 + AuxStore
85 + HeaderMetadata<Block, Error = BlockChainError>
86 + StorageProvider<Block, BE>
87 + Send
88 + Sync
89 + 'static,
90 Client::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>
91 + AccountNonceApi<Block, AccountId, Nonce>
92 + BlockBuilder<Block>,
93 TxPool: TransactionPool<Block = Block> + Sync + Send + 'static,
94 BE: Backend<Block> + 'static,
95 AccountId: DeserializeOwned + Encode + Debug + Decode + Display + Clone + Sync + Send + 'static,
96 CIDP: Clone,
97{
98 type Deps = FullDeps<Block, Client, TxPool, BE, CIDP>;
99
100 fn deps(
101 &self,
102 full_deps: FullDeps<Block, Client, TxPool, BE, CIDP>,
103 ) -> Result<Self::Deps, sc_service::Error> {
104 Ok(full_deps)
105 }
106
107 fn rpc_id(&self) -> Option<Box<dyn SubscriptionIdProvider>> {
108 None
109 }
110
111 fn rpc_builder<SE>(
112 &self,
113 deps: Self::Deps,
114 _subscription_task_executor: SubscriptionTaskExecutor,
115 _essential_task_spawner: SE,
116 ) -> Result<RpcModule<()>, Box<dyn Error + Send + Sync>>
117 where
118 SE: SpawnEssentialNamed + Clone,
119 {
120 crate::rpc::create_full::<_, _, _, AccountId, BE, CIDP>(deps)
121 }
122}