Skip to content

Commit

Permalink
Allow the pending timeout to be optional
Browse files Browse the repository at this point in the history
  • Loading branch information
dangeross committed Apr 24, 2024
1 parent 1128f90 commit c6dd7b8
Show file tree
Hide file tree
Showing 12 changed files with 102 additions and 67 deletions.
2 changes: 1 addition & 1 deletion libs/sdk-bindings/src/breez_sdk.udl
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ dictionary Config {
string working_dir;
Network network;
u32 payment_timeout_sec;
u64 payment_request_yield_sec;
string? default_lsp_id;
string? api_key;
f64 maxfee_percent;
Expand Down Expand Up @@ -750,6 +749,7 @@ dictionary SendPaymentRequest {
string bolt11;
u64? amount_msat = null;
string? label = null;
u64? pending_timeout_sec = null;
};

dictionary SendSpontaneousPaymentRequest {
Expand Down
78 changes: 50 additions & 28 deletions libs/sdk-core/src/breez_services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,33 +324,55 @@ impl BreezServices {
})
.await?;

let timeout = Duration::from_secs(self.config.payment_request_yield_sec);
let (tx, rx) = std::sync::mpsc::channel();
let cloned = self.clone();
tokio::spawn(async move {
let payment_res = cloned
.node_api
.send_payment(
parsed_invoice.bolt11.clone(),
req.amount_msat,
req.label.clone(),
)
.await;
let result = cloned
.on_payment_completed(
parsed_invoice.payee_pubkey.clone(),
Some(parsed_invoice),
payment_res.map_err(Into::into),
)
.await;
let _ = tx.send(result);
});

match rx.recv_timeout(timeout) {
Ok(result) => result.map(|payment| SendPaymentResponse { payment }),
Err(_) => Ok(SendPaymentResponse {
payment: pending_payment,
}),
match req.pending_timeout_sec {
Some(secs) => {
let (tx, rx) = std::sync::mpsc::channel();
let cloned = self.clone();
tokio::spawn(async move {
let payment_res = cloned
.node_api
.send_payment(
parsed_invoice.bolt11.clone(),
req.amount_msat,
req.label.clone(),
)
.await;
let result = cloned
.on_payment_completed(
parsed_invoice.payee_pubkey.clone(),
Some(parsed_invoice),
payment_res.map_err(Into::into),
)
.await;
let _ = tx.send(result);
});

match rx.recv_timeout(Duration::from_secs(secs)) {
Ok(result) => result.map(|payment| SendPaymentResponse { payment }),
Err(_) => Ok(SendPaymentResponse {
payment: pending_payment,
}),
}
}
None => {
let payment_res = self
.node_api
.send_payment(
parsed_invoice.bolt11.clone(),
req.amount_msat,
req.label.clone(),
)
.map_err(Into::into)
.await;
let payment = self
.on_payment_completed(
parsed_invoice.payee_pubkey.clone(),
Some(parsed_invoice),
payment_res,
)
.await?;
Ok(SendPaymentResponse { payment })
}
}
}
}
Expand Down Expand Up @@ -404,8 +426,8 @@ impl BreezServices {
ValidatedCallbackResponse::EndpointSuccess { data: cb } => {
let pay_req = SendPaymentRequest {
bolt11: cb.pr.clone(),
amount_msat: None,
label: req.payment_label,
..Default::default()
};
let invoice = parse_invoice(cb.pr.as_str())?;

Expand Down
6 changes: 3 additions & 3 deletions libs/sdk-core/src/bridge_generated.io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,6 @@ impl Wire2Api<Config> for wire_Config {
working_dir: self.working_dir.wire2api(),
network: self.network.wire2api(),
payment_timeout_sec: self.payment_timeout_sec.wire2api(),
payment_request_yield_sec: self.payment_request_yield_sec.wire2api(),
default_lsp_id: self.default_lsp_id.wire2api(),
api_key: self.api_key.wire2api(),
maxfee_percent: self.maxfee_percent.wire2api(),
Expand Down Expand Up @@ -1073,6 +1072,7 @@ impl Wire2Api<SendPaymentRequest> for wire_SendPaymentRequest {
bolt11: self.bolt11.wire2api(),
amount_msat: self.amount_msat.wire2api(),
label: self.label.wire2api(),
pending_timeout_sec: self.pending_timeout_sec.wire2api(),
}
}
}
Expand Down Expand Up @@ -1144,7 +1144,6 @@ pub struct wire_Config {
working_dir: *mut wire_uint_8_list,
network: i32,
payment_timeout_sec: u32,
payment_request_yield_sec: u64,
default_lsp_id: *mut wire_uint_8_list,
api_key: *mut wire_uint_8_list,
maxfee_percent: f64,
Expand Down Expand Up @@ -1392,6 +1391,7 @@ pub struct wire_SendPaymentRequest {
bolt11: *mut wire_uint_8_list,
amount_msat: *mut u64,
label: *mut wire_uint_8_list,
pending_timeout_sec: *mut u64,
}

#[repr(C)]
Expand Down Expand Up @@ -1517,7 +1517,6 @@ impl NewWithNullPtr for wire_Config {
working_dir: core::ptr::null_mut(),
network: Default::default(),
payment_timeout_sec: Default::default(),
payment_request_yield_sec: Default::default(),
default_lsp_id: core::ptr::null_mut(),
api_key: core::ptr::null_mut(),
maxfee_percent: Default::default(),
Expand Down Expand Up @@ -2000,6 +1999,7 @@ impl NewWithNullPtr for wire_SendPaymentRequest {
bolt11: core::ptr::null_mut(),
amount_msat: core::ptr::null_mut(),
label: core::ptr::null_mut(),
pending_timeout_sec: core::ptr::null_mut(),
}
}
}
Expand Down
1 change: 0 additions & 1 deletion libs/sdk-core/src/bridge_generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1206,7 +1206,6 @@ impl support::IntoDart for Config {
self.working_dir.into_into_dart().into_dart(),
self.network.into_into_dart().into_dart(),
self.payment_timeout_sec.into_into_dart().into_dart(),
self.payment_request_yield_sec.into_into_dart().into_dart(),
self.default_lsp_id.into_dart(),
self.api_key.into_dart(),
self.maxfee_percent.into_into_dart().into_dart(),
Expand Down
10 changes: 4 additions & 6 deletions libs/sdk-core/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,9 +478,6 @@ pub struct Config {
pub network: Network,
/// Maps to the CLN `retry_for` config when paying invoices (`lightning-pay`)
pub payment_timeout_sec: u32,
/// The duration, in seconds, in which to return from a [crate::BreezServices::send_payment]
/// request with a pending payment if not already finished.
pub payment_request_yield_sec: u64,
pub default_lsp_id: Option<String>,
pub api_key: Option<String>,
/// Maps to the CLN `maxfeepercent` config when paying invoices (`lightning-pay`)
Expand All @@ -502,7 +499,6 @@ impl Config {
working_dir: ".".to_string(),
network: Bitcoin,
payment_timeout_sec: 60,
payment_request_yield_sec: 30,
default_lsp_id: None,
api_key: Some(api_key),
maxfee_percent: 1.0,
Expand All @@ -519,7 +515,6 @@ impl Config {
working_dir: ".".to_string(),
network: Bitcoin,
payment_timeout_sec: 60,
payment_request_yield_sec: 30,
default_lsp_id: None,
api_key: Some(api_key),
maxfee_percent: 0.5,
Expand Down Expand Up @@ -877,14 +872,17 @@ pub struct ReceivePaymentResponse {
}

/// Represents a send payment request.
#[derive(Clone, Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct SendPaymentRequest {
/// The bolt11 invoice
pub bolt11: String,
/// The amount to pay in millisatoshis. Should only be set when `bolt11` is a zero-amount invoice.
pub amount_msat: Option<u64>,
/// The external label or identifier of the [Payment]
pub label: Option<String>,
/// If set, a timeout in seconds, that [crate::BreezServices::send_payment] will return a
/// pending payment if not already finished.
pub pending_timeout_sec: Option<u64>,
}

/// Represents a TLV entry for a keysend payment.
Expand Down
2 changes: 1 addition & 1 deletion libs/sdk-flutter/ios/Classes/bridge_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ typedef struct wire_Config {
struct wire_uint_8_list *working_dir;
int32_t network;
uint32_t payment_timeout_sec;
uint64_t payment_request_yield_sec;
struct wire_uint_8_list *default_lsp_id;
struct wire_uint_8_list *api_key;
double maxfee_percent;
Expand Down Expand Up @@ -113,6 +112,7 @@ typedef struct wire_SendPaymentRequest {
struct wire_uint_8_list *bolt11;
uint64_t *amount_msat;
struct wire_uint_8_list *label;
uint64_t *pending_timeout_sec;
} wire_SendPaymentRequest;

typedef struct wire_TlvEntry {
Expand Down
30 changes: 14 additions & 16 deletions libs/sdk-flutter/lib/bridge_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -528,10 +528,6 @@ class Config {

/// Maps to the CLN `retry_for` config when paying invoices (`lightning-pay`)
final int paymentTimeoutSec;

/// The duration, in seconds, in which to return from a [crate::BreezServices::send_payment]
/// request with a pending payment if not already finished.
final int paymentRequestYieldSec;
final String? defaultLspId;
final String? apiKey;

Expand All @@ -549,7 +545,6 @@ class Config {
required this.workingDir,
required this.network,
required this.paymentTimeoutSec,
required this.paymentRequestYieldSec,
this.defaultLspId,
this.apiKey,
required this.maxfeePercent,
Expand Down Expand Up @@ -1806,10 +1801,15 @@ class SendPaymentRequest {
/// The external label or identifier of the [Payment]
final String? label;

/// If set, a timeout in seconds, that [crate::BreezServices::send_payment] will return a
/// pending payment if not already finished.
final int? pendingTimeoutSec;

const SendPaymentRequest({
required this.bolt11,
this.amountMsat,
this.label,
this.pendingTimeoutSec,
});
}

Expand Down Expand Up @@ -3387,20 +3387,19 @@ class BreezSdkCoreImpl implements BreezSdkCore {

Config _wire2api_config(dynamic raw) {
final arr = raw as List<dynamic>;
if (arr.length != 12) throw Exception('unexpected arr length: expect 12 but see ${arr.length}');
if (arr.length != 11) throw Exception('unexpected arr length: expect 11 but see ${arr.length}');
return Config(
breezserver: _wire2api_String(arr[0]),
chainnotifierUrl: _wire2api_String(arr[1]),
mempoolspaceUrl: _wire2api_opt_String(arr[2]),
workingDir: _wire2api_String(arr[3]),
network: _wire2api_network(arr[4]),
paymentTimeoutSec: _wire2api_u32(arr[5]),
paymentRequestYieldSec: _wire2api_u64(arr[6]),
defaultLspId: _wire2api_opt_String(arr[7]),
apiKey: _wire2api_opt_String(arr[8]),
maxfeePercent: _wire2api_f64(arr[9]),
exemptfeeMsat: _wire2api_u64(arr[10]),
nodeConfig: _wire2api_node_config(arr[11]),
defaultLspId: _wire2api_opt_String(arr[6]),
apiKey: _wire2api_opt_String(arr[7]),
maxfeePercent: _wire2api_f64(arr[8]),
exemptfeeMsat: _wire2api_u64(arr[9]),
nodeConfig: _wire2api_node_config(arr[10]),
);
}

Expand Down Expand Up @@ -4847,7 +4846,6 @@ class BreezSdkCorePlatform extends FlutterRustBridgeBase<BreezSdkCoreWire> {
wireObj.working_dir = api2wire_String(apiObj.workingDir);
wireObj.network = api2wire_network(apiObj.network);
wireObj.payment_timeout_sec = api2wire_u32(apiObj.paymentTimeoutSec);
wireObj.payment_request_yield_sec = api2wire_u64(apiObj.paymentRequestYieldSec);
wireObj.default_lsp_id = api2wire_opt_String(apiObj.defaultLspId);
wireObj.api_key = api2wire_opt_String(apiObj.apiKey);
wireObj.maxfee_percent = api2wire_f64(apiObj.maxfeePercent);
Expand Down Expand Up @@ -5059,6 +5057,7 @@ class BreezSdkCorePlatform extends FlutterRustBridgeBase<BreezSdkCoreWire> {
wireObj.bolt11 = api2wire_String(apiObj.bolt11);
wireObj.amount_msat = api2wire_opt_box_autoadd_u64(apiObj.amountMsat);
wireObj.label = api2wire_opt_String(apiObj.label);
wireObj.pending_timeout_sec = api2wire_opt_box_autoadd_u64(apiObj.pendingTimeoutSec);
}

void _api_fill_to_wire_send_spontaneous_payment_request(
Expand Down Expand Up @@ -6522,9 +6521,6 @@ final class wire_Config extends ffi.Struct {
@ffi.Uint32()
external int payment_timeout_sec;

@ffi.Uint64()
external int payment_request_yield_sec;

external ffi.Pointer<wire_uint_8_list> default_lsp_id;

external ffi.Pointer<wire_uint_8_list> api_key;
Expand Down Expand Up @@ -6608,6 +6604,8 @@ final class wire_SendPaymentRequest extends ffi.Struct {
external ffi.Pointer<ffi.Uint64> amount_msat;

external ffi.Pointer<wire_uint_8_list> label;

external ffi.Pointer<ffi.Uint64> pending_timeout_sec;
}

final class wire_TlvEntry extends ffi.Struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,6 @@ fun asConfig(config: ReadableMap): Config? {
"workingDir",
"network",
"paymentTimeoutSec",
"paymentRequestYieldSec",
"maxfeePercent",
"exemptfeeMsat",
"nodeConfig",
Expand All @@ -400,7 +399,6 @@ fun asConfig(config: ReadableMap): Config? {
val workingDir = config.getString("workingDir")!!
val network = config.getString("network")?.let { asNetwork(it) }!!
val paymentTimeoutSec = config.getInt("paymentTimeoutSec").toUInt()
val paymentRequestYieldSec = config.getDouble("paymentRequestYieldSec").toULong()
val defaultLspId = if (hasNonNullKey(config, "defaultLspId")) config.getString("defaultLspId") else null
val apiKey = if (hasNonNullKey(config, "apiKey")) config.getString("apiKey") else null
val maxfeePercent = config.getDouble("maxfeePercent")
Expand All @@ -413,7 +411,6 @@ fun asConfig(config: ReadableMap): Config? {
workingDir,
network,
paymentTimeoutSec,
paymentRequestYieldSec,
defaultLspId,
apiKey,
maxfeePercent,
Expand All @@ -430,7 +427,6 @@ fun readableMapOf(config: Config): ReadableMap {
"workingDir" to config.workingDir,
"network" to config.network.name.lowercase(),
"paymentTimeoutSec" to config.paymentTimeoutSec,
"paymentRequestYieldSec" to config.paymentRequestYieldSec,
"defaultLspId" to config.defaultLspId,
"apiKey" to config.apiKey,
"maxfeePercent" to config.maxfeePercent,
Expand Down Expand Up @@ -3232,10 +3228,21 @@ fun asSendPaymentRequest(sendPaymentRequest: ReadableMap): SendPaymentRequest? {
val bolt11 = sendPaymentRequest.getString("bolt11")!!
val amountMsat = if (hasNonNullKey(sendPaymentRequest, "amountMsat")) sendPaymentRequest.getDouble("amountMsat").toULong() else null
val label = if (hasNonNullKey(sendPaymentRequest, "label")) sendPaymentRequest.getString("label") else null
val pendingTimeoutSec =
if (hasNonNullKey(
sendPaymentRequest,
"pendingTimeoutSec",
)
) {
sendPaymentRequest.getDouble("pendingTimeoutSec").toULong()
} else {
null
}
return SendPaymentRequest(
bolt11,
amountMsat,
label,
pendingTimeoutSec,
)
}

Expand All @@ -3244,6 +3251,7 @@ fun readableMapOf(sendPaymentRequest: SendPaymentRequest): ReadableMap {
"bolt11" to sendPaymentRequest.bolt11,
"amountMsat" to sendPaymentRequest.amountMsat,
"label" to sendPaymentRequest.label,
"pendingTimeoutSec" to sendPaymentRequest.pendingTimeoutSec,
)
}

Expand Down
Loading

0 comments on commit c6dd7b8

Please sign in to comment.