mirror of
https://github.com/aljazceru/breez-sdk-liquid.git
synced 2026-01-20 14:34:19 +01:00
Return pending payment (#245)
* Return pending payment * Simplify select loop * Revert dart pubspec * Add error logging for payment events without swap ids Co-authored-by: ok300 <106775972+ok300@users.noreply.github.com> --------- Co-authored-by: ok300 <106775972+ok300@users.noreply.github.com>
This commit is contained in:
@@ -59,6 +59,9 @@ pub enum PaymentError {
|
||||
#[error("Boltz did not return any pairs from the request")]
|
||||
PairsNotFound,
|
||||
|
||||
#[error("The payment timed out")]
|
||||
PaymentTimeout,
|
||||
|
||||
#[error("Could not store the swap details locally")]
|
||||
PersistError,
|
||||
|
||||
|
||||
@@ -326,21 +326,22 @@ impl CstDecode<crate::error::PaymentError> for wire_cst_payment_error {
|
||||
}
|
||||
}
|
||||
8 => crate::error::PaymentError::PairsNotFound,
|
||||
9 => crate::error::PaymentError::PersistError,
|
||||
10 => {
|
||||
9 => crate::error::PaymentError::PaymentTimeout,
|
||||
10 => crate::error::PaymentError::PersistError,
|
||||
11 => {
|
||||
let ans = unsafe { self.kind.Refunded };
|
||||
crate::error::PaymentError::Refunded {
|
||||
err: ans.err.cst_decode(),
|
||||
refund_tx_id: ans.refund_tx_id.cst_decode(),
|
||||
}
|
||||
}
|
||||
11 => {
|
||||
12 => {
|
||||
let ans = unsafe { self.kind.SendError };
|
||||
crate::error::PaymentError::SendError {
|
||||
err: ans.err.cst_decode(),
|
||||
}
|
||||
}
|
||||
12 => {
|
||||
13 => {
|
||||
let ans = unsafe { self.kind.SignerError };
|
||||
crate::error::PaymentError::SignerError {
|
||||
err: ans.err.cst_decode(),
|
||||
|
||||
@@ -821,9 +821,12 @@ impl SseDecode for crate::error::PaymentError {
|
||||
return crate::error::PaymentError::PairsNotFound;
|
||||
}
|
||||
9 => {
|
||||
return crate::error::PaymentError::PersistError;
|
||||
return crate::error::PaymentError::PaymentTimeout;
|
||||
}
|
||||
10 => {
|
||||
return crate::error::PaymentError::PersistError;
|
||||
}
|
||||
11 => {
|
||||
let mut var_err = <String>::sse_decode(deserializer);
|
||||
let mut var_refundTxId = <String>::sse_decode(deserializer);
|
||||
return crate::error::PaymentError::Refunded {
|
||||
@@ -831,11 +834,11 @@ impl SseDecode for crate::error::PaymentError {
|
||||
refund_tx_id: var_refundTxId,
|
||||
};
|
||||
}
|
||||
11 => {
|
||||
12 => {
|
||||
let mut var_err = <String>::sse_decode(deserializer);
|
||||
return crate::error::PaymentError::SendError { err: var_err };
|
||||
}
|
||||
12 => {
|
||||
13 => {
|
||||
let mut var_err = <String>::sse_decode(deserializer);
|
||||
return crate::error::PaymentError::SignerError { err: var_err };
|
||||
}
|
||||
@@ -1258,18 +1261,19 @@ impl flutter_rust_bridge::IntoDart for crate::error::PaymentError {
|
||||
[7.into_dart(), err.into_into_dart().into_dart()].into_dart()
|
||||
}
|
||||
crate::error::PaymentError::PairsNotFound => [8.into_dart()].into_dart(),
|
||||
crate::error::PaymentError::PersistError => [9.into_dart()].into_dart(),
|
||||
crate::error::PaymentError::PaymentTimeout => [9.into_dart()].into_dart(),
|
||||
crate::error::PaymentError::PersistError => [10.into_dart()].into_dart(),
|
||||
crate::error::PaymentError::Refunded { err, refund_tx_id } => [
|
||||
10.into_dart(),
|
||||
11.into_dart(),
|
||||
err.into_into_dart().into_dart(),
|
||||
refund_tx_id.into_into_dart().into_dart(),
|
||||
]
|
||||
.into_dart(),
|
||||
crate::error::PaymentError::SendError { err } => {
|
||||
[11.into_dart(), err.into_into_dart().into_dart()].into_dart()
|
||||
[12.into_dart(), err.into_into_dart().into_dart()].into_dart()
|
||||
}
|
||||
crate::error::PaymentError::SignerError { err } => {
|
||||
[12.into_dart(), err.into_into_dart().into_dart()].into_dart()
|
||||
[13.into_dart(), err.into_into_dart().into_dart()].into_dart()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1753,20 +1757,23 @@ impl SseEncode for crate::error::PaymentError {
|
||||
crate::error::PaymentError::PairsNotFound => {
|
||||
<i32>::sse_encode(8, serializer);
|
||||
}
|
||||
crate::error::PaymentError::PersistError => {
|
||||
crate::error::PaymentError::PaymentTimeout => {
|
||||
<i32>::sse_encode(9, serializer);
|
||||
}
|
||||
crate::error::PaymentError::Refunded { err, refund_tx_id } => {
|
||||
crate::error::PaymentError::PersistError => {
|
||||
<i32>::sse_encode(10, serializer);
|
||||
}
|
||||
crate::error::PaymentError::Refunded { err, refund_tx_id } => {
|
||||
<i32>::sse_encode(11, serializer);
|
||||
<String>::sse_encode(err, serializer);
|
||||
<String>::sse_encode(refund_tx_id, serializer);
|
||||
}
|
||||
crate::error::PaymentError::SendError { err } => {
|
||||
<i32>::sse_encode(11, serializer);
|
||||
<i32>::sse_encode(12, serializer);
|
||||
<String>::sse_encode(err, serializer);
|
||||
}
|
||||
crate::error::PaymentError::SignerError { err } => {
|
||||
<i32>::sse_encode(12, serializer);
|
||||
<i32>::sse_encode(13, serializer);
|
||||
<String>::sse_encode(err, serializer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1019,6 +1019,7 @@ impl LiquidSdk {
|
||||
})?;
|
||||
|
||||
let swap_id = &create_response.id;
|
||||
let accept_zero_conf = create_response.accept_zero_conf;
|
||||
let create_response_json = SendSwap::from_boltz_struct_to_json(&create_response, swap_id)?;
|
||||
|
||||
let payer_amount_sat = req.fees_sat + receiver_amount_sat;
|
||||
@@ -1035,28 +1036,55 @@ impl LiquidSdk {
|
||||
refund_private_key: keypair.display_secret().to_string(),
|
||||
};
|
||||
self.persister.insert_send_swap(&swap)?;
|
||||
|
||||
let mut events_stream = self.event_manager.subscribe();
|
||||
self.status_stream.track_swap_id(swap_id)?;
|
||||
|
||||
self.wait_for_payment(swap.id, accept_zero_conf)
|
||||
.await
|
||||
.map(|payment| SendPaymentResponse { payment })
|
||||
}
|
||||
|
||||
async fn wait_for_payment(
|
||||
&self,
|
||||
swap_id: String,
|
||||
accept_zero_conf: bool,
|
||||
) -> Result<Payment, PaymentError> {
|
||||
let timeout_fut = tokio::time::sleep(Duration::from_secs(15));
|
||||
tokio::pin!(timeout_fut);
|
||||
|
||||
let mut events_stream = self.event_manager.subscribe();
|
||||
let mut maybe_payment: Option<Payment> = None;
|
||||
|
||||
loop {
|
||||
match events_stream.recv().await {
|
||||
Ok(LiquidSdkEvent::PaymentFailed { details }) => match details.swap_id {
|
||||
Some(id) if id == swap.id => {
|
||||
return Err(PaymentError::SendError {
|
||||
err: "Payment failed".to_string(),
|
||||
})
|
||||
}
|
||||
_ => (),
|
||||
tokio::select! {
|
||||
_ = &mut timeout_fut => match maybe_payment {
|
||||
Some(payment) => return Ok(payment),
|
||||
None => return Err(PaymentError::PaymentTimeout),
|
||||
},
|
||||
Ok(LiquidSdkEvent::PaymentSucceed { details }) => match details.swap_id.clone() {
|
||||
Some(id) if id == swap.id => {
|
||||
return Ok(SendPaymentResponse { payment: details })
|
||||
}
|
||||
_ => (),
|
||||
},
|
||||
Ok(event) => debug!("Unhandled event: {event:?}"),
|
||||
Err(e) => debug!("Received error waiting for event: {e:?}"),
|
||||
event = events_stream.recv() => match event {
|
||||
Ok(LiquidSdkEvent::PaymentPending { details }) => match details.swap_id.clone() {
|
||||
Some(id) if id == swap_id => match accept_zero_conf {
|
||||
true => {
|
||||
debug!("Received Send Payment pending event with zero-conf accepted");
|
||||
return Ok(details)
|
||||
}
|
||||
false => {
|
||||
debug!("Received Send Payment pending event, waiting for confirmation");
|
||||
maybe_payment = Some(details);
|
||||
}
|
||||
},
|
||||
_ => error!("Received Send Payment pending event for payment without swap ID"),
|
||||
},
|
||||
Ok(LiquidSdkEvent::PaymentSucceed { details }) => match details.swap_id.clone()
|
||||
{
|
||||
Some(id) if id == swap_id => {
|
||||
debug!("Received Send Payment succeed event");
|
||||
return Ok(details);
|
||||
}
|
||||
_ => error!("Received Send Payment succeed event for payment without swap ID"),
|
||||
},
|
||||
Ok(event) => debug!("Unhandled event: {event:?}"),
|
||||
Err(e) => debug!("Received error waiting for event: {e:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user