electrum_c/
response.rs

1use bitcoin::{
2    absolute,
3    hashes::{Hash, HashEngine},
4    Amount,
5};
6
7use crate::DoubleSHA;
8
9#[derive(Debug, Clone, serde::Deserialize, PartialEq, Eq)]
10#[serde(transparent)]
11pub struct HeaderResp {
12    #[serde(deserialize_with = "crate::custom_serde::from_consensus_hex")]
13    pub header: bitcoin::block::Header,
14}
15
16#[derive(Debug, Clone, serde::Deserialize, PartialEq, Eq)]
17pub struct HeaderWithProofResp {
18    pub branch: Vec<DoubleSHA>,
19    #[serde(deserialize_with = "crate::custom_serde::from_consensus_hex")]
20    pub header: bitcoin::block::Header,
21    pub root: DoubleSHA,
22}
23
24#[derive(Debug, Clone, serde::Deserialize)]
25pub struct HeadersResp {
26    pub count: usize,
27    #[serde(
28        rename = "hex",
29        deserialize_with = "crate::custom_serde::from_cancat_consensus_hex"
30    )]
31    pub headers: Vec<bitcoin::block::Header>,
32    pub max: usize,
33}
34
35#[derive(Debug, Clone, serde::Deserialize)]
36pub struct HeadersWithCheckpointResp {
37    pub count: usize,
38    #[serde(
39        rename = "hex",
40        deserialize_with = "crate::custom_serde::from_cancat_consensus_hex"
41    )]
42    pub headers: Vec<bitcoin::block::Header>,
43    pub max: usize,
44    pub root: DoubleSHA,
45    pub branch: Vec<DoubleSHA>,
46}
47
48#[derive(Debug, Clone, serde::Deserialize)]
49#[serde(transparent)]
50pub struct EstimateFeeResp {
51    #[serde(deserialize_with = "crate::custom_serde::feerate_opt_from_btc_per_kb")]
52    pub fee_rate: Option<bitcoin::FeeRate>,
53}
54
55#[derive(Debug, Clone, serde::Deserialize)]
56pub struct HeadersSubscribeResp {
57    #[serde(
58        rename = "hex",
59        deserialize_with = "crate::custom_serde::from_consensus_hex"
60    )]
61    pub header: bitcoin::block::Header,
62    pub height: u32,
63}
64
65#[derive(Debug, Clone, serde::Deserialize)]
66#[serde(transparent)]
67pub struct RelayFeeResp {
68    #[serde(deserialize_with = "crate::custom_serde::amount_from_btc")]
69    pub fee: Amount,
70}
71
72#[derive(Debug, Clone, serde::Deserialize)]
73pub struct GetBalanceResp {
74    #[serde(deserialize_with = "crate::custom_serde::amount_from_sats")]
75    pub confirmed: Amount,
76    #[serde(deserialize_with = "crate::custom_serde::amount_from_maybe_negative_sats")]
77    pub unconfirmed: Amount,
78}
79
80#[derive(Debug, Clone, serde::Deserialize)]
81#[serde(untagged)]
82pub enum Tx {
83    Mempool(MempoolTx),
84    Confirmed(ConfirmedTx),
85}
86
87impl Tx {
88    pub fn txid(&self) -> bitcoin::Txid {
89        match self {
90            Tx::Mempool(MempoolTx { txid, .. }) => *txid,
91            Tx::Confirmed(ConfirmedTx { txid, .. }) => *txid,
92        }
93    }
94
95    pub fn confirmation_height(&self) -> Option<absolute::Height> {
96        match self {
97            Tx::Mempool(_) => None,
98            Tx::Confirmed(ConfirmedTx { height, .. }) => Some(*height),
99        }
100    }
101}
102
103#[derive(Debug, Clone, serde::Deserialize)]
104pub struct ConfirmedTx {
105    #[serde(rename = "tx_hash")]
106    pub txid: bitcoin::Txid,
107    pub height: absolute::Height,
108}
109
110#[derive(Debug, Clone, serde::Deserialize)]
111pub struct MempoolTx {
112    #[serde(rename = "tx_hash")]
113    pub txid: bitcoin::Txid,
114    #[serde(deserialize_with = "crate::custom_serde::amount_from_sats")]
115    pub fee: bitcoin::Amount,
116    #[serde(
117        rename = "height",
118        deserialize_with = "crate::custom_serde::all_inputs_confirmed_bool_from_height"
119    )]
120    pub all_inputs_confirmed: bool,
121}
122
123#[derive(Debug, Clone, serde::Deserialize)]
124pub struct Utxo {
125    pub height: absolute::Height,
126    pub tx_pos: usize,
127    #[serde(rename = "tx_hash")]
128    pub txid: bitcoin::Txid,
129    #[serde(deserialize_with = "crate::custom_serde::amount_from_sats")]
130    pub value: bitcoin::Amount,
131}
132
133#[derive(Debug, Clone, serde::Deserialize)]
134#[serde(transparent)]
135pub struct FullTx {
136    #[serde(deserialize_with = "crate::custom_serde::from_consensus_hex")]
137    pub tx: bitcoin::Transaction,
138}
139
140#[derive(Debug, Clone, serde::Deserialize)]
141pub struct TxMerkle {
142    pub block_height: absolute::Height,
143    pub merkle: Vec<DoubleSHA>,
144    pub pos: usize,
145}
146
147impl TxMerkle {
148    /// Returns the merkle root of a [`Header`] which satisfies this proof.
149    pub fn expected_merkle_root(&self, txid: bitcoin::Txid) -> bitcoin::TxMerkleNode {
150        let mut index = self.pos;
151        let mut cur = txid.to_raw_hash();
152        for next_hash in &self.merkle {
153            cur = DoubleSHA::from_engine({
154                let mut engine = DoubleSHA::engine();
155                if index % 2 == 0 {
156                    engine.input(cur.as_ref());
157                    engine.input(next_hash.as_ref());
158                } else {
159                    engine.input(next_hash.as_ref());
160                    engine.input(cur.as_ref());
161                };
162                engine
163            });
164            index /= 2;
165        }
166        cur.into()
167    }
168}
169
170#[derive(Debug, Clone, serde::Deserialize)]
171#[serde(transparent)]
172pub struct TxidFromPos {
173    pub txid: bitcoin::Txid,
174}
175
176#[derive(Debug, Clone, serde::Deserialize)]
177pub struct FeePair {
178    #[serde(deserialize_with = "crate::custom_serde::feerate_from_sat_per_byte")]
179    pub fee_rate: bitcoin::FeeRate,
180    #[serde(deserialize_with = "crate::custom_serde::weight_from_vb")]
181    pub weight: bitcoin::Weight,
182}