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}