11//! An implementation of `TrustedWalletInterface` using the Spark SDK.
22use crate :: bitcoin:: hex:: FromHex ;
3- use crate :: bitcoin:: io ;
3+ use crate :: bitcoin:: { Network , io } ;
44use crate :: logging:: Logger ;
55use crate :: store:: { PaymentId , TxMetadataStore , TxStatus } ;
66use crate :: trusted_wallet:: { Payment , TrustedError , TrustedWalletInterface } ;
@@ -32,17 +32,53 @@ use std::time::Duration;
3232use tokio:: runtime:: Runtime ;
3333use uuid:: Uuid ;
3434
35+ /// Configuration options for the Spark wallet.
36+ #[ derive( Debug , Copy , Clone ) ]
37+ pub struct SparkWalletConfig {
38+ /// How often to sync the wallet with the blockchain, in seconds.
39+ /// Default is 60 seconds.
40+ pub sync_interval_secs : u32 ,
41+ /// When this is set to `true` we will prefer to use spark payments over
42+ /// lightning when sending and receiving. This has the benefit of lower fees
43+ /// but is at the cost of privacy.
44+ pub prefer_spark_over_lightning : bool ,
45+ }
46+
47+ impl Default for SparkWalletConfig {
48+ fn default ( ) -> Self {
49+ SparkWalletConfig { sync_interval_secs : 60 , prefer_spark_over_lightning : false }
50+ }
51+ }
52+
53+ /// Breez API key for using the Spark SDK. We aren't using any of their services
54+ /// but the SDK requires a valid API key to function.
55+ const BREEZ_API_KEY : & str = "MIIBajCCARygAwIBAgIHPnfOjAhBgzAFBgMrZXAwEDEOMAwGA1UEAxMFQnJlZXowHhcNMjUwOTE5MjEzNTU1WhcNMzUwOTE3MjEzNTU1WjAqMRMwEQYDVQQKEwpvcmFuZ2Utc2RrMRMwEQYDVQQDEwpvcmFuZ2Utc2RrMCowBQYDK2VwAyEA0IP1y98gPByiIMoph1P0G6cctLb864rNXw1LRLOpXXejezB5MA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTaOaPuXmtLDTJVv++VYBiQr9gHCTAfBgNVHSMEGDAWgBTeqtaSVvON53SSFvxMtiCyayiYazAZBgNVHREEEjAQgQ5iZW5Ac3BpcmFsLnh5ejAFBgMrZXADQQCry+1LkA3nrYa1sovS5iFI1Tkpmr/R0nM/4gJtsO93vFOkm3vBEGwjKAV7lrGzFcFbbuyM1wEJPi4Po1XCEG0D" ;
56+
57+ impl SparkWalletConfig {
58+ fn to_breez_config ( self , network : Network ) -> Result < breez_sdk_spark:: Config , TrustedError > {
59+ let network = match network {
60+ Network :: Bitcoin => breez_sdk_spark:: Network :: Mainnet ,
61+ Network :: Regtest => breez_sdk_spark:: Network :: Regtest ,
62+ _ => return Err ( TrustedError :: InvalidNetwork ) ,
63+ } ;
64+
65+ Ok ( breez_sdk_spark:: Config {
66+ network,
67+ sync_interval_secs : self . sync_interval_secs ,
68+ prefer_spark_over_lightning : self . prefer_spark_over_lightning ,
69+ api_key : Some ( BREEZ_API_KEY . to_string ( ) ) ,
70+ max_deposit_claim_fee : None ,
71+ lnurl_domain : None ,
72+ } )
73+ }
74+ }
75+
3576/// A wallet implementation using the Breez Spark SDK.
3677#[ derive( Clone ) ]
3778pub ( crate ) struct Spark {
3879 spark_wallet : Arc < BreezSdk > ,
39- store : Arc < dyn KVStore + Send + Sync > ,
40- event_queue : Arc < EventQueue > ,
41- tx_metadata : TxMetadataStore ,
4280 shutdown_sender : watch:: Sender < ( ) > ,
43- shutdown_receiver : watch:: Receiver < ( ) > ,
4481 logger : Arc < Logger > ,
45- runtime : Arc < Runtime > ,
4682}
4783
4884impl TrustedWalletInterface for Spark {
@@ -199,15 +235,11 @@ impl TrustedWalletInterface for Spark {
199235impl Spark {
200236 /// Initialize a new Spark wallet instance with the given configuration.
201237 pub ( crate ) async fn init (
202- config : & WalletConfig , spark_config : breez_sdk_spark :: Config ,
238+ config : & WalletConfig , spark_config : SparkWalletConfig ,
203239 store : Arc < dyn KVStore + Sync + Send > , event_queue : Arc < EventQueue > ,
204240 tx_metadata : TxMetadataStore , logger : Arc < Logger > , runtime : Arc < Runtime > ,
205241 ) -> Result < Self , InitFailure > {
206- match ( config. network , spark_config. network ) {
207- ( crate :: bitcoin:: Network :: Bitcoin , breez_sdk_spark:: Network :: Mainnet ) => { } ,
208- ( crate :: bitcoin:: Network :: Regtest , breez_sdk_spark:: Network :: Regtest ) => { } ,
209- _ => Err ( TrustedError :: InvalidNetwork ) ?,
210- }
242+ let spark_config: breez_sdk_spark:: Config = spark_config. to_breez_config ( config. network ) ?;
211243
212244 let ( mnemonic, passphrase) = match & config. seed {
213245 Seed :: Seed64 ( bytes) => {
@@ -217,7 +249,7 @@ impl Spark {
217249 Seed :: Mnemonic { mnemonic, passphrase } => ( mnemonic. to_string ( ) , passphrase. clone ( ) ) ,
218250 } ;
219251
220- let spark_store = SparkStore ( Arc :: clone ( & store) ) ;
252+ let spark_store = SparkStore ( store) ;
221253 let builder = SdkBuilder :: new ( spark_config, mnemonic, passphrase, Arc :: new ( spark_store) ) ;
222254
223255 let spark_wallet = Arc :: new ( builder. build ( ) . await . map_err ( |e| {
@@ -230,6 +262,7 @@ impl Spark {
230262 let ( shutdown_sender, shutdown_receiver) = watch:: channel :: < ( ) > ( ( ) ) ;
231263 let listener = SparkEventHandler {
232264 event_queue : Arc :: clone ( & event_queue) ,
265+ tx_metadata,
233266 logger : Arc :: clone ( & logger) ,
234267 } ;
235268
@@ -244,21 +277,14 @@ impl Spark {
244277
245278 log_info ! ( logger, "Spark wallet initialized" ) ;
246279
247- Ok ( Spark {
248- spark_wallet,
249- store,
250- event_queue,
251- tx_metadata,
252- shutdown_sender,
253- shutdown_receiver,
254- logger,
255- runtime,
256- } )
280+ Ok ( Spark { spark_wallet, shutdown_sender, logger } )
257281 }
258282}
259283
260284struct SparkEventHandler {
261285 event_queue : Arc < EventQueue > ,
286+ #[ allow( unused) ] // will be used in future events
287+ tx_metadata : TxMetadataStore ,
262288 logger : Arc < Logger > ,
263289}
264290
@@ -370,7 +396,7 @@ fn parse_payment_id(id: &str) -> Result<[u8; 32], TrustedError> {
370396 . map_err ( |_| TrustedError :: Other ( format ! ( "Failed to parse payment id: {id}" ) ) ) ?
371397 } else {
372398 // if it's not in the expected format, try to parse the whole thing as a uuid
373- Uuid :: from_str ( & id)
399+ Uuid :: from_str ( id)
374400 . map_err ( |_| TrustedError :: Other ( format ! ( "Failed to parse payment id: {id}" ) ) ) ?
375401 } ;
376402 Ok ( convert_from_uuid_id ( uuid. into_bytes ( ) ) )
0 commit comments