blockchain_client/
traits.rs1use async_trait::async_trait;
2
3use crate::error::Result;
4use crate::types::{
5 AddressValidation, BlockchainInfo, RawTransaction, ReceivedByAddress, TransactionListItem, Utxo,
6};
7
8#[async_trait]
9pub trait BlockchainClient: Send + Sync {
10 async fn get_blockchain_info(&self) -> Result<BlockchainInfo>;
11
12 async fn get_raw_transaction(&self, txid: &str, verbose: bool) -> Result<RawTransaction> {
13 self.get_raw_transaction_with_block(txid, verbose, None)
14 .await
15 }
16
17 async fn get_raw_transaction_with_block(
18 &self,
19 txid: &str,
20 verbose: bool,
21 blockhash: Option<&str>,
22 ) -> Result<RawTransaction>;
23
24 async fn list_unspent(
25 &self,
26 min_conf: Option<u32>,
27 max_conf: Option<u32>,
28 addresses: Option<&[String]>,
29 ) -> Result<Vec<Utxo>>;
30
31 async fn list_transactions(
32 &self,
33 label: Option<&str>,
34 count: Option<usize>,
35 skip: Option<usize>,
36 include_watchonly: bool,
37 ) -> Result<Vec<TransactionListItem>>;
38
39 async fn get_received_by_address(&self, address: &str, min_conf: Option<u32>) -> Result<f64>;
40
41 async fn list_received_by_address(
42 &self,
43 min_conf: Option<u32>,
44 include_empty: bool,
45 include_watchonly: bool,
46 ) -> Result<Vec<ReceivedByAddress>>;
47
48 async fn is_address_watched(&self, address: &str) -> Result<bool>;
49
50 async fn import_address(&self, address: &str, label: Option<&str>, rescan: bool)
51 -> Result<()>;
52
53 async fn validate_address(&self, address: &str) -> Result<AddressValidation>;
54
55 async fn get_transaction(&self, txid: &str) -> Result<serde_json::Value>;
56
57 async fn get_block_count(&self) -> Result<u64>;
58
59 async fn get_best_block_hash(&self) -> Result<String>;
60}
61
62#[derive(Debug, Clone, Copy)]
63pub struct PaginationParams {
64 pub skip: usize,
65 pub count: usize,
66}
67
68#[async_trait]
69pub trait PaginatedBlockchainClient: BlockchainClient {
70 async fn list_transactions_paginated(
71 &self,
72 params: PaginationParams,
73 include_watchonly: bool,
74 ) -> Result<Vec<TransactionListItem>> {
75 let mut all = Vec::new();
76 let mut skip = params.skip;
77 let count = params.count;
78
79 loop {
80 let batch = self
81 .list_transactions(None, Some(count), Some(skip), include_watchonly)
82 .await?;
83
84 let batch_len = batch.len();
85 if batch_len == 0 {
86 break;
87 }
88
89 all.extend(batch);
90 skip += batch_len;
91
92 if batch_len < count {
93 break;
94 }
95 }
96
97 Ok(all)
98 }
99}
100
101impl<T> PaginatedBlockchainClient for T where T: BlockchainClient + ?Sized {}