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 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}