diff --git a/lib/bindings/src/breez_sdk_liquid.udl b/lib/bindings/src/breez_sdk_liquid.udl index 89626f05a..c97b0c9b2 100644 --- a/lib/bindings/src/breez_sdk_liquid.udl +++ b/lib/bindings/src/breez_sdk_liquid.udl @@ -332,7 +332,7 @@ dictionary Config { LiquidNetwork network; u64 payment_timeout_sec; u32 zero_conf_min_fee_rate_msat; - string sync_service_url; + string? sync_service_url; string? breez_api_key; string? cache_dir; u64? zero_conf_max_amount_sat; diff --git a/lib/core/src/frb_generated.rs b/lib/core/src/frb_generated.rs index ec5cd90a1..ce4017d59 100644 --- a/lib/core/src/frb_generated.rs +++ b/lib/core/src/frb_generated.rs @@ -2372,7 +2372,7 @@ impl SseDecode for crate::model::Config { let mut var_network = ::sse_decode(deserializer); let mut var_paymentTimeoutSec = ::sse_decode(deserializer); let mut var_zeroConfMinFeeRateMsat = ::sse_decode(deserializer); - let mut var_syncServiceUrl = ::sse_decode(deserializer); + let mut var_syncServiceUrl = >::sse_decode(deserializer); let mut var_zeroConfMaxAmountSat = >::sse_decode(deserializer); let mut var_breezApiKey = >::sse_decode(deserializer); let mut var_externalInputParsers = @@ -6779,7 +6779,7 @@ impl SseEncode for crate::model::Config { ::sse_encode(self.network, serializer); ::sse_encode(self.payment_timeout_sec, serializer); ::sse_encode(self.zero_conf_min_fee_rate_msat, serializer); - ::sse_encode(self.sync_service_url, serializer); + >::sse_encode(self.sync_service_url, serializer); >::sse_encode(self.zero_conf_max_amount_sat, serializer); >::sse_encode(self.breez_api_key, serializer); >>::sse_encode( diff --git a/lib/core/src/model.rs b/lib/core/src/model.rs index 145043f7a..2238435f8 100644 --- a/lib/core/src/model.rs +++ b/lib/core/src/model.rs @@ -30,7 +30,7 @@ use crate::utils; // Uses f64 for the maximum precision when converting between units 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; -const BREEZ_SYNC_SERVICE_URL: &str = "https://datasync.breez.technology"; +pub const BREEZ_SYNC_SERVICE_URL: &str = "https://datasync.breez.technology"; /// Configuration for the Liquid SDK #[derive(Clone, Debug, Serialize)] @@ -50,8 +50,9 @@ pub struct Config { pub payment_timeout_sec: u64, /// Zero-conf minimum accepted fee-rate in millisatoshis per vbyte pub zero_conf_min_fee_rate_msat: u32, - /// The url of the real-time sync service - pub sync_service_url: String, + /// The url of the real-time sync service. Defaults to [BREEZ_SYNC_SERVICE_URL] + /// Setting this field to `None` will disable the serivce + pub sync_service_url: Option, /// Maximum amount in satoshi to accept zero-conf payments with /// Defaults to [DEFAULT_ZERO_CONF_MAX_SAT] pub zero_conf_max_amount_sat: Option, @@ -68,7 +69,7 @@ pub struct Config { } impl Config { - pub fn mainnet(breez_api_key: String) -> Self { + pub fn mainnet(breez_api_key: Option) -> Self { Config { liquid_electrum_url: "elements-mainnet.breez.technology:50002".to_string(), bitcoin_electrum_url: "bitcoin-mainnet.blockstream.info:50002".to_string(), @@ -78,9 +79,9 @@ impl Config { network: LiquidNetwork::Mainnet, payment_timeout_sec: 15, zero_conf_min_fee_rate_msat: DEFAULT_ZERO_CONF_MIN_FEE_RATE_MAINNET, - sync_service_url: BREEZ_SYNC_SERVICE_URL.to_string(), + sync_service_url: Some(BREEZ_SYNC_SERVICE_URL.to_string()), zero_conf_max_amount_sat: None, - breez_api_key: Some(breez_api_key), + breez_api_key, external_input_parsers: None, use_default_external_input_parsers: true, } @@ -96,7 +97,7 @@ impl Config { network: LiquidNetwork::Testnet, payment_timeout_sec: 15, zero_conf_min_fee_rate_msat: DEFAULT_ZERO_CONF_MIN_FEE_RATE_TESTNET, - sync_service_url: BREEZ_SYNC_SERVICE_URL.to_string(), + sync_service_url: Some(BREEZ_SYNC_SERVICE_URL.to_string()), zero_conf_max_amount_sat: None, breez_api_key, external_input_parsers: None, diff --git a/lib/core/src/persist/cache.rs b/lib/core/src/persist/cache.rs index 6f04e40ec..6feef3a82 100644 --- a/lib/core/src/persist/cache.rs +++ b/lib/core/src/persist/cache.rs @@ -127,7 +127,7 @@ impl Persister { let tx = con.transaction_with_behavior(TransactionBehavior::Immediate)?; self.set_last_derivation_index_inner(&tx, index)?; tx.commit()?; - self.sync_trigger.try_send(())?; + self.trigger_sync()?; Ok(()) } @@ -151,8 +151,7 @@ impl Persister { None => None, }; tx.commit()?; - self.sync_trigger.try_send(())?; - + self.trigger_sync()?; Ok(res) } } diff --git a/lib/core/src/persist/chain.rs b/lib/core/src/persist/chain.rs index 03ecfd19d..550dede01 100644 --- a/lib/core/src/persist/chain.rs +++ b/lib/core/src/persist/chain.rs @@ -107,7 +107,7 @@ impl Persister { true => { self.commit_outgoing(&tx, &chain_swap.id, RecordType::Chain, updated_fields)?; tx.commit()?; - self.sync_trigger.try_send(())?; + self.trigger_sync()?; } false => { tx.commit()?; @@ -272,11 +272,9 @@ impl Persister { Some(vec!["accept_zero_conf".to_string()]), )?; tx.commit()?; - self.sync_trigger - .try_send(()) - .map_err(|err| PaymentError::Generic { - err: format!("Could not trigger manual sync: {err:?}"), - })?; + self.trigger_sync().map_err(|err| PaymentError::Generic { + err: format!("Could not trigger manual sync: {err:?}"), + })?; Ok(()) } @@ -316,11 +314,9 @@ impl Persister { ]), )?; tx.commit()?; - self.sync_trigger - .try_send(()) - .map_err(|err| PaymentError::Generic { - err: format!("Could not trigger manual sync: {err:?}"), - })?; + self.trigger_sync().map_err(|err| PaymentError::Generic { + err: format!("Could not trigger manual sync: {err:?}"), + })?; Ok(()) } diff --git a/lib/core/src/persist/mod.rs b/lib/core/src/persist/mod.rs index c9998dbd0..8295b0da5 100644 --- a/lib/core/src/persist/mod.rs +++ b/lib/core/src/persist/mod.rs @@ -10,6 +10,7 @@ pub(crate) mod sync; use std::collections::{HashMap, HashSet}; use std::ops::Not; +use std::sync::RwLock; use std::{fs::create_dir_all, path::PathBuf, str::FromStr}; use crate::lightning_invoice::{Bolt11Invoice, Bolt11InvoiceDescription}; @@ -33,7 +34,7 @@ const DEFAULT_DB_FILENAME: &str = "storage.sql"; pub(crate) struct Persister { main_db_dir: PathBuf, network: LiquidNetwork, - sync_trigger: Sender<()>, + pub(crate) sync_trigger: RwLock>>, } /// Builds a WHERE clause that checks if `state` is any of the given arguments @@ -52,7 +53,7 @@ impl Persister { pub fn new( working_dir: &str, network: LiquidNetwork, - sync_trigger: Sender<()>, + sync_trigger: Option>, ) -> Result { let main_db_dir = PathBuf::from_str(working_dir)?; if !main_db_dir.exists() { @@ -61,7 +62,7 @@ impl Persister { Ok(Persister { main_db_dir, network, - sync_trigger, + sync_trigger: RwLock::new(sync_trigger), }) } @@ -238,9 +239,8 @@ impl Persister { } tx.commit()?; - if trigger_sync { - self.sync_trigger.try_send(())?; + self.trigger_sync()?; } Ok(()) @@ -299,8 +299,7 @@ impl Persister { None, )?; tx.commit()?; - - self.sync_trigger.try_send(())?; + self.trigger_sync()?; Ok(()) } diff --git a/lib/core/src/persist/receive.rs b/lib/core/src/persist/receive.rs index 53d1e16ad..60bbca81d 100644 --- a/lib/core/src/persist/receive.rs +++ b/lib/core/src/persist/receive.rs @@ -100,7 +100,7 @@ impl Persister { true => { self.commit_outgoing(&tx, &receive_swap.id, RecordType::Receive, updated_fields)?; tx.commit()?; - self.sync_trigger.try_send(())?; + self.trigger_sync()?; } false => { tx.commit()?; diff --git a/lib/core/src/persist/send.rs b/lib/core/src/persist/send.rs index 17de6e91f..4161f0d0b 100644 --- a/lib/core/src/persist/send.rs +++ b/lib/core/src/persist/send.rs @@ -92,7 +92,7 @@ impl Persister { true => { self.commit_outgoing(&tx, &send_swap.id, RecordType::Send, updated_fields)?; tx.commit()?; - self.sync_trigger.try_send(())?; + self.trigger_sync()?; } false => { tx.commit()?; @@ -282,11 +282,10 @@ impl Persister { let updated_fields = get_updated_fields!(preimage); self.commit_outgoing(&tx, swap_id, RecordType::Send, updated_fields)?; tx.commit()?; - self.sync_trigger - .try_send(()) - .map_err(|err| PaymentError::Generic { - err: format!("Could not trigger manual sync: {err:?}"), - })?; + + self.trigger_sync().map_err(|err| PaymentError::Generic { + err: format!("Could not trigger manual sync: {err:?}"), + })?; Ok(()) } diff --git a/lib/core/src/persist/sync.rs b/lib/core/src/persist/sync.rs index f9d27b49c..01aee1003 100644 --- a/lib/core/src/persist/sync.rs +++ b/lib/core/src/persist/sync.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::{collections::HashMap, ops::Deref}; use anyhow::Result; use rusqlite::{ @@ -249,6 +249,10 @@ impl Persister { record_type: RecordType, updated_fields: Option>, ) -> Result<()> { + if self.sync_trigger.read().unwrap().is_none() { + return Ok(()); + } + let record_id = Record::get_id_from_record_type(record_type, data_id); let updated_fields = updated_fields .map(|fields| { @@ -493,4 +497,11 @@ impl Persister { Ok(()) } + + pub(crate) fn trigger_sync(&self) -> Result<()> { + if let Some(trigger) = self.sync_trigger.read().unwrap().deref() { + return Ok(trigger.try_send(())?); + } + Ok(()) + } } diff --git a/lib/core/src/sdk.rs b/lib/core/src/sdk.rs index 857845d5f..c331a5c33 100644 --- a/lib/core/src/sdk.rs +++ b/lib/core/src/sdk.rs @@ -83,7 +83,7 @@ pub struct LiquidSdk { pub(crate) shutdown_sender: watch::Sender<()>, pub(crate) shutdown_receiver: watch::Receiver<()>, pub(crate) send_swap_handler: SendSwapHandler, - pub(crate) sync_service: Arc, + pub(crate) sync_service: Option>, pub(crate) receive_swap_handler: ReceiveSwapHandler, pub(crate) chain_swap_handler: Arc, pub(crate) buy_bitcoin_service: Arc, @@ -130,7 +130,7 @@ impl LiquidSdk { Ok(sdk) } - fn validate_api_key(api_key: &str) -> Result<()> { + fn validate_breez_api_key(api_key: &str) -> Result<()> { let api_key_decoded = lwk_wollet::bitcoin::base64::engine::general_purpose::STANDARD .decode(api_key.as_bytes()) .map_err(|err| anyhow!("Could not base64 decode the Breez API key: {err:?}"))?; @@ -160,13 +160,9 @@ impl LiquidSdk { swapper_proxy_url: Option, signer: Arc>, ) -> Result> { - match (config.network, &config.breez_api_key) { - (_, Some(api_key)) => Self::validate_api_key(api_key)?, - (LiquidNetwork::Mainnet, None) => { - return Err(anyhow!("Breez API key must be provided on mainnet.")); - } - (LiquidNetwork::Testnet, None) => {} - }; + if let Some(breez_api_key) = &config.breez_api_key { + Self::validate_breez_api_key(breez_api_key)? + } fs::create_dir_all(&config.working_dir)?; let fingerprint_hex: String = @@ -177,12 +173,7 @@ impl LiquidSdk { &fingerprint_hex, )?; - let (sync_trigger_tx, sync_trigger_rx) = tokio::sync::mpsc::channel::<()>(30); - let persister = Arc::new(Persister::new( - &working_dir, - config.network, - sync_trigger_tx, - )?); + let persister = Arc::new(Persister::new(&working_dir, config.network, None)?); persister.init()?; let liquid_chain_service = @@ -204,15 +195,23 @@ impl LiquidSdk { bitcoin_chain_service.clone(), )?); - let syncer_client = Box::new(BreezSyncerClient::new(config.breez_api_key.clone())); - let sync_service = Arc::new(SyncService::new( - config.sync_service_url.clone(), - persister.clone(), - recoverer.clone(), - signer.clone(), - syncer_client, - sync_trigger_rx, - )); + let mut sync_service = None; + if let Some(sync_service_url) = config.sync_service_url.clone() { + if BREEZ_SYNC_SERVICE_URL == sync_service_url && config.breez_api_key.is_none() { + anyhow::bail!( + "Cannot start the Breez real-time sync service without providing a valid API key. See https://sdk-doc-liquid.breez.technology/guide/getting_started.html#api-key", + ); + } + + let syncer_client = Box::new(BreezSyncerClient::new(config.breez_api_key.clone())); + sync_service = Some(Arc::new(SyncService::new( + sync_service_url, + persister.clone(), + recoverer.clone(), + signer.clone(), + syncer_client, + ))); + } let event_manager = Arc::new(EventManager::new()); let (shutdown_sender, shutdown_receiver) = watch::channel::<()>(()); @@ -315,10 +314,9 @@ impl LiquidSdk { .clone() .start(reconnect_handler, self.shutdown_receiver.clone()) .await; - self.sync_service - .clone() - .start(self.shutdown_receiver.clone()) - .await?; + if let Some(sync_service) = self.sync_service.clone() { + sync_service.start(self.shutdown_receiver.clone()).await?; + } self.track_new_blocks().await; self.track_swap_updates().await; @@ -929,12 +927,14 @@ impl LiquidSdk { }; } Ok(InputType::Bolt11 { invoice }) => { - self.sync_service - .pull() - .await - .map_err(|err| PaymentError::Generic { - err: format!("Could not pull real-time sync changes: {err:?}"), - })?; + if let Some(sync_service) = &self.sync_service { + sync_service + .pull() + .await + .map_err(|err| PaymentError::Generic { + err: format!("Could not pull real-time sync changes: {err:?}"), + })?; + } self.ensure_send_is_not_self_transfer(&invoice.bolt11)?; self.validate_bolt11_invoice(&invoice.bolt11)?; @@ -2906,14 +2906,7 @@ impl LiquidSdk { breez_api_key: Option, ) -> Result { let config = match network { - LiquidNetwork::Mainnet => { - let Some(breez_api_key) = breez_api_key else { - return Err(SdkError::Generic { - err: "Breez API key must be provided on mainnet.".to_string(), - }); - }; - Config::mainnet(breez_api_key) - } + LiquidNetwork::Mainnet => Config::mainnet(breez_api_key), LiquidNetwork::Testnet => Config::testnet(breez_api_key), }; Ok(config) diff --git a/lib/core/src/sync/client.rs b/lib/core/src/sync/client.rs index 698b0908b..d35f540ed 100644 --- a/lib/core/src/sync/client.rs +++ b/lib/core/src/sync/client.rs @@ -113,9 +113,9 @@ pub struct ApiKeyInterceptor { impl Interceptor for ApiKeyInterceptor { fn call(&mut self, mut req: Request<()>) -> Result, Status> { - if self.api_key_metadata.clone().is_some() { + if let Some(api_key_metadata) = &self.api_key_metadata { req.metadata_mut() - .insert("authorization", self.api_key_metadata.clone().unwrap()); + .insert("authorization", api_key_metadata.clone()); } Ok(req) } diff --git a/lib/core/src/sync/mod.rs b/lib/core/src/sync/mod.rs index e32511a4d..85ffec516 100644 --- a/lib/core/src/sync/mod.rs +++ b/lib/core/src/sync/mod.rs @@ -39,22 +39,28 @@ pub(crate) struct SyncService { } impl SyncService { + fn set_sync_trigger(persister: Arc) -> Receiver<()> { + let (sync_trigger_tx, sync_trigger_rx) = tokio::sync::mpsc::channel::<()>(30); + let mut persister_trigger = persister.sync_trigger.write().unwrap(); + *persister_trigger = Some(sync_trigger_tx); + sync_trigger_rx + } + pub(crate) fn new( remote_url: String, persister: Arc, recoverer: Arc, signer: Arc>, client: Box, - sync_trigger: Receiver<()>, ) -> Self { - let sync_trigger = Mutex::new(sync_trigger); + let sync_trigger_rx = Self::set_sync_trigger(persister.clone()); Self { remote_url, persister, recoverer, signer, client, - sync_trigger, + sync_trigger: Mutex::new(sync_trigger_rx), } } diff --git a/lib/core/src/test_utils/persist.rs b/lib/core/src/test_utils/persist.rs index 8e632b4be..c59ef870f 100644 --- a/lib/core/src/test_utils/persist.rs +++ b/lib/core/src/test_utils/persist.rs @@ -139,7 +139,6 @@ pub(crate) fn new_receive_swap(payment_state: Option) -> ReceiveSw macro_rules! create_persister { ($name:ident) => { - let (sync_trigger_tx, _sync_trigger_rx) = tokio::sync::mpsc::channel::<()>(100); let temp_dir = tempdir::TempDir::new("liquid-sdk")?; let $name = std::sync::Arc::new(crate::persist::Persister::new( temp_dir @@ -147,7 +146,7 @@ macro_rules! create_persister { .to_str() .ok_or(anyhow::anyhow!("Could not create temporary directory"))?, crate::model::LiquidNetwork::Testnet, - sync_trigger_tx, + None, )?); $name.init()?; }; diff --git a/lib/core/src/test_utils/sdk.rs b/lib/core/src/test_utils/sdk.rs index 14d69021d..7d00be239 100644 --- a/lib/core/src/test_utils/sdk.rs +++ b/lib/core/src/test_utils/sdk.rs @@ -102,7 +102,7 @@ pub(crate) fn new_liquid_sdk_with_chain_services( let (_incoming_tx, _outgoing_records, sync_service) = new_sync_service(persister.clone(), recoverer.clone(), signer.clone())?; - let sync_service = Arc::new(sync_service); + let sync_service = Some(Arc::new(sync_service)); Ok(LiquidSdk { config, diff --git a/lib/core/src/test_utils/sync.rs b/lib/core/src/test_utils/sync.rs index a4ab84e3a..0b6f6273a 100644 --- a/lib/core/src/test_utils/sync.rs +++ b/lib/core/src/test_utils/sync.rs @@ -96,7 +96,6 @@ pub(crate) fn new_sync_service( Arc>>, SyncService, )> { - let (_, sync_trigger_rx) = mpsc::channel::<()>(30); let (incoming_tx, incoming_rx) = mpsc::channel::(10); let outgoing_records = Arc::new(Mutex::new(HashMap::new())); let client = Box::new(MockSyncerClient::new(incoming_rx, outgoing_records.clone())); @@ -106,7 +105,6 @@ pub(crate) fn new_sync_service( recoverer, signer.clone(), client, - sync_trigger_rx, ); Ok((incoming_tx, outgoing_records, sync_service)) diff --git a/packages/dart/lib/src/frb_generated.dart b/packages/dart/lib/src/frb_generated.dart index bd7749cef..5906f0b57 100644 --- a/packages/dart/lib/src/frb_generated.dart +++ b/packages/dart/lib/src/frb_generated.dart @@ -1709,7 +1709,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { network: dco_decode_liquid_network(arr[5]), paymentTimeoutSec: dco_decode_u_64(arr[6]), zeroConfMinFeeRateMsat: dco_decode_u_32(arr[7]), - syncServiceUrl: dco_decode_String(arr[8]), + syncServiceUrl: dco_decode_opt_String(arr[8]), zeroConfMaxAmountSat: dco_decode_opt_box_autoadd_u_64(arr[9]), breezApiKey: dco_decode_opt_String(arr[10]), externalInputParsers: dco_decode_opt_list_external_input_parser(arr[11]), @@ -3665,7 +3665,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { var var_network = sse_decode_liquid_network(deserializer); var var_paymentTimeoutSec = sse_decode_u_64(deserializer); var var_zeroConfMinFeeRateMsat = sse_decode_u_32(deserializer); - var var_syncServiceUrl = sse_decode_String(deserializer); + var var_syncServiceUrl = sse_decode_opt_String(deserializer); var var_zeroConfMaxAmountSat = sse_decode_opt_box_autoadd_u_64(deserializer); var var_breezApiKey = sse_decode_opt_String(deserializer); var var_externalInputParsers = sse_decode_opt_list_external_input_parser(deserializer); @@ -5821,7 +5821,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_liquid_network(self.network, serializer); sse_encode_u_64(self.paymentTimeoutSec, serializer); sse_encode_u_32(self.zeroConfMinFeeRateMsat, serializer); - sse_encode_String(self.syncServiceUrl, serializer); + sse_encode_opt_String(self.syncServiceUrl, serializer); sse_encode_opt_box_autoadd_u_64(self.zeroConfMaxAmountSat, serializer); sse_encode_opt_String(self.breezApiKey, serializer); sse_encode_opt_list_external_input_parser(self.externalInputParsers, serializer); diff --git a/packages/dart/lib/src/frb_generated.io.dart b/packages/dart/lib/src/frb_generated.io.dart index 4f139e050..1e0b9d4f3 100644 --- a/packages/dart/lib/src/frb_generated.io.dart +++ b/packages/dart/lib/src/frb_generated.io.dart @@ -2275,7 +2275,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { wireObj.network = cst_encode_liquid_network(apiObj.network); wireObj.payment_timeout_sec = cst_encode_u_64(apiObj.paymentTimeoutSec); wireObj.zero_conf_min_fee_rate_msat = cst_encode_u_32(apiObj.zeroConfMinFeeRateMsat); - wireObj.sync_service_url = cst_encode_String(apiObj.syncServiceUrl); + wireObj.sync_service_url = cst_encode_opt_String(apiObj.syncServiceUrl); wireObj.zero_conf_max_amount_sat = cst_encode_opt_box_autoadd_u_64(apiObj.zeroConfMaxAmountSat); wireObj.breez_api_key = cst_encode_opt_String(apiObj.breezApiKey); wireObj.external_input_parsers = cst_encode_opt_list_external_input_parser(apiObj.externalInputParsers); diff --git a/packages/dart/lib/src/model.dart b/packages/dart/lib/src/model.dart index 7fa73fbd1..18014ad05 100644 --- a/packages/dart/lib/src/model.dart +++ b/packages/dart/lib/src/model.dart @@ -134,8 +134,9 @@ class Config { /// Zero-conf minimum accepted fee-rate in millisatoshis per vbyte final int zeroConfMinFeeRateMsat; - /// The url of the real-time sync service - final String syncServiceUrl; + /// The url of the real-time sync service. Defaults to [BREEZ_SYNC_SERVICE_URL] + /// Setting this field to `None` will disable the serivce + final String? syncServiceUrl; /// Maximum amount in satoshi to accept zero-conf payments with /// Defaults to [DEFAULT_ZERO_CONF_MAX_SAT] @@ -163,7 +164,7 @@ class Config { required this.network, required this.paymentTimeoutSec, required this.zeroConfMinFeeRateMsat, - required this.syncServiceUrl, + this.syncServiceUrl, this.zeroConfMaxAmountSat, this.breezApiKey, this.externalInputParsers, diff --git a/packages/react-native/android/src/main/java/com/breezsdkliquid/BreezSDKLiquidMapper.kt b/packages/react-native/android/src/main/java/com/breezsdkliquid/BreezSDKLiquidMapper.kt index 2b5048c34..2df986852 100644 --- a/packages/react-native/android/src/main/java/com/breezsdkliquid/BreezSDKLiquidMapper.kt +++ b/packages/react-native/android/src/main/java/com/breezsdkliquid/BreezSDKLiquidMapper.kt @@ -248,7 +248,6 @@ fun asConfig(config: ReadableMap): Config? { "network", "paymentTimeoutSec", "zeroConfMinFeeRateMsat", - "syncServiceUrl", "useDefaultExternalInputParsers", ), ) @@ -262,7 +261,7 @@ fun asConfig(config: ReadableMap): Config? { val network = config.getString("network")?.let { asLiquidNetwork(it) }!! val paymentTimeoutSec = config.getDouble("paymentTimeoutSec").toULong() val zeroConfMinFeeRateMsat = config.getInt("zeroConfMinFeeRateMsat").toUInt() - val syncServiceUrl = config.getString("syncServiceUrl")!! + val syncServiceUrl = if (hasNonNullKey(config, "syncServiceUrl")) config.getString("syncServiceUrl") else null val breezApiKey = if (hasNonNullKey(config, "breezApiKey")) config.getString("breezApiKey") else null val cacheDir = if (hasNonNullKey(config, "cacheDir")) config.getString("cacheDir") else null val zeroConfMaxAmountSat = diff --git a/packages/react-native/ios/BreezSDKLiquidMapper.swift b/packages/react-native/ios/BreezSDKLiquidMapper.swift index 6e85f25f1..8c4c244c5 100644 --- a/packages/react-native/ios/BreezSDKLiquidMapper.swift +++ b/packages/react-native/ios/BreezSDKLiquidMapper.swift @@ -307,8 +307,12 @@ enum BreezSDKLiquidMapper { guard let zeroConfMinFeeRateMsat = config["zeroConfMinFeeRateMsat"] as? UInt32 else { throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "zeroConfMinFeeRateMsat", typeName: "Config")) } - guard let syncServiceUrl = config["syncServiceUrl"] as? String else { - throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "syncServiceUrl", typeName: "Config")) + var syncServiceUrl: String? + if hasNonNilKey(data: config, key: "syncServiceUrl") { + guard let syncServiceUrlTmp = config["syncServiceUrl"] as? String else { + throw SdkError.Generic(message: errUnexpectedValue(fieldName: "syncServiceUrl")) + } + syncServiceUrl = syncServiceUrlTmp } var breezApiKey: String? if hasNonNilKey(data: config, key: "breezApiKey") { @@ -351,7 +355,7 @@ enum BreezSDKLiquidMapper { "network": valueOf(liquidNetwork: config.network), "paymentTimeoutSec": config.paymentTimeoutSec, "zeroConfMinFeeRateMsat": config.zeroConfMinFeeRateMsat, - "syncServiceUrl": config.syncServiceUrl, + "syncServiceUrl": config.syncServiceUrl == nil ? nil : config.syncServiceUrl, "breezApiKey": config.breezApiKey == nil ? nil : config.breezApiKey, "cacheDir": config.cacheDir == nil ? nil : config.cacheDir, "zeroConfMaxAmountSat": config.zeroConfMaxAmountSat == nil ? nil : config.zeroConfMaxAmountSat, diff --git a/packages/react-native/src/index.ts b/packages/react-native/src/index.ts index c7b48b8c5..8b6db2169 100644 --- a/packages/react-native/src/index.ts +++ b/packages/react-native/src/index.ts @@ -65,7 +65,7 @@ export interface Config { network: LiquidNetwork paymentTimeoutSec: number zeroConfMinFeeRateMsat: number - syncServiceUrl: string + syncServiceUrl?: string breezApiKey?: string cacheDir?: string zeroConfMaxAmountSat?: number