lsp_plugin: pass-through invoice params

Calling lsps_jitchannel we want to pass through the label and
description parameters used to call `invoice` to keep the api close to
Core-Lightning

Signed-off-by: Peter Neuroth <pet.v.ne@gmail.com>
This commit is contained in:
Peter Neuroth
2025-09-29 16:39:41 +02:00
committed by Rusty Russell
parent e789b969ec
commit 366ada7853
2 changed files with 24 additions and 39 deletions

View File

@@ -167,19 +167,8 @@ async fn on_lsps_lsps2_buy(
.context("Failed to create Bolt8Transport")?;
let client = JsonRpcClient::new(transport);
// Convert from AmountOrAny to Msat.
let payment_size_msat = if let Some(payment_size) = req.payment_size_msat {
match payment_size {
AmountOrAny::Amount(amount) => Some(Msat::from_msat(amount.msat())),
AmountOrAny::Any => None,
}
} else {
None
};
let selected_params = req.opening_fee_params;
if let Some(payment_size) = payment_size_msat {
if let Some(payment_size) = req.payment_size_msat {
if payment_size < selected_params.min_payment_size_msat {
return Err(anyhow!(
"Requested payment size {}msat is below minimum {}msat required by LSP",
@@ -224,7 +213,7 @@ async fn on_lsps_lsps2_buy(
debug!("Calling lsps2.buy for peer {}", req.lsp_id);
let buy_req = Lsps2BuyRequest {
opening_fee_params: selected_params, // Pass the chosen params back
payment_size_msat,
payment_size_msat: req.payment_size_msat,
};
let buy_res: Lsps2BuyResponse = client
.call_typed(buy_req)
@@ -270,16 +259,18 @@ async fn on_lsps_jitchannel(
#[derive(Deserialize)]
struct Request {
lsp_id: String,
// Optional: for fixed-amount invoices
payment_size_msat: Option<AmountOrAny>,
// Optional: for discounts/API keys
token: Option<String>,
// Pass-through of cln invoice rpc params
pub amount_msat: cln_rpc::primitives::AmountOrAny,
pub description: String,
pub label: String,
}
let req: Request = serde_json::from_value(v).context("Failed to parse request JSON")?;
debug!(
"Handling lsps-buy-jit-channel request for peer {} with payment_size {:?} and token {:?}",
req.lsp_id, req.payment_size_msat, req.token
req.lsp_id, req.amount_msat, req.token
);
let dir = p.configuration().lightning_dir;
@@ -322,13 +313,18 @@ async fn on_lsps_jitchannel(
info!("Selected fee parameters: {:?}", selected_params);
let payment_size_msat = match req.amount_msat {
AmountOrAny::Amount(amount) => Some(Msat::from_msat(amount.msat())),
AmountOrAny::Any => None,
};
// 3. Request channel from LSP.
let buy_res: Lsps2BuyResponse = cln_client
.call_raw(
"lsps-lsps2-buy",
&ClnRpcLsps2BuyRequest {
lsp_id: req.lsp_id.clone(),
payment_size_msat: req.payment_size_msat,
payment_size_msat,
opening_fee_params: selected_params.clone(),
},
)
@@ -356,20 +352,14 @@ async fn on_lsps_jitchannel(
cltv_expiry_delta: u16::try_from(buy_res.lsp_cltv_expiry_delta)?,
};
let amount_msat = if let Some(payment_size) = req.payment_size_msat {
payment_size
} else {
AmountOrAny::Any
};
let inv: cln_rpc::model::responses::InvoiceResponse = cln_client
.call_raw(
"invoice",
&InvoiceRequest {
amount_msat,
amount_msat: req.amount_msat,
dev_routes: Some(vec![vec![hint]]),
description: String::from("TODO"), // TODO: Pass down description from rpc call
label: gen_label(None), // TODO: Pass down label from rpc call
description: req.description,
label: req.label,
expiry: Some(expiry as u64),
cltv: Some(u32::try_from(6 + 2)?), // TODO: FETCH REAL VALUE!
deschashonly: None,
@@ -619,15 +609,6 @@ async fn ensure_lsp_connected(cln_client: &mut ClnRpc, lsp_id: &str) -> Result<(
Ok(())
}
/// Generates a unique label from an optional `String`. The given label is
/// appended by a timestamp (now).
fn gen_label(label: Option<&str>) -> String {
let now = Utc::now();
let millis = now.timestamp_millis();
let l = label.unwrap_or_else(|| "lsps2.buy");
format!("{}_{}", l, millis)
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
struct LspsBuyJitChannelResponse {
bolt11: String,
@@ -668,8 +649,7 @@ pub struct RoutehintHopDev {
#[derive(Debug, Clone, Serialize, Deserialize)]
struct ClnRpcLsps2BuyRequest {
lsp_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
payment_size_msat: Option<AmountOrAny>,
payment_size_msat: Option<Msat>,
opening_fee_params: OpeningFeeParams,
}

View File

@@ -86,7 +86,7 @@ def test_lsps2_buy(node_factory):
res = l1.rpc.lsps_lsps2_getinfo(lsp_id=l2.info['id'])
params = res["opening_fee_params_menu"][0]
res = l1.rpc.lsps_lsps2_buy(lsp_id=l2.info['id'], payment_size_msat=None, opening_fee_params=params)
res = l1.rpc.lsps_lsps2_buy(lsp_id=l2.info['id'], opening_fee_params=params)
assert res
@@ -133,7 +133,12 @@ def test_lsps2_buyjitchannel_no_mpp_var_invoice(node_factory, bitcoind):
chanid = only_one(l3.rpc.listpeerchannels(l2.info['id'])['channels'])['short_channel_id']
inv = l1.rpc.lsps_jitchannel(lsp_id=l2.info['id'])
inv = l1.rpc.lsps_jitchannel(
lsp_id=l2.info['id'],
amount_msat="any",
description="lsp-jit-channel-0",
label="lsp-jit-channel-0"
)
assert inv
dec = l3.rpc.decode(inv['bolt11'])