1pub use {
2 address::{AddressData, AddressTxOut},
3 block::Block,
4 event::{Event, EventType, Location},
5 inscription_id::InscriptionId,
6 mempool_entry::{MempoolEntry, MempoolEntryFee},
7 outpoint::SerializedOutPoint,
8 pagination::{Pagination, PaginationResponse},
9 rune::{MintResponse, RuneAmount, RuneResponse},
10 stats::{BlockTip, Status},
11 subscription::{Subscription, TcpSubscriptionRequest},
12 transaction::{Transaction, TransactionStatus},
13 tx_in::TxIn,
14 tx_out::{SpenderReference, SpentStatus, TxOut},
15 txid::SerializedTxid,
16};
17
18mod address;
19mod block;
20mod event;
21mod inscription_id;
22mod mempool_entry;
23mod outpoint;
24mod pagination;
25pub mod query;
26mod rune;
27mod rune_id;
28mod rune_type;
29mod serde_str;
30mod spaced_rune;
31mod stats;
32mod subscription;
33mod transaction;
34mod tx_in;
35mod tx_out;
36mod txid;
37
38pub use ordinals::{Artifact, Cenotaph, Edict, Etching, Runestone};
40
41pub use crate::rune_id::RuneId;
42pub use crate::rune_type::Rune;
43pub use crate::spaced_rune::SpacedRune;
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48 use bitcoin::{hashes::Hash, BlockHash, ScriptBuf};
49 use borsh::{BorshDeserialize, BorshSerialize};
50 use serde_json;
51 use std::str::FromStr;
52
53 fn test_borsh_roundtrip<T>(original: &T) -> T
55 where
56 T: BorshSerialize + BorshDeserialize + std::fmt::Debug + PartialEq,
57 {
58 let serialized = borsh::to_vec(original).expect("Failed to serialize");
59 let deserialized = borsh::from_slice(&serialized).expect("Failed to deserialize");
60 assert_eq!(original, &deserialized, "Borsh roundtrip failed");
61 deserialized
62 }
63
64 fn test_serde_roundtrip<T>(original: &T) -> T
66 where
67 T: serde::Serialize + for<'de> serde::Deserialize<'de> + std::fmt::Debug + PartialEq,
68 {
69 let serialized = serde_json::to_string(original).expect("Failed to serialize");
70 let deserialized = serde_json::from_str(&serialized).expect("Failed to deserialize");
71 assert_eq!(original, &deserialized, "Serde roundtrip failed");
72 deserialized
73 }
74
75 #[test]
76 fn test_serialized_txid() {
77 let txid_bytes = [1u8; 32];
78 let original = SerializedTxid::from(txid_bytes);
79
80 test_borsh_roundtrip(&original);
82
83 test_serde_roundtrip(&original);
85
86 let hex_str = original.to_string();
88 let from_str = SerializedTxid::from_str(&hex_str).expect("Failed to parse from string");
89 assert_eq!(original, from_str);
90 }
91
92 #[test]
93 fn test_rune_amount() {
94 let rune_id = RuneId::new(840000, 1);
95 let original = RuneAmount {
96 rune_id,
97 amount: 1000000000000000000u128,
98 };
99
100 test_borsh_roundtrip(&original);
102
103 test_serde_roundtrip(&original);
105 }
106
107 #[test]
108 fn test_spender_reference() {
109 let txid = SerializedTxid::from([42u8; 32]);
110 let original = SpenderReference { txid, vin: 3 };
111
112 test_borsh_roundtrip(&original);
114
115 test_serde_roundtrip(&original);
117 }
118
119 #[test]
120 fn test_spent_status() {
121 let unspent = SpentStatus::Unspent;
123 test_borsh_roundtrip(&unspent);
124 test_serde_roundtrip(&unspent);
125
126 let txid = SerializedTxid::from([99u8; 32]);
128 let spender_ref = SpenderReference { txid, vin: 2 };
129 let spent = SpentStatus::Spent(spender_ref);
130 test_borsh_roundtrip(&spent);
131 test_serde_roundtrip(&spent);
132 }
133
134 #[test]
135 fn test_tx_out_entry() {
136 let rune_id = RuneId::new(840000, 1);
137 let rune_amount = RuneAmount {
138 rune_id,
139 amount: 500000000000000000u128,
140 };
141
142 let original = TxOut {
143 runes: vec![rune_amount.clone()],
144 risky_runes: vec![rune_amount],
145 value: 50000,
146 spent: SpentStatus::Unspent,
147 script_pubkey: ScriptBuf::new(),
148 };
149
150 test_borsh_roundtrip(&original);
152
153 test_serde_roundtrip(&original);
155 }
156
157 #[test]
158 fn test_transaction_tx_out() {
159 let script = ScriptBuf::from_bytes(vec![0x76, 0xa9, 0x14]); let rune_id = RuneId::new(840000, 1);
161 let rune_amount = RuneAmount {
162 rune_id,
163 amount: 100000000000000000u128,
164 };
165
166 let original = TxOut {
167 value: 100000,
168 script_pubkey: script,
169 runes: vec![rune_amount.clone()],
170 risky_runes: vec![rune_amount],
171 spent: SpentStatus::Unspent,
172 };
173
174 test_borsh_roundtrip(&original);
176
177 test_serde_roundtrip(&original);
179 }
180
181 #[test]
182 fn test_transaction_status() {
183 let unconfirmed = TransactionStatus::unconfirmed();
185 test_serde_roundtrip(&unconfirmed);
186
187 let block_hash = BlockHash::from_raw_hash(Hash::from_slice(&[1u8; 32]).unwrap());
189 let confirmed = TransactionStatus::confirmed(840000, block_hash);
190 test_serde_roundtrip(&confirmed);
191 }
192
193 #[test]
194 fn test_serialized_outpoint() {
195 let txid_bytes = [5u8; 32];
196 let original = SerializedOutPoint::new(&txid_bytes, 1);
197
198 test_borsh_roundtrip(&original);
200
201 test_serde_roundtrip(&original);
203
204 assert_eq!(original.txid(), &txid_bytes);
206 assert_eq!(original.vout(), 1);
207 }
208
209 #[test]
210 fn test_mempool_entry_fee() {
211 let original = MempoolEntryFee {
212 base: 1000,
213 descendant: 2000,
214 ancestor: 3000,
215 };
216
217 test_borsh_roundtrip(&original);
219
220 test_serde_roundtrip(&original);
222 }
223
224 #[test]
225 fn test_mempool_entry() {
226 let txid = SerializedTxid::from([7u8; 32]);
227 let fees = MempoolEntryFee {
228 base: 1000,
229 descendant: 2000,
230 ancestor: 3000,
231 };
232
233 let original = MempoolEntry {
234 vsize: 250,
235 weight: Some(1000),
236 descendant_count: 1,
237 descendant_size: 250,
238 ancestor_count: 1,
239 ancestor_size: 250,
240 fees,
241 depends: vec![txid.clone()],
242 spent_by: vec![txid],
243 };
244
245 test_borsh_roundtrip(&original);
247
248 test_serde_roundtrip(&original);
250 }
251
252 #[test]
253 fn test_edge_cases() {
254 let empty_tx_out = TxOut {
256 runes: vec![],
257 risky_runes: vec![],
258 value: 0,
259 spent: SpentStatus::Unspent,
260 script_pubkey: ScriptBuf::new(),
261 };
262 test_borsh_roundtrip(&empty_tx_out);
263 test_serde_roundtrip(&empty_tx_out);
264
265 let mempool_no_weight = MempoolEntry {
267 vsize: 250,
268 weight: None,
269 descendant_count: 1,
270 descendant_size: 250,
271 ancestor_count: 1,
272 ancestor_size: 250,
273 fees: MempoolEntryFee {
274 base: 1000,
275 descendant: 2000,
276 ancestor: 3000,
277 },
278 depends: vec![],
279 spent_by: vec![],
280 };
281 test_borsh_roundtrip(&mempool_no_weight);
282 test_serde_roundtrip(&mempool_no_weight);
283
284 let max_rune_amount = RuneAmount {
286 rune_id: RuneId::new(u64::MAX, u32::MAX),
287 amount: u128::MAX,
288 };
289 test_borsh_roundtrip(&max_rune_amount);
290 test_serde_roundtrip(&max_rune_amount);
291 }
292
293 #[test]
294 fn test_complex_nested_structures() {
295 let rune_id1 = RuneId::new(840000, 1);
297 let rune_id2 = RuneId::new(840001, 2);
298
299 let rune_amounts = vec![
300 RuneAmount {
301 rune_id: rune_id1,
302 amount: 1000000000000000000u128,
303 },
304 RuneAmount {
305 rune_id: rune_id2,
306 amount: 2000000000000000000u128,
307 },
308 ];
309
310 let spender_ref = SpenderReference {
311 txid: SerializedTxid::from([255u8; 32]),
312 vin: 0,
313 };
314
315 let complex_tx_out = TxOut {
316 value: 5000000,
317 script_pubkey: ScriptBuf::from_bytes(vec![0x00, 0x14]), runes: rune_amounts.clone(),
319 risky_runes: rune_amounts,
320 spent: SpentStatus::Spent(spender_ref),
321 };
322
323 test_borsh_roundtrip(&complex_tx_out);
324 test_serde_roundtrip(&complex_tx_out);
325 }
326
327 #[test]
328 fn test_serialization_consistency() {
329 let rune_id = RuneId::new(840000, 1);
332 let original = RuneAmount {
333 rune_id,
334 amount: 1000000000000000000u128,
335 };
336
337 let borsh_serialized = borsh::to_vec(&original).unwrap();
338 let borsh_deserialized: RuneAmount = borsh::from_slice(&borsh_serialized).unwrap();
339
340 let serde_serialized = serde_json::to_string(&original).unwrap();
341 let serde_deserialized: RuneAmount = serde_json::from_str(&serde_serialized).unwrap();
342
343 assert_eq!(borsh_deserialized, serde_deserialized);
345 assert_eq!(original, borsh_deserialized);
346 assert_eq!(original, serde_deserialized);
347 }
348}