Skip to content

Commit 2dc7e91

Browse files
committed
Properly convert breez payment to ours
1 parent 824e668 commit 2dc7e91

2 files changed

Lines changed: 62 additions & 25 deletions

File tree

orange-sdk/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ bitcoin-payment-instructions = { workspace = true }
2323
chrono = { version = "0.4", default-features = false }
2424
rand = { version = "0.8.5", optional = true }
2525
reqwest = { version = "0.12.23", default-features = false, features = ["rustls-tls"] }
26-
breez-sdk-spark = { git = "https://github.com/breez/spark-sdk.git", rev = "e0ecc7ff44ecc9d3ae82e40f5cb576e80711a45d", default-features = false, features = ["rustls-tls"], optional = true }
26+
breez-sdk-spark = { git = "https://github.com/breez/spark-sdk.git", rev = "41212dfcfe36e22a55ac224c791b326f259f90d6", default-features = false, features = ["rustls-tls"], optional = true }
2727
tokio = { version = "1.0", default-features = false, features = ["rt-multi-thread", "sync"] }
2828
uuid = { version = "1.0", default-features = false, optional = true }
2929
cdk = { git = "https://github.com/benthecarman/cdk.git", rev = "7d25e9ae5ed7f47f9ae7e87d8a9ee16797fee8cd", default-features = false, features = ["wallet"], optional = true }

orange-sdk/src/trusted_wallet/spark.rs

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
//! An implementation of `TrustedWalletInterface` using the Spark SDK.
2-
use crate::bitcoin::hashes::{Hash, sha256};
32
use crate::bitcoin::hex::FromHex;
43
use crate::bitcoin::{Network, io};
54
use crate::logging::Logger;
65
use crate::store::{PaymentId, TxMetadataStore, TxStatus};
76
use crate::trusted_wallet::{Payment, TrustedError, TrustedWalletInterface};
8-
use crate::{Event, EventQueue, InitFailure, Mnemonic, Seed, WalletConfig};
7+
use crate::{Event, EventQueue, InitFailure, Seed, WalletConfig};
98

109
use ldk_node::lightning::util::logger::Logger as _;
1110
use ldk_node::lightning::util::persist::KVStore;
@@ -139,20 +138,8 @@ impl TrustedWalletInterface for Spark {
139138
.list_payments(ListPaymentsRequest { limit: None, offset: None })
140139
.await?;
141140

142-
let payments = resp
143-
.payments
144-
.into_iter()
145-
.map(|p| {
146-
parse_payment_id(&p.id).map(|id| Payment {
147-
id,
148-
amount: Amount::from_sats(p.amount).unwrap(),
149-
fee: Amount::from_sats(p.fees).unwrap(),
150-
status: p.status.into(),
151-
outbound: p.payment_type == PaymentType::Send,
152-
time_since_epoch: Duration::from_secs(p.timestamp),
153-
})
154-
})
155-
.collect::<Result<_, _>>()?;
141+
let payments =
142+
resp.payments.into_iter().map(|p| p.try_into()).collect::<Result<_, _>>()?;
156143

157144
Ok(payments)
158145
})
@@ -238,18 +225,16 @@ impl Spark {
238225
) -> Result<Self, InitFailure> {
239226
let spark_config: breez_sdk_spark::Config = spark_config.to_breez_config(config.network)?;
240227

241-
let (mnemonic, passphrase) = match &config.seed {
242-
Seed::Seed64(bytes) => {
243-
// max entropy for bip39 is 32 bytes, so we hash the 64 bytes down to 32
244-
let hash = sha256::Hash::hash(bytes);
245-
let mnemonic = Mnemonic::from_entropy(hash.as_byte_array()).expect("valid length");
246-
(mnemonic.to_string(), None)
228+
let seed = match &config.seed {
229+
Seed::Seed64(bytes) => breez_sdk_spark::Seed::Entropy(bytes.to_vec()),
230+
Seed::Mnemonic { mnemonic, passphrase } => breez_sdk_spark::Seed::Mnemonic {
231+
mnemonic: mnemonic.to_string(),
232+
passphrase: passphrase.clone(),
247233
},
248-
Seed::Mnemonic { mnemonic, passphrase } => (mnemonic.to_string(), passphrase.clone()),
249234
};
250235

251236
let spark_store = SparkStore(store);
252-
let builder = SdkBuilder::new(spark_config, mnemonic, passphrase, Arc::new(spark_store));
237+
let builder = SdkBuilder::new(spark_config, seed, Arc::new(spark_store));
253238

254239
let spark_wallet = Arc::new(builder.build().await.map_err(|e| {
255240
log_error!(logger, "Failed to initialize Spark wallet: {e:?}");
@@ -307,6 +292,11 @@ impl EventListener for SparkEventHandler {
307292
log_error!(self.logger, "Failed to handle payment succeeded: {e:?}");
308293
}
309294
},
295+
SdkEvent::PaymentFailed { payment } => {
296+
if let Err(e) = self.handle_payment_failed(payment) {
297+
log_error!(self.logger, "Failed to handle payment succeeded: {e:?}");
298+
}
299+
},
310300
}
311301
}
312302
}
@@ -383,6 +373,36 @@ impl SparkEventHandler {
383373

384374
Ok(())
385375
}
376+
377+
fn handle_payment_failed(&self, payment: breez_sdk_spark::Payment) -> Result<(), TrustedError> {
378+
log_info!(self.logger, "Spark payment failed: {payment:?}");
379+
380+
let id = parse_payment_id(&payment.id)?;
381+
382+
match payment.payment_type {
383+
PaymentType::Send => match payment.details {
384+
Some(PaymentDetails::Lightning { payment_hash, .. }) => {
385+
let payment_hash: [u8; 32] = FromHex::from_hex(&payment_hash).map_err(|e| {
386+
TrustedError::Other(format!("Invalid payment_hash hex: {e:?}"))
387+
})?;
388+
389+
self.event_queue.add_event(Event::PaymentFailed {
390+
payment_id: PaymentId::Trusted(id),
391+
payment_hash: Some(PaymentHash(payment_hash)),
392+
reason: None,
393+
})?;
394+
},
395+
_ => {
396+
log_debug!(self.logger, "Unsupported payment details for Send: {payment:?}")
397+
},
398+
},
399+
PaymentType::Receive => {
400+
log_debug!(self.logger, "Receive payments cannot fail: {payment:?}");
401+
},
402+
}
403+
404+
Ok(())
405+
}
386406
}
387407

388408
fn parse_payment_id(id: &str) -> Result<[u8; 32], TrustedError> {
@@ -614,3 +634,20 @@ impl breez_sdk_spark::Storage for SparkStore {
614634
Ok(())
615635
}
616636
}
637+
638+
impl TryFrom<breez_sdk_spark::Payment> for Payment {
639+
type Error = TrustedError;
640+
641+
fn try_from(value: breez_sdk_spark::Payment) -> Result<Self, Self::Error> {
642+
let id = parse_payment_id(&value.id)?;
643+
644+
Ok(Payment {
645+
id,
646+
amount: Amount::from_sats(value.amount).map_err(|_| TrustedError::AmountError)?,
647+
fee: Amount::from_sats(value.fees).map_err(|_| TrustedError::AmountError)?,
648+
status: value.status.into(),
649+
outbound: value.payment_type == PaymentType::Send,
650+
time_since_epoch: Duration::from_secs(value.timestamp),
651+
})
652+
}
653+
}

0 commit comments

Comments
 (0)