subcoin_rpc_bitcoind/
lib.rs

1//! Bitcoin Core compatible JSON-RPC API for Subcoin.
2//!
3//! This crate provides a Bitcoin Core compatible RPC layer that enables Subcoin
4//! to work with Bitcoin ecosystem tools like electrs (Electrum server).
5//!
6//! # Supported RPC Methods
7//!
8//! ## Blockchain
9//! - `getbestblockhash` - Returns the hash of the best block
10//! - `getblockchaininfo` - Returns blockchain state info
11//! - `getblockcount` - Returns the current block count
12//! - `getblockhash` - Returns block hash at given height
13//! - `getblock` - Returns block data (raw hex or JSON)
14//! - `getblockheader` - Returns block header (raw hex or JSON)
15//!
16//! ## Raw Transactions
17//! - `getrawtransaction` - Returns raw transaction data
18//! - `sendrawtransaction` - Broadcasts a raw transaction
19//! - `decoderawtransaction` - Decodes a raw transaction hex
20//!
21//! ## Network
22//! - `getnetworkinfo` - Returns network state info
23//!
24//! ## Mempool
25//! - `getrawmempool` - Returns all mempool txids
26//! - `getmempoolinfo` - Returns mempool statistics
27//! - `getmempoolentry` - Returns mempool entry for a txid
28//!
29//! ## Mining/Fees
30//! - `estimatesmartfee` - Estimates fee rate for confirmation target
31
32mod blockchain;
33mod error;
34mod mempool;
35mod mining;
36mod network;
37mod rawtx;
38mod types;
39
40pub use blockchain::{Blockchain, BlockchainApiServer};
41pub use error::Error;
42pub use mempool::{MempoolApiServer, MempoolRpc};
43pub use mining::{MiningApiServer, MiningRpc};
44pub use network::{NetworkApiServer, NetworkRpc};
45pub use rawtx::{RawTransaction, RawTransactionApiServer};
46pub use types::*;
47
48use bitcoin::Network;
49use sc_client_api::{AuxStore, BlockBackend, HeaderBackend};
50use sp_runtime::traits::Block as BlockT;
51use std::sync::Arc;
52use subcoin_network::NetworkApi;
53use subcoin_primitives::{BitcoinTransactionAdapter, TransactionIndex};
54
55/// Bitcoin Core compatible RPC server.
56///
57/// Aggregates all Bitcoin Core compatible RPC modules.
58pub struct BitcoindRpc<Block, Client, TransactionAdapter> {
59    /// Blockchain RPC.
60    pub blockchain: Blockchain<Block, Client, TransactionAdapter>,
61    /// Raw transaction RPC.
62    pub rawtx: RawTransaction<Block, Client, TransactionAdapter>,
63    /// Network RPC.
64    pub network: NetworkRpc,
65    /// Mempool RPC.
66    pub mempool: MempoolRpc,
67    /// Mining RPC.
68    pub mining: MiningRpc,
69}
70
71impl<Block, Client, TransactionAdapter> BitcoindRpc<Block, Client, TransactionAdapter>
72where
73    Block: BlockT + 'static,
74    Client: HeaderBackend<Block> + BlockBackend<Block> + AuxStore + 'static,
75    TransactionAdapter: BitcoinTransactionAdapter<Block> + Send + Sync + 'static,
76{
77    /// Creates a new instance of [`BitcoindRpc`].
78    pub fn new(
79        client: Arc<Client>,
80        network_api: Arc<dyn NetworkApi>,
81        transaction_index: Arc<dyn TransactionIndex + Send + Sync>,
82        network: Network,
83    ) -> Self {
84        Self {
85            blockchain: Blockchain::<_, _, TransactionAdapter>::new(client.clone(), network),
86            rawtx: RawTransaction::<_, _, TransactionAdapter>::new(
87                client,
88                network_api,
89                transaction_index,
90                network,
91            ),
92            network: NetworkRpc::new(network),
93            mempool: MempoolRpc::new(),
94            mining: MiningRpc::new(),
95        }
96    }
97
98    /// Merges all RPC modules into a given RPC method registry.
99    pub fn merge_into(
100        self,
101        module: &mut jsonrpsee::Methods,
102    ) -> Result<(), jsonrpsee::server::RegisterMethodError> {
103        let Self {
104            blockchain,
105            rawtx,
106            network,
107            mempool,
108            mining,
109        } = self;
110
111        module.merge(blockchain.into_rpc())?;
112        module.merge(rawtx.into_rpc())?;
113        module.merge(network.into_rpc())?;
114        module.merge(mempool.into_rpc())?;
115        module.merge(mining.into_rpc())?;
116
117        Ok(())
118    }
119}