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) -> Result<()>;
51
52 async fn validate_address(&self, address: &str) -> Result<AddressValidation>;
53
54 async fn get_transaction(&self, txid: &str) -> Result<serde_json::Value>;
55
56 async fn get_block_count(&self) -> Result<u64>;
57
58 async fn get_best_block_hash(&self) -> Result<String>;
59}
60
61#[derive(Debug, Clone, Copy)]
62pub struct PaginationParams {
63 pub skip: usize,
64 pub count: usize,
65}
66
67#[async_trait]
68pub trait PaginatedBlockchainClient: BlockchainClient {
69 async fn list_transactions_paginated(
70 &self,
71 params: PaginationParams,
72 include_watchonly: bool,
73 ) -> Result<Vec<TransactionListItem>> {
74 let mut all = Vec::new();
75 let mut skip = params.skip;
76 let count = params.count;
77
78 loop {
79 let batch = self
80 .list_transactions(None, Some(count), Some(skip), include_watchonly)
81 .await?;
82
83 let batch_len = batch.len();
84 if batch_len == 0 {
85 break;
86 }
87
88 all.extend(batch);
89 skip += batch_len;
90
91 if batch_len < count {
92 break;
93 }
94 }
95
96 Ok(all)
97 }
98}
99
100impl<T> PaginatedBlockchainClient for T where T: BlockchainClient + ?Sized {}