breez_sdk_spark/chain/
mod.rs1use std::sync::Arc;
2
3use platform_utils::{DefaultHttpClient, HttpClient};
4use serde::{Deserialize, Serialize};
5use thiserror::Error;
6
7use crate::{
8 Credentials, Network,
9 chain::rest_client::{BasicAuth, ChainApiType, RestClientChainService},
10};
11
12pub mod rest_client;
13
14#[derive(Debug, Error, Clone)]
15#[cfg_attr(feature = "uniffi", derive(uniffi::Error))]
16pub enum ChainServiceError {
17 #[error("Invalid address: {0}")]
18 InvalidAddress(String),
19 #[error("Service connectivity: {0}")]
20 ServiceConnectivity(String),
21 #[error("Generic: {0}")]
22 Generic(String),
23}
24
25impl From<platform_utils::HttpError> for ChainServiceError {
26 fn from(value: platform_utils::HttpError) -> Self {
27 ChainServiceError::ServiceConnectivity(value.to_string())
28 }
29}
30
31impl From<bitcoin::address::ParseError> for ChainServiceError {
32 fn from(value: bitcoin::address::ParseError) -> Self {
33 ChainServiceError::InvalidAddress(value.to_string())
34 }
35}
36
37#[cfg_attr(feature = "uniffi", uniffi::export(with_foreign))]
38#[macros::async_trait]
39pub trait BitcoinChainService: Send + Sync {
40 async fn get_address_utxos(&self, address: String) -> Result<Vec<Utxo>, ChainServiceError>;
41 async fn get_transaction_status(&self, txid: String) -> Result<TxStatus, ChainServiceError>;
42 async fn get_transaction_hex(&self, txid: String) -> Result<String, ChainServiceError>;
43 async fn broadcast_transaction(&self, tx: String) -> Result<(), ChainServiceError>;
44 async fn recommended_fees(&self) -> Result<RecommendedFees, ChainServiceError>;
45}
46
47#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)]
48#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
49pub struct TxStatus {
50 pub confirmed: bool,
51 pub block_height: Option<u32>,
52 pub block_time: Option<u64>,
53}
54
55#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)]
56#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
57pub struct Utxo {
58 pub txid: String,
59 pub vout: u32,
60 pub value: u64,
61 pub status: TxStatus,
62}
63
64#[derive(Deserialize, Serialize, Clone, Debug, PartialEq, Eq)]
65#[cfg_attr(feature = "uniffi", derive(uniffi::Record))]
66pub struct RecommendedFees {
67 pub fastest_fee: u64,
68 pub half_hour_fee: u64,
69 pub hour_fee: u64,
70 pub economy_fee: u64,
71 pub minimum_fee: u64,
72}
73
74#[cfg_attr(feature = "uniffi", uniffi::export(async_runtime = "tokio"))]
84#[must_use]
85pub async fn new_rest_chain_service(
86 url: String,
87 network: Network,
88 api_type: ChainApiType,
89 credentials: Option<Credentials>,
90) -> Arc<dyn BitcoinChainService> {
91 let http_client: Arc<dyn HttpClient> = Arc::new(DefaultHttpClient::default());
92 Arc::new(RestClientChainService::new(
93 url,
94 network,
95 5,
96 http_client,
97 credentials.map(|c| BasicAuth::new(c.username, c.password)),
98 api_type,
99 ))
100}