1use super::types::ScriptHash;
2use miniscript::bitcoin::Txid;
3use miniscript::serde::{ser::SerializeSeq, Deserialize, Serialize, Serializer};
4
5#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
6#[serde(untagged)]
7pub enum VersionKind {
8 Single(String),
9 MinMax(String, String),
10}
11
12#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
13#[serde(untagged)]
14pub enum TxGetArgs {
15 Txid((Txid,)),
16 TxidVerbose(Txid, bool),
17}
18
19impl From<&TxGetArgs> for (Txid, bool) {
20 fn from(args: &TxGetArgs) -> Self {
21 match args {
22 TxGetArgs::Txid((txid,)) => (*txid, false),
23 TxGetArgs::TxidVerbose(txid, verbose) => (*txid, *verbose),
24 }
25 }
26}
27
28#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
29#[serde(untagged)]
30pub enum Params {
31 #[serde(serialize_with = "default")]
32 None,
33 BlockHeader((usize ,)),
38 BlockHeaders(
40 (
41 usize, usize, ),
45 ),
46 TransactionBroadcast((String,)),
47 EstimateFee((u16,)),
48 ScriptHashGetBalance((ScriptHash,)),
49 ScriptHashGetHistory((ScriptHash,)),
50 ScriptHashGetMempool((ScriptHash,)),
51 ScriptHashListUnspent((ScriptHash,)),
52 ScriptHashSubscribe((ScriptHash,)),
53 ScriptHashUnsubscribe((ScriptHash,)),
54 TransactionGet(TxGetArgs),
55 TransactionGetMerkle((Txid, usize)),
56 TransactionFromPosition(
57 (
58 usize, usize, bool, ),
62 ),
63 Version((String, VersionKind)),
64}
65
66fn default<S>(serializer: S) -> Result<S::Ok, S::Error>
67where
68 S: Serializer,
69{
70 let sequence = serializer.serialize_seq(Some(0))?;
72 sequence.end()
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78 use miniscript::bitcoin::{hex::FromHex, OutPoint, Script};
79 use std::str::FromStr;
80
81 macro_rules! json {
82 ($value:expr, $str:expr) => {{
83 use serde_json::to_string;
84
85 let json_str = to_string(&$value).unwrap();
86 assert_eq!(
89 json_str, $str,
90 "Debug and JSON representations do not match"
91 );
92 }};
93 }
94
95 #[test]
96 fn params() {
97 assert_eq!(serde_json::to_string(&Params::None).unwrap(), "[]");
98 assert_eq!(
99 serde_json::to_string(&Params::BlockHeader((0,))).unwrap(),
100 "[0]"
101 );
102 }
103
104 #[test]
105 fn tx_get_args() {
106 let outpoint = OutPoint::from_str(
107 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:42",
108 )
109 .unwrap();
110 let arg1 = TxGetArgs::Txid((outpoint.txid,));
111
112 let arg2 = TxGetArgs::TxidVerbose(outpoint.txid, true);
113
114 assert_eq!(
115 arg1,
116 serde_json::from_str(
117 r#"["5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456"]"#
118 )
119 .unwrap()
120 );
121 assert_eq!(
122 arg2,
123 serde_json::from_str(
124 r#"["5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456",true]"#
125 )
126 .unwrap()
127 );
128 }
129
130 #[test]
131 fn from_tx_get_arg() {
132 let outpoint = OutPoint::from_str(
133 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:42",
134 )
135 .unwrap();
136 let arg1 = TxGetArgs::Txid((outpoint.txid,));
137
138 let arg2 = TxGetArgs::TxidVerbose(outpoint.txid, true);
139
140 let (txid, verbose): (Txid, bool) = (&arg1).into();
141 assert_eq!(txid, outpoint.txid);
142 assert!(!verbose);
143
144 let (txid, verbose): (Txid, bool) = (&arg2).into();
145 assert_eq!(txid, outpoint.txid);
146 assert!(verbose);
147 }
148
149 #[test]
150 fn version_kind() {
151 let version1 = VersionKind::Single("1.4".into());
152 let version2 = VersionKind::MinMax("1.1".into(), "1.4".into());
153
154 assert_eq!(version1, serde_json::from_str(r#""1.4""#).unwrap());
155 assert_eq!(version2, serde_json::from_str(r#"["1.1","1.4"]"#).unwrap());
156 }
157
158 #[test]
159 fn params_() {
160 json!(Params::None, "[]");
161 json!(Params::BlockHeader((12,)), "[12]");
162 json!(Params::BlockHeaders((12, 34)), "[12,34]");
163 json!(Params::TransactionBroadcast(("toto".into(),)), "[\"toto\"]");
164 json!(Params::EstimateFee((2,)), "[2]");
165
166 let raw_script = Vec::from_hex("0014992f8cc4f6d284acac5f603e233592b566c04b2a").unwrap();
167 let script = Script::from_bytes(raw_script.as_slice());
168 let sh = ScriptHash::new(script);
169 json!(
170 Params::ScriptHashGetBalance((sh,)),
171 "[\"8b2154ad6733677e53c2b9fd12d527bf292ace4df41281755ce1ecabe456fce5\"]"
172 );
173 json!(
174 Params::ScriptHashGetHistory((sh,)),
175 "[\"8b2154ad6733677e53c2b9fd12d527bf292ace4df41281755ce1ecabe456fce5\"]"
176 );
177 json!(
178 Params::ScriptHashGetMempool((sh,)),
179 "[\"8b2154ad6733677e53c2b9fd12d527bf292ace4df41281755ce1ecabe456fce5\"]"
180 );
181 json!(
182 Params::ScriptHashListUnspent((sh,)),
183 "[\"8b2154ad6733677e53c2b9fd12d527bf292ace4df41281755ce1ecabe456fce5\"]"
184 );
185 json!(
186 Params::ScriptHashSubscribe((sh,)),
187 "[\"8b2154ad6733677e53c2b9fd12d527bf292ace4df41281755ce1ecabe456fce5\"]"
188 );
189 json!(
190 Params::ScriptHashUnsubscribe((sh,)),
191 "[\"8b2154ad6733677e53c2b9fd12d527bf292ace4df41281755ce1ecabe456fce5\"]"
192 );
193
194 let outpoint = OutPoint::from_str(
195 "5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456:42",
196 )
197 .unwrap();
198 let arg1 = TxGetArgs::Txid((outpoint.txid,));
199
200 let arg2 = TxGetArgs::TxidVerbose(outpoint.txid, true);
201
202 json!(
203 Params::TransactionGet(arg1),
204 "[\"5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456\"]"
205 );
206 json!(
207 Params::TransactionGet(arg2),
208 "[\"5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456\",true]"
209 );
210 json!(
211 Params::TransactionGetMerkle((outpoint.txid, 3)),
212 "[\"5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456\",3]"
213 );
214 json!(
215 Params::TransactionFromPosition((1, 2, false)),
216 "[1,2,false]"
217 );
218 json!(
219 Params::Version(("last".into(), VersionKind::Single("1.4.into())".into()))),
220 "[\"last\",\"1.4.into())\"]"
221 );
222 }
223}