bitcoind_async_client/
types.rs

1//! Types that are not returned by the RPC server, but used as arguments/inputs of the RPC methods.
2
3use bitcoin::{Amount, FeeRate, Txid};
4use serde::{
5    de::{self, Visitor},
6    Deserialize, Deserializer, Serialize, Serializer,
7};
8
9/// Models the arguments of JSON-RPC method `createrawtransaction`.
10///
11/// # Note
12///
13/// Assumes that the transaction is always "replaceable" by default and has a locktime of 0.
14#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
15pub struct CreateRawTransactionArguments {
16    pub inputs: Vec<CreateRawTransactionInput>,
17    pub outputs: Vec<CreateRawTransactionOutput>,
18}
19
20/// Models the input of JSON-RPC method `createrawtransaction`.
21#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
22pub struct CreateRawTransactionInput {
23    pub txid: String,
24    pub vout: u32,
25}
26
27/// Models transaction outputs for Bitcoin RPC methods.
28///
29/// Used by various RPC methods such as `createrawtransaction`, `psbtbumpfee`,
30/// and `walletcreatefundedpsbt`. The outputs are specified as key-value pairs,
31/// where the keys are addresses and the values are amounts to send.
32#[derive(Clone, Debug, PartialEq, Deserialize)]
33#[serde(untagged)]
34pub enum CreateRawTransactionOutput {
35    /// A pair of an [`bitcoin::Address`] string and an [`Amount`] in BTC.
36    AddressAmount {
37        /// An [`bitcoin::Address`] string.
38        address: String,
39        /// An [`Amount`] in BTC.
40        amount: f64,
41    },
42    /// A payload such as in `OP_RETURN` transactions.
43    Data {
44        /// The payload.
45        data: String,
46    },
47}
48
49impl Serialize for CreateRawTransactionOutput {
50    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
51    where
52        S: serde::Serializer,
53    {
54        match self {
55            CreateRawTransactionOutput::AddressAmount { address, amount } => {
56                let mut map = serde_json::Map::new();
57                map.insert(
58                    address.clone(),
59                    serde_json::Value::Number(serde_json::Number::from_f64(*amount).unwrap()),
60                );
61                map.serialize(serializer)
62            }
63            CreateRawTransactionOutput::Data { data } => {
64                let mut map = serde_json::Map::new();
65                map.insert("data".to_string(), serde_json::Value::String(data.clone()));
66                map.serialize(serializer)
67            }
68        }
69    }
70}
71
72/// Models the optional previous transaction outputs argument for the method
73/// `signrawtransactionwithwallet`.
74///
75/// These are the outputs that this transaction depends on but may not yet be in the block chain.
76/// Widely used for One Parent One Child (1P1C) Relay in Bitcoin >28.0.
77///
78/// > transaction outputs
79/// > [
80/// > {                            (json object)
81/// > "txid": "hex",             (string, required) The transaction id
82/// > "vout": n,                 (numeric, required) The output number
83/// > "scriptPubKey": "hex",     (string, required) The output script
84/// > "redeemScript": "hex",     (string, optional) (required for P2SH) redeem script
85/// > "witnessScript": "hex",    (string, optional) (required for P2WSH or P2SH-P2WSH) witness
86/// > script
87/// > "amount": amount,          (numeric or string, optional) (required for Segwit inputs) the
88/// > amount spent
89/// > },
90/// > ...
91/// > ]
92#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
93pub struct PreviousTransactionOutput {
94    /// The transaction id.
95    #[serde(deserialize_with = "deserialize_txid")]
96    pub txid: Txid,
97    /// The output number.
98    pub vout: u32,
99    /// The output script.
100    #[serde(rename = "scriptPubKey")]
101    pub script_pubkey: String,
102    /// The redeem script.
103    #[serde(rename = "redeemScript")]
104    pub redeem_script: Option<String>,
105    /// The witness script.
106    #[serde(rename = "witnessScript")]
107    pub witness_script: Option<String>,
108    /// The amount spent.
109    pub amount: Option<f64>,
110}
111
112/// Models the Descriptor in the result of the JSON-RPC method `importdescriptors`.
113#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
114pub struct ImportDescriptorInput {
115    /// The descriptor.
116    pub desc: String,
117    /// Set this descriptor to be the active descriptor
118    /// for the corresponding output type/externality.
119    pub active: Option<bool>,
120    /// Time from which to start rescanning the blockchain for this descriptor,
121    /// in UNIX epoch time. Can also be a string "now"
122    pub timestamp: String,
123}
124
125/// Models the `createwallet` JSON-RPC method.
126///
127/// # Note
128///
129/// This can also be used for the `loadwallet` JSON-RPC method.
130#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)]
131pub struct CreateWalletArguments {
132    /// Wallet name
133    pub name: String,
134    /// Load on startup
135    pub load_on_startup: Option<bool>,
136}
137
138/// Serializes the optional [`Amount`] into BTC.
139fn serialize_option_bitcoin<S>(amount: &Option<Amount>, serializer: S) -> Result<S::Ok, S::Error>
140where
141    S: Serializer,
142{
143    match amount {
144        Some(amt) => serializer.serialize_some(&amt.to_btc()),
145        None => serializer.serialize_none(),
146    }
147}
148
149/// Deserializes the transaction id string into proper [`Txid`]s.
150fn deserialize_txid<'d, D>(deserializer: D) -> Result<Txid, D::Error>
151where
152    D: Deserializer<'d>,
153{
154    struct TxidVisitor;
155
156    impl Visitor<'_> for TxidVisitor {
157        type Value = Txid;
158
159        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
160            write!(formatter, "a transaction id string expected")
161        }
162
163        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
164        where
165            E: de::Error,
166        {
167            let txid = v.parse::<Txid>().expect("invalid txid");
168
169            Ok(txid)
170        }
171    }
172    deserializer.deserialize_any(TxidVisitor)
173}
174
175/// Signature hash types for Bitcoin transactions.
176///
177/// These types specify which parts of a transaction are included in the signature
178/// hash calculation when signing transaction inputs. Used with wallet signing
179/// operations like `walletprocesspsbt`.
180///
181/// # Note
182///
183/// These correspond to the SIGHASH flags defined in Bitcoin's script system
184/// and BIP 143 (witness transaction digest).
185#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
186#[serde(rename_all = "UPPERCASE")]
187pub enum SighashType {
188    /// Use the default signature hash type (equivalent to SIGHASH_ALL).
189    Default,
190
191    /// Sign all inputs and all outputs of the transaction.
192    ///
193    /// This is the most common and secure signature type, ensuring the entire
194    /// transaction structure cannot be modified after signing.
195    All,
196
197    /// Sign all inputs but no outputs.
198    ///
199    /// Allows outputs to be modified after signing, useful for donation scenarios
200    /// where the exact destination amounts can be adjusted.
201    None,
202
203    /// Sign all inputs and the output with the same index as this input.
204    ///
205    /// Used in scenarios where multiple parties contribute inputs and want to
206    /// ensure their corresponding output is protected.
207    Single,
208
209    /// Combination of SIGHASH_ALL with ANYONECANPAY flag.
210    ///
211    /// Signs all outputs but only this specific input, allowing other inputs
212    /// to be added or removed. Useful for crowdfunding transactions.
213    #[serde(rename = "ALL|ANYONECANPAY")]
214    AllPlusAnyoneCanPay,
215
216    /// Combination of SIGHASH_NONE with ANYONECANPAY flag.
217    ///
218    /// Signs only this specific input with no outputs committed, providing
219    /// maximum flexibility for transaction modification.
220    #[serde(rename = "NONE|ANYONECANPAY")]
221    NonePlusAnyoneCanPay,
222
223    /// Combination of SIGHASH_SINGLE with ANYONECANPAY flag.
224    ///
225    /// Signs only this input and its corresponding output, allowing other
226    /// inputs and outputs to be modified independently.
227    #[serde(rename = "SINGLE|ANYONECANPAY")]
228    SinglePlusAnyoneCanPay,
229}
230
231/// Options for creating a funded PSBT with wallet inputs.
232///
233/// Used with `wallet_create_funded_psbt` to control funding behavior,
234/// fee estimation, and transaction policies when the wallet automatically
235/// selects inputs to fund the specified outputs.
236///
237/// # Note
238///
239/// All fields are optional and will use Bitcoin Core defaults if not specified.
240/// Fee rate takes precedence over confirmation target if both are provided.
241#[derive(Clone, Debug, PartialEq, Serialize, Default)]
242pub struct WalletCreateFundedPsbtOptions {
243    /// Fee rate in sat/vB (satoshis per virtual byte) for the transaction.
244    ///
245    /// If specified, this overrides the `conf_target` parameter for fee estimation.
246    /// Must be a positive value representing the desired fee density.
247    #[serde(default, rename = "fee_rate", skip_serializing_if = "Option::is_none")]
248    pub fee_rate: Option<f64>,
249
250    /// Whether to lock the selected UTXOs to prevent them from being spent by other transactions.
251    ///
252    /// When `true`, the wallet will temporarily lock the selected unspent outputs
253    /// until the transaction is broadcast or manually unlocked. Default is `false`.
254    #[serde(
255        default,
256        rename = "lockUnspents",
257        skip_serializing_if = "Option::is_none"
258    )]
259    pub lock_unspents: Option<bool>,
260
261    /// Target number of confirmations for automatic fee estimation.
262    ///
263    /// Represents the desired number of blocks within which the transaction should
264    /// be confirmed. Higher values result in lower fees but longer confirmation times.
265    /// Ignored if `fee_rate` is specified.
266    #[serde(
267        default,
268        rename = "conf_target",
269        skip_serializing_if = "Option::is_none"
270    )]
271    pub conf_target: Option<u16>,
272
273    /// Whether the transaction should be BIP-125 opt-in Replace-By-Fee (RBF) enabled.
274    ///
275    /// When `true`, allows the transaction to be replaced with a higher-fee version
276    /// before confirmation. Useful for fee bumping if the initial fee proves insufficient.
277    #[serde(
278        default,
279        rename = "replaceable",
280        skip_serializing_if = "Option::is_none"
281    )]
282    pub replaceable: Option<bool>,
283}
284
285/// Query options for filtering unspent transaction outputs.
286///
287/// Used with `list_unspent` to apply additional filtering criteria
288/// beyond confirmation counts and addresses, allowing precise UTXO selection
289/// based on amount ranges and result limits.
290///
291/// # Note
292///
293/// All fields are optional and can be combined. UTXOs must satisfy all
294/// specified criteria to be included in the results.
295#[derive(Clone, Debug, PartialEq, Serialize)]
296#[serde(rename_all = "camelCase")]
297pub struct ListUnspentQueryOptions {
298    /// Minimum amount that UTXOs must have to be included.
299    ///
300    /// Only unspent outputs with a value greater than or equal to this amount
301    /// will be returned. Useful for filtering out dust or very small UTXOs.
302    #[serde(serialize_with = "serialize_option_bitcoin")]
303    pub minimum_amount: Option<Amount>,
304
305    /// Maximum amount that UTXOs can have to be included.
306    ///
307    /// Only unspent outputs with a value less than or equal to this amount
308    /// will be returned. Useful for finding smaller UTXOs or avoiding large ones.
309    #[serde(serialize_with = "serialize_option_bitcoin")]
310    pub maximum_amount: Option<Amount>,
311
312    /// Maximum number of UTXOs to return in the result set.
313    ///
314    /// Limits the total number of unspent outputs returned, regardless of how many
315    /// match the other criteria. Useful for pagination or limiting response size.
316    pub maximum_count: Option<u32>,
317}
318
319/// Options for psbtbumpfee RPC method.
320#[derive(Clone, Debug, Default, PartialEq, Serialize)]
321pub struct PsbtBumpFeeOptions {
322    /// Confirmation target in blocks.
323    #[serde(skip_serializing_if = "Option::is_none")]
324    pub conf_target: Option<u16>,
325
326    /// Fee rate in sat/vB.
327    #[serde(skip_serializing_if = "Option::is_none")]
328    pub fee_rate: Option<FeeRate>,
329
330    /// Whether the new transaction should be BIP-125 replaceable.
331    #[serde(skip_serializing_if = "Option::is_none")]
332    pub replaceable: Option<bool>,
333
334    /// Fee estimate mode ("unset", "economical", "conservative").
335    #[serde(skip_serializing_if = "Option::is_none")]
336    pub estimate_mode: Option<String>,
337
338    /// New transaction outputs to replace the existing ones.
339    #[serde(skip_serializing_if = "Option::is_none")]
340    pub outputs: Option<Vec<CreateRawTransactionOutput>>,
341
342    /// Index of the change output to recycle from the original transaction.
343    #[serde(skip_serializing_if = "Option::is_none")]
344    pub original_change_index: Option<u32>,
345}