boltz_client/network/
mod.rs

1use core::fmt;
2use std::str::FromStr;
3
4use crate::error::Error;
5use elements::{AddressParams, AssetId};
6
7#[cfg(feature = "electrum")]
8#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
9pub mod electrum;
10
11#[cfg(feature = "esplora")]
12pub mod esplora;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub enum Chain {
16    Bitcoin(BitcoinChain),
17    Liquid(LiquidChain),
18}
19
20impl fmt::Display for Chain {
21    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22        match self {
23            Chain::Bitcoin(_) => write!(f, "BTC"),
24            Chain::Liquid(_) => write!(f, "L-BTC"),
25        }
26    }
27}
28
29impl From<BitcoinChain> for Chain {
30    fn from(value: BitcoinChain) -> Self {
31        Chain::Bitcoin(value)
32    }
33}
34
35impl From<LiquidChain> for Chain {
36    fn from(value: LiquidChain) -> Self {
37        Chain::Liquid(value)
38    }
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub enum BitcoinChain {
43    Bitcoin,
44    BitcoinTestnet,
45    BitcoinRegtest,
46}
47
48impl From<BitcoinChain> for bitcoin::Network {
49    fn from(value: BitcoinChain) -> Self {
50        match value {
51            BitcoinChain::Bitcoin => Self::Bitcoin,
52            BitcoinChain::BitcoinTestnet => Self::Testnet,
53            BitcoinChain::BitcoinRegtest => Self::Regtest,
54        }
55    }
56}
57
58#[derive(Debug, Clone, Copy, PartialEq, Eq)]
59pub enum LiquidChain {
60    Liquid,
61    LiquidTestnet,
62    LiquidRegtest,
63}
64
65const ASSET_ID_REGTEST: &str = "5ac9f65c0efcc4775e0baec4ec03abdde22473cd3cf33c0419ca290e0751b225";
66const ASSET_ID_TESTNET: &str = "144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49";
67
68impl LiquidChain {
69    pub fn bitcoin(self) -> AssetId {
70        match self {
71            LiquidChain::Liquid => AssetId::LIQUID_BTC,
72            LiquidChain::LiquidTestnet => AssetId::from_str(ASSET_ID_TESTNET).unwrap(),
73            LiquidChain::LiquidRegtest => AssetId::from_str(ASSET_ID_REGTEST).unwrap(),
74        }
75    }
76}
77
78impl From<LiquidChain> for &'static AddressParams {
79    fn from(value: LiquidChain) -> Self {
80        match value {
81            LiquidChain::Liquid => &AddressParams::LIQUID,
82            LiquidChain::LiquidTestnet => &AddressParams::LIQUID_TESTNET,
83            LiquidChain::LiquidRegtest => &AddressParams::ELEMENTS,
84        }
85    }
86}
87
88#[derive(serde::Deserialize, serde::Serialize, Debug, Clone, Copy, PartialEq, Eq)]
89pub enum Network {
90    Mainnet,
91    Testnet,
92    Regtest,
93}
94
95impl From<Network> for BitcoinChain {
96    fn from(value: Network) -> Self {
97        match value {
98            Network::Mainnet => BitcoinChain::Bitcoin,
99            Network::Testnet => BitcoinChain::BitcoinTestnet,
100            Network::Regtest => BitcoinChain::BitcoinRegtest,
101        }
102    }
103}
104
105impl From<Network> for LiquidChain {
106    fn from(value: Network) -> Self {
107        match value {
108            Network::Mainnet => LiquidChain::Liquid,
109            Network::Testnet => LiquidChain::LiquidTestnet,
110            Network::Regtest => LiquidChain::LiquidRegtest,
111        }
112    }
113}
114
115impl From<Network> for bitcoin::Network {
116    fn from(value: Network) -> Self {
117        match value {
118            Network::Mainnet => Self::Bitcoin,
119            Network::Testnet => Self::Testnet,
120            Network::Regtest => Self::Regtest,
121        }
122    }
123}
124
125impl From<Chain> for Network {
126    fn from(value: Chain) -> Self {
127        match value {
128            Chain::Bitcoin(_) => Network::Mainnet,
129            Chain::Liquid(_) => Network::Mainnet,
130        }
131    }
132}
133
134#[macros::async_trait]
135pub trait BitcoinClient: Send + Sync {
136    async fn get_address_balance(&self, address: &bitcoin::Address) -> Result<(u64, i64), Error>;
137
138    async fn get_address_utxos(
139        &self,
140        address: &bitcoin::Address,
141    ) -> Result<Vec<(bitcoin::OutPoint, bitcoin::TxOut)>, Error>;
142
143    async fn broadcast_tx(&self, signed_tx: &bitcoin::Transaction) -> Result<bitcoin::Txid, Error>;
144
145    fn network(&self) -> BitcoinChain;
146}
147
148#[macros::async_trait]
149pub trait LiquidClient: Send + Sync {
150    async fn get_address_utxo(
151        &self,
152        address: &elements::Address,
153    ) -> Result<Option<(elements::OutPoint, elements::TxOut)>, Error>;
154
155    async fn get_genesis_hash(&self) -> Result<elements::BlockHash, Error>;
156
157    async fn broadcast_tx(&self, signed_tx: &elements::Transaction) -> Result<String, Error>;
158
159    fn network(&self) -> LiquidChain;
160}