feat: switch Esplora client url to Breez server instance (#845)

Co-authored-by: Ross Savage <mr.dangeross@googlemail.com>
This commit is contained in:
yse
2025-04-08 10:27:13 +02:00
committed by GitHub
parent 58c94c6105
commit 8a33bb42e6
9 changed files with 86 additions and 34 deletions

4
lib/Cargo.lock generated
View File

@@ -760,7 +760,7 @@ checksum = "829a082bd3761fde7476dc2ed85ca56c11628948460ece621e4f56fef5046567"
[[package]]
name = "boltz-client"
version = "0.3.0"
source = "git+https://github.com/SatoshiPortal/boltz-rust?rev=f78e159fe72e1c357e7830bc08d2b9e42a65362c#f78e159fe72e1c357e7830bc08d2b9e42a65362c"
source = "git+https://github.com/hydra-yse/boltz-rust?rev=b54f181e218d#b54f181e218d6c7d44d7bfd3eabda3681006fbc0"
dependencies = [
"async-trait",
"bip39",
@@ -3182,7 +3182,7 @@ dependencies = [
[[package]]
name = "macros"
version = "0.0.0"
source = "git+https://github.com/SatoshiPortal/boltz-rust?rev=f78e159fe72e1c357e7830bc08d2b9e42a65362c#f78e159fe72e1c357e7830bc08d2b9e42a65362c"
source = "git+https://github.com/hydra-yse/boltz-rust?rev=b54f181e218d#b54f181e218d6c7d44d7bfd3eabda3681006fbc0"
dependencies = [
"proc-macro2",
"quote",

View File

@@ -76,7 +76,7 @@ maybe-sync = { version = "0.1.1", features = ["sync"] }
prost = "^0.11"
tonic = { version = "^0.8", features = ["tls", "tls-webpki-roots"] }
uuid = { version = "1.8.0", features = ["v4"] }
boltz-client = { git = "https://github.com/SatoshiPortal/boltz-rust", rev = "f78e159fe72e1c357e7830bc08d2b9e42a65362c", features = ["electrum"] }
boltz-client = { git = "https://github.com/hydra-yse/boltz-rust", rev = "b54f181e218d", features = ["electrum"] }
rusqlite = { git = "https://github.com/Spxg/rusqlite", rev = "e36644127f31fa6e7ea0999b59432deb4a07f220", features = [
"backup",
"bundled",
@@ -95,7 +95,7 @@ tonic = { version = "0.12", default-features = false, features = [
"codegen",
"prost",
] }
boltz-client = { git = "https://github.com/SatoshiPortal/boltz-rust", rev = "f78e159fe72e1c357e7830bc08d2b9e42a65362c" }
boltz-client = { git = "https://github.com/hydra-yse/boltz-rust", rev = "b54f181e218d" }
rusqlite = { git = "https://github.com/Spxg/rusqlite", rev = "e36644127f31fa6e7ea0999b59432deb4a07f220", features = [
"backup",
"bundled",

View File

@@ -52,7 +52,6 @@ impl EsploraBitcoinChainService {
.timeout(3)
.max_retries(10)
.build_async()?;
let client = self.client.get_or_init(|| client);
Ok(client)
}

View File

@@ -1,16 +1,16 @@
use std::{sync::OnceLock, time::Duration};
use anyhow::{anyhow, Context as _, Result};
use anyhow::{anyhow, bail, Context as _, Result};
use tokio::sync::RwLock;
use tokio_with_wasm::alias as tokio;
use crate::{
elements::{Address, OutPoint, Script, Transaction, Txid},
model::{BlockchainExplorer, Config, Utxo},
model::{BlockchainExplorer, Config, Utxo, BREEZ_LIQUID_ESPLORA_URL},
utils,
};
use log::info;
use log::{error, info};
use lwk_wollet::{
asyncr::EsploraClientBuilder, clients::asyncr::EsploraClient, elements::hex::FromHex as _,
};
@@ -40,10 +40,23 @@ impl EsploraLiquidChainService {
BlockchainExplorer::Esplora {
url,
use_waterfalls,
} => EsploraClientBuilder::new(url, self.config.network.into())
.timeout(3)
.waterfalls(*use_waterfalls)
.build(),
} => {
let mut builder = EsploraClientBuilder::new(url, self.config.network.into());
if url == BREEZ_LIQUID_ESPLORA_URL {
match &self.config.breez_api_key {
Some(api_key) => {
builder = builder
.header("authorization".to_string(), format!("Bearer {api_key}"));
}
None => {
let err = "Cannot start Breez Esplora client: Breez API key is not set";
error!("{err}");
bail!(err)
}
};
}
builder.timeout(3).waterfalls(*use_waterfalls).build()
}
#[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
BlockchainExplorer::Electrum { .. } => {
anyhow::bail!("Cannot start Liquid Esplora chain service without an Esplora url")

View File

@@ -1,4 +1,4 @@
use anyhow::{anyhow, Result};
use anyhow::{anyhow, bail, Result};
use bitcoin::{bip32, ScriptBuf};
use boltz_client::{
boltz::{ChainPair, BOLTZ_MAINNET_URL_V2, BOLTZ_REGTEST, BOLTZ_TESTNET_URL_V2},
@@ -40,6 +40,7 @@ use crate::{
pub const LIQUID_FEE_RATE_SAT_PER_VBYTE: f64 = 0.1;
pub const LIQUID_FEE_RATE_MSAT_PER_VBYTE: f32 = (LIQUID_FEE_RATE_SAT_PER_VBYTE * 1000.0) as f32;
pub const BREEZ_SYNC_SERVICE_URL: &str = "https://datasync.breez.technology";
pub const BREEZ_LIQUID_ESPLORA_URL: &str = "https://lq1.breez.technology/liquid/api";
const SIDESWAP_API_KEY: &str = "97fb6a1dfa37ee6656af92ef79675cc03b8ac4c52e04655f41edbd5af888dcc2";
@@ -128,7 +129,7 @@ impl Config {
pub fn mainnet_esplora(breez_api_key: Option<String>) -> Self {
Config {
liquid_explorer: BlockchainExplorer::Esplora {
url: "https://waterfalls.liquidwebwallet.org/liquid/api".to_string(),
url: BREEZ_LIQUID_ESPLORA_URL.to_string(),
use_waterfalls: true,
},
bitcoin_explorer: BlockchainExplorer::Esplora {
@@ -314,15 +315,18 @@ impl Config {
}
}
pub(crate) fn liquid_chain_service(&self) -> Arc<dyn LiquidChainService> {
match self.liquid_explorer {
BlockchainExplorer::Esplora { .. } => {
Arc::new(EsploraLiquidChainService::new(self.clone()))
pub(crate) fn liquid_chain_service(&self) -> Result<Arc<dyn LiquidChainService>> {
match &self.liquid_explorer {
BlockchainExplorer::Esplora { url, .. } => {
if url == BREEZ_LIQUID_ESPLORA_URL && self.breez_api_key.is_none() {
bail!("Cannot start the Breez Esplora chain service without providing a valid API key. See https://sdk-doc-liquid.breez.technology/guide/getting_started.html#api-key")
}
Ok(Arc::new(EsploraLiquidChainService::new(self.clone())))
}
#[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
BlockchainExplorer::Electrum { .. } => Arc::new(
BlockchainExplorer::Electrum { .. } => Ok(Arc::new(
crate::chain::liquid::electrum::ElectrumLiquidChainService::new(self.clone()),
),
)),
}
}

View File

@@ -221,7 +221,7 @@ impl LiquidSdkBuilder {
let liquid_chain_service: Arc<dyn LiquidChainService> =
match self.liquid_chain_service.clone() {
Some(liquid_chain_service) => liquid_chain_service,
None => self.config.liquid_chain_service(),
None => self.config.liquid_chain_service()?,
};
let onchain_wallet: Arc<dyn OnchainWallet> = match self.onchain_wallet.clone() {

View File

@@ -1,6 +1,6 @@
use crate::{
bitcoin, elements,
model::{BlockchainExplorer, Config},
model::{BlockchainExplorer, Config, BREEZ_LIQUID_ESPLORA_URL},
};
use boltz_client::{
error::Error,
@@ -9,7 +9,9 @@ use boltz_client::{
BitcoinChain, BitcoinClient as BoltzBitcoinClient, LiquidChain,
LiquidClient as BoltzLiquidClient,
},
reqwest,
};
use log::error;
use sdk_macros::async_trait;
const BOLTZ_CONNECTION_TIMEOUT: u8 = 100;
@@ -37,7 +39,30 @@ impl LiquidClient {
))
}
BlockchainExplorer::Esplora { url, .. } => {
Self::Esplora(Box::new(EsploraLiquidClient::new(
let mut builder = reqwest::Client::builder();
if url == BREEZ_LIQUID_ESPLORA_URL {
match &config.breez_api_key {
Some(api_key) => {
let mut headers = reqwest::header::HeaderMap::new();
let api_key = format!("Bearer {api_key}").parse().map_err(|err| {
Error::Generic(format!("Could not set api key header: {err}"))
})?;
headers.insert(reqwest::header::AUTHORIZATION, api_key);
builder = builder.default_headers(headers)
}
None => {
let err = "Cannot start Breez Esplora client: Breez API key is not set";
error!("{err}");
return Err(Error::Generic(err.to_string()));
}
};
}
let client = builder.build().map_err(|err| {
Error::Generic(format!("Could not initialize HTTP client: {err}"))
})?;
Self::Esplora(Box::new(EsploraLiquidClient::with_client(
client,
config.network.into(),
url,
BOLTZ_CONNECTION_TIMEOUT as u64,

View File

@@ -4,7 +4,7 @@ use boltz_client::{
ChainFees, ChainMinerFees, ChainPair, ChainSwapDetails, CreateChainResponse,
CreateReverseResponse, CreateSubmarineResponse, Leaf, PairLimits, PairMinerFees,
ReverseFees, ReverseLimits, ReversePair, SubmarineClaimTxResponse, SubmarineFees,
SubmarinePair, SwapTree,
SubmarinePair, SubmarinePairLimits, SwapTree,
},
util::secrets::Preimage,
Amount, PublicKey,
@@ -187,10 +187,11 @@ impl Swapper for MockSwapper {
Ok(Some(SubmarinePair {
hash: generate_random_string(10),
rate: 0.0,
limits: PairLimits {
limits: SubmarinePairLimits {
maximal: 25_000_000,
minimal: 1_000,
maximal_zero_conf: 250_000,
minimal_batched: None,
},
fees: SubmarineFees {
percentage: 0.1,

View File

@@ -2,9 +2,9 @@ use std::collections::HashMap;
use std::io::Write;
use std::str::FromStr;
use anyhow::{anyhow, Result};
use anyhow::{anyhow, bail, Result};
use boltz_client::ElementsAddress;
use log::{debug, info, warn};
use log::{debug, error, info, warn};
use lwk_common::Signer as LwkSigner;
use lwk_common::{singlesig_desc, Singlesig};
use lwk_wollet::asyncr::{EsploraClient, EsploraClientBuilder};
@@ -22,7 +22,7 @@ use sdk_common::lightning::util::message_signing::verify;
use tokio::sync::Mutex;
use web_time::Instant;
use crate::model::{BlockchainExplorer, Signer};
use crate::model::{BlockchainExplorer, Signer, BREEZ_LIQUID_ESPLORA_URL};
use crate::persist::Persister;
use crate::signer::SdkLwkSigner;
use crate::{
@@ -133,12 +133,22 @@ impl WalletClient {
url,
use_waterfalls,
} => {
let client = Box::new(
EsploraClientBuilder::new(url, config.network.into())
.timeout(3)
.waterfalls(*use_waterfalls)
.build(),
);
let waterfalls = *use_waterfalls;
let mut builder = EsploraClientBuilder::new(url, config.network.into());
if url == BREEZ_LIQUID_ESPLORA_URL {
match &config.breez_api_key {
Some(api_key) => {
builder = builder
.header("authorization".to_string(), format!("Bearer {api_key}"));
}
None => {
let err = "Cannot start Breez Esplora client: Breez API key is not set";
error!("{err}");
bail!(err)
}
};
}
let client = Box::new(builder.timeout(3).waterfalls(waterfalls).build());
Ok(Self::Esplora(client))
}
}