bitcoind_async_client/
traits.rs

1use bitcoin::{bip32::Xpriv, block::Header, Address, Block, BlockHash, Network, Transaction, Txid};
2use corepc_types::model::{
3    GetAddressInfo, GetBlockchainInfo, GetMempoolInfo, GetRawMempool, GetRawMempoolVerbose,
4    GetRawTransaction, GetRawTransactionVerbose, GetTransaction, GetTxOut, ListTransactions,
5    ListUnspent, PsbtBumpFee, SignRawTransactionWithWallet, SubmitPackage, TestMempoolAccept,
6    WalletCreateFundedPsbt, WalletProcessPsbt,
7};
8use corepc_types::v29::ImportDescriptors;
9use std::future::Future;
10
11use crate::types::{ImportDescriptorInput, SighashType};
12use crate::{
13    types::{
14        CreateRawTransactionArguments, CreateRawTransactionInput, CreateRawTransactionOutput,
15        ListUnspentQueryOptions, PreviousTransactionOutput, PsbtBumpFeeOptions,
16        WalletCreateFundedPsbtOptions,
17    },
18    ClientResult,
19};
20
21/// Basic functionality that any Bitcoin client that interacts with the
22/// Bitcoin network should provide.
23///
24/// # Note
25///
26/// This is a fully `async` trait. The user should be responsible for
27/// handling the `async` nature of the trait methods. And if implementing
28/// this trait for a specific type that is not `async`, the user should
29/// consider wrapping with [`tokio`](https://tokio.rs)'s
30/// [`spawn_blocking`](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html) or any other method.
31pub trait Reader {
32    /// Estimates the approximate fee per kilobyte needed for a transaction
33    /// to begin confirmation within conf_target blocks if possible and return
34    /// the number of blocks for which the estimate is valid.
35    ///
36    /// # Parameters
37    ///
38    /// - `conf_target`: Confirmation target in blocks.
39    ///
40    /// # Note
41    ///
42    /// Uses virtual transaction size as defined in
43    /// [BIP 141](https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki)
44    /// (witness data is discounted).
45    ///
46    /// By default uses the estimate mode of `CONSERVATIVE` which is the
47    /// default in Bitcoin Core v27.
48    fn estimate_smart_fee(
49        &self,
50        conf_target: u16,
51    ) -> impl Future<Output = ClientResult<u64>> + Send;
52
53    /// Gets a [`Header`] with the given hash.
54    fn get_block_header(
55        &self,
56        hash: &BlockHash,
57    ) -> impl Future<Output = ClientResult<Header>> + Send;
58
59    /// Gets a [`Block`] with the given hash.
60    fn get_block(&self, hash: &BlockHash) -> impl Future<Output = ClientResult<Block>> + Send;
61
62    /// Gets a block height with the given hash.
63    fn get_block_height(&self, hash: &BlockHash) -> impl Future<Output = ClientResult<u64>> + Send;
64
65    /// Gets a [`Header`] at given height.
66    fn get_block_header_at(&self, height: u64)
67        -> impl Future<Output = ClientResult<Header>> + Send;
68
69    /// Gets a [`Block`] at given height.
70    fn get_block_at(&self, height: u64) -> impl Future<Output = ClientResult<Block>> + Send;
71
72    /// Gets the height of the most-work fully-validated chain.
73    ///
74    /// # Note
75    ///
76    /// The genesis block has a height of 0.
77    fn get_block_count(&self) -> impl Future<Output = ClientResult<u64>> + Send;
78
79    /// Gets the [`BlockHash`] at given height.
80    fn get_block_hash(&self, height: u64) -> impl Future<Output = ClientResult<BlockHash>> + Send;
81
82    /// Gets various state info regarding blockchain processing.
83    fn get_blockchain_info(&self) -> impl Future<Output = ClientResult<GetBlockchainInfo>> + Send;
84
85    /// Gets the timestamp in the block header of the current best block in bitcoin.
86    ///
87    /// # Note
88    ///
89    /// Time is Unix epoch time in seconds.
90    fn get_current_timestamp(&self) -> impl Future<Output = ClientResult<u32>> + Send;
91
92    /// Gets all transaction ids in mempool.
93    fn get_raw_mempool(&self) -> impl Future<Output = ClientResult<GetRawMempool>> + Send;
94
95    /// Gets verbose representation of transactions in mempool.
96    fn get_raw_mempool_verbose(
97        &self,
98    ) -> impl Future<Output = ClientResult<GetRawMempoolVerbose>> + Send;
99
100    /// Returns details on the active state of the mempool.
101    fn get_mempool_info(&self) -> impl Future<Output = ClientResult<GetMempoolInfo>> + Send;
102
103    /// Gets a raw transaction by its [`Txid`].
104    fn get_raw_transaction_verbosity_zero(
105        &self,
106        txid: &Txid,
107    ) -> impl Future<Output = ClientResult<GetRawTransaction>> + Send;
108
109    /// Gets a raw transaction by its [`Txid`].
110    fn get_raw_transaction_verbosity_one(
111        &self,
112        txid: &Txid,
113    ) -> impl Future<Output = ClientResult<GetRawTransactionVerbose>> + Send;
114
115    /// Returns details about an unspent transaction output.
116    fn get_tx_out(
117        &self,
118        txid: &Txid,
119        vout: u32,
120        include_mempool: bool,
121    ) -> impl Future<Output = ClientResult<GetTxOut>> + Send;
122
123    /// Gets the underlying [`Network`] information.
124    fn network(&self) -> impl Future<Output = ClientResult<Network>> + Send;
125}
126
127/// Broadcasting functionality that any Bitcoin client that interacts with the
128/// Bitcoin network should provide.
129///
130/// # Note
131///
132/// This is a fully `async` trait. The user should be responsible for
133/// handling the `async` nature of the trait methods. And if implementing
134/// this trait for a specific type that is not `async`, the user should
135/// consider wrapping with [`tokio`](https://tokio.rs)'s
136/// [`spawn_blocking`](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html)
137/// or any other method.
138pub trait Broadcaster {
139    /// Sends a raw transaction to the network.
140    ///
141    /// # Parameters
142    ///
143    /// - `tx`: The raw transaction to send. This should be a byte array containing the serialized
144    ///   raw transaction data.
145    fn send_raw_transaction(
146        &self,
147        tx: &Transaction,
148    ) -> impl Future<Output = ClientResult<Txid>> + Send;
149
150    /// Tests if a raw transaction is valid.
151    fn test_mempool_accept(
152        &self,
153        tx: &Transaction,
154    ) -> impl Future<Output = ClientResult<TestMempoolAccept>> + Send;
155
156    /// Submit a package of raw transactions (serialized, hex-encoded) to local node.
157    ///
158    /// The package will be validated according to consensus and mempool policy rules. If any
159    /// transaction passes, it will be accepted to mempool. This RPC is experimental and the
160    /// interface may be unstable. Refer to doc/policy/packages.md for documentation on package
161    /// policies.
162    ///
163    /// # Warning
164    ///
165    /// Successful submission does not mean the transactions will propagate throughout the network.
166    fn submit_package(
167        &self,
168        txs: &[Transaction],
169    ) -> impl Future<Output = ClientResult<SubmitPackage>> + Send;
170}
171
172/// Wallet functionality that any Bitcoin client **without private keys** that
173/// interacts with the Bitcoin network should provide.
174///
175/// For signing transactions, see [`Signer`].
176///
177/// # Note
178///
179/// This is a fully `async` trait. The user should be responsible for
180/// handling the `async` nature of the trait methods. And if implementing
181/// this trait for a specific type that is not `async`, the user should
182/// consider wrapping with [`tokio`](https://tokio.rs)'s
183/// [`spawn_blocking`](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html)
184/// or any other method.
185pub trait Wallet {
186    /// Generates new address under own control for the underlying Bitcoin
187    /// client's wallet.
188    fn get_new_address(&self) -> impl Future<Output = ClientResult<Address>> + Send;
189
190    /// Gets information related to a transaction.
191    ///
192    /// # Note
193    ///
194    /// This assumes that the transaction is present in the underlying Bitcoin
195    /// client's wallet.
196    fn get_transaction(
197        &self,
198        txid: &Txid,
199    ) -> impl Future<Output = ClientResult<GetTransaction>> + Send;
200
201    /// Lists transactions in the underlying Bitcoin client's wallet.
202    ///
203    /// # Parameters
204    ///
205    /// - `count`: The number of transactions to list. If `None`, assumes a maximum of 10
206    ///   transactions.
207    fn list_transactions(
208        &self,
209        count: Option<usize>,
210    ) -> impl Future<Output = ClientResult<ListTransactions>> + Send;
211
212    /// Lists all wallets in the underlying Bitcoin client.
213    fn list_wallets(&self) -> impl Future<Output = ClientResult<Vec<String>>> + Send;
214
215    /// Creates a raw transaction.
216    fn create_raw_transaction(
217        &self,
218        raw_tx: CreateRawTransactionArguments,
219    ) -> impl Future<Output = ClientResult<Transaction>> + Send;
220
221    /// Creates and funds a PSBT with inputs and outputs from the wallet.
222    ///
223    /// Uses the wallet's UTXOs to automatically fund the specified outputs, creating
224    /// a partially signed Bitcoin transaction that can be further processed or signed.
225    ///
226    /// # Parameters
227    ///
228    /// - `inputs`: Array of specific transaction inputs to include (can be empty for automatic selection).
229    /// - `outputs`: Array of transaction outputs, supporting both address-amount pairs and OP_RETURN data.
230    /// - `locktime`: Optional locktime for the transaction (0 = no locktime).
231    /// - `options`: Optional funding options including fee rate, change address, and confirmation targets.
232    /// - `bip32_derivs`: Whether to include BIP32 derivation paths in the PSBT for signing.
233    ///
234    /// # Returns
235    ///
236    /// Returns a [`WalletCreateFundedPsbt`] containing the funded PSBT, calculated fee, and change output position.
237    ///
238    /// # Note
239    ///
240    /// The returned PSBT is not signed and requires further processing with `wallet_process_psbt`
241    /// or `finalize_psbt` before it can be broadcast to the network.
242    fn wallet_create_funded_psbt(
243        &self,
244        inputs: &[CreateRawTransactionInput],
245        outputs: &[CreateRawTransactionOutput],
246        locktime: Option<u32>,
247        options: Option<WalletCreateFundedPsbtOptions>,
248        bip32_derivs: Option<bool>,
249    ) -> impl Future<Output = ClientResult<WalletCreateFundedPsbt>> + Send;
250
251    /// Returns detailed information about the given address.
252    ///
253    /// Queries the wallet for comprehensive information about a Bitcoin address,
254    /// including ownership status, spending capabilities, and script details.
255    /// This is useful for determining if an address belongs to the wallet and
256    /// how it can be used for transactions.
257    ///
258    /// # Parameters
259    ///
260    /// - `address`: The Bitcoin address to analyze (any valid Bitcoin address format).
261    ///
262    /// # Returns
263    ///
264    /// Returns a [`GetAddressInfo`] containing:
265    /// - Address ownership status (`is_mine`)
266    /// - Watch-only status (`is_watchonly`)
267    /// - Spending capability (`solvable`)
268    /// - The queried address for confirmation
269    ///
270    /// # Note
271    ///
272    /// The address doesn't need to belong to the wallet to query information about it.
273    /// However, detailed ownership and spending information will only be available
274    /// for addresses that the wallet knows about.
275    fn get_address_info(
276        &self,
277        address: &Address,
278    ) -> impl Future<Output = ClientResult<GetAddressInfo>> + Send;
279
280    /// Lists unspent transaction outputs with filtering options.
281    ///
282    /// Queries the wallet for unspent transaction outputs (UTXOs) with comprehensive
283    /// filtering capabilities. This is essential for coin selection, balance calculation,
284    /// and preparing transaction inputs. Provides fine-grained control over which
285    /// UTXOs are returned based on confirmations, addresses, safety, and amounts.
286    ///
287    /// # Parameters
288    ///
289    /// - `min_conf`: Minimum number of confirmations required (default: 1). Use 0 for unconfirmed outputs.
290    /// - `max_conf`: Maximum number of confirmations to include (default: 9,999,999). Limits how old UTXOs can be.
291    /// - `addresses`: Optional list of specific addresses to filter by. If provided, only UTXOs from these addresses are returned.
292    /// - `include_unsafe`: Whether to include outputs that are not safe to spend (default: true). Unsafe outputs include unconfirmed transactions from external keys.
293    /// - `query_options`: Additional filtering options for amount ranges and result limits via [`ListUnspentQueryOptions`].
294    ///
295    /// # Returns
296    ///
297    /// Returns a vector of [`ListUnspent`] containing:
298    /// - Transaction ID and output index (`txid`, `vout`)
299    /// - Bitcoin address and amount (`address`, `amount`)
300    /// - Confirmation count and safety status (`confirmations`, `safe`)
301    /// - Spendability information (`spendable`, `solvable`)
302    /// - Script details (`script_pubkey`, `label`)
303    ///
304    /// # Note
305    ///
306    /// UTXOs must satisfy ALL specified criteria to be included in results.
307    /// This method is commonly used for wallet balance calculation and transaction
308    /// preparation. Consider using `query_options` for amount-based filtering
309    /// to optimize coin selection strategies.
310    fn list_unspent(
311        &self,
312        min_conf: Option<u32>,
313        max_conf: Option<u32>,
314        addresses: Option<&[Address]>,
315        include_unsafe: Option<bool>,
316        query_options: Option<ListUnspentQueryOptions>,
317    ) -> impl Future<Output = ClientResult<ListUnspent>> + Send;
318}
319
320/// Signing functionality that any Bitcoin client **with private keys** that
321/// interacts with the Bitcoin network should provide.
322///
323/// # Note
324///
325/// This is a fully `async` trait. The user should be responsible for
326/// handling the `async` nature of the trait methods. And if implementing
327/// this trait for a specific type that is not `async`, the user should
328/// consider wrapping with [`tokio`](https://tokio.rs)'s
329/// [`spawn_blocking`](https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html)
330/// or any other method.
331pub trait Signer {
332    /// Signs a transaction using the keys available in the underlying Bitcoin
333    /// client's wallet and returns a signed transaction.
334    ///
335    /// # Note
336    ///
337    /// The returned signed transaction might not be consensus-valid if it
338    /// requires additional signatures, such as in a multisignature context.
339    fn sign_raw_transaction_with_wallet(
340        &self,
341        tx: &Transaction,
342        prev_outputs: Option<Vec<PreviousTransactionOutput>>,
343    ) -> impl Future<Output = ClientResult<SignRawTransactionWithWallet>> + Send;
344
345    /// Gets the underlying [`Xpriv`] from the wallet.
346    fn get_xpriv(&self) -> impl Future<Output = ClientResult<Option<Xpriv>>> + Send;
347
348    /// Imports the descriptors into the wallet.
349    fn import_descriptors(
350        &self,
351        descriptors: Vec<ImportDescriptorInput>,
352        wallet_name: String,
353    ) -> impl Future<Output = ClientResult<ImportDescriptors>> + Send;
354
355    /// Updates a PSBT with input information from the wallet and optionally signs it.
356    ///
357    /// # Parameters
358    ///
359    /// - `psbt`: The PSBT to process as a base64 string.
360    /// - `sign`: Whether to sign the transaction (default: true).
361    /// - `sighashtype`: Optional signature hash type to use.
362    /// - `bip32_derivs`: Whether to include BIP32 derivation paths.
363    ///
364    /// # Returns
365    ///
366    /// Returns a [`WalletProcessPsbt`] with the processed PSBT and completion status.
367    fn wallet_process_psbt(
368        &self,
369        psbt: &str,
370        sign: Option<bool>,
371        sighashtype: Option<SighashType>,
372        bip32_derivs: Option<bool>,
373    ) -> impl Future<Output = ClientResult<WalletProcessPsbt>> + Send;
374
375    /// Bumps the fee of an opt-in-RBF transaction, replacing it with a new transaction.
376    ///
377    /// # Parameters
378    ///
379    /// - `txid`: The transaction ID to be bumped.
380    /// - `options`: Optional fee bumping options including:
381    ///   - `conf_target`: Confirmation target in blocks
382    ///   - `fee_rate`: Fee rate in sat/vB (overrides conf_target)
383    ///   - `replaceable`: Whether the new transaction should be BIP-125 replaceable
384    ///   - `estimate_mode`: Fee estimate mode ("unset", "economical", "conservative")
385    ///   - `outputs`: New transaction outputs to replace existing ones
386    ///   - `original_change_index`: Index of change output to recycle from original transaction
387    ///
388    /// # Returns
389    ///
390    /// Returns a [`PsbtBumpFee`] containing the new PSBT and fee information.
391    ///
392    /// # Note
393    ///
394    /// The transaction must be BIP-125 opt-in replaceable and the new fee rate must be
395    /// higher than the original.
396    fn psbt_bump_fee(
397        &self,
398        txid: &Txid,
399        options: Option<PsbtBumpFeeOptions>,
400    ) -> impl Future<Output = ClientResult<PsbtBumpFee>> + Send;
401}