bitcoind_async_client/
traits.rs

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