RPC Method handler for `lsps-jitchannel`. Calls lsps2.get_info, selects parameters, calculates fee, calls lsps2.buy, creates invoice.
(
p: cln_plugin::Plugin<State>,
v: serde_json::Value,
)
| 301 | /// Calls lsps2.get_info, selects parameters, calculates fee, calls lsps2.buy, |
| 302 | /// creates invoice. |
| 303 | async fn on_lsps_lsps2_invoice( |
| 304 | p: cln_plugin::Plugin<State>, |
| 305 | v: serde_json::Value, |
| 306 | ) -> Result<serde_json::Value, anyhow::Error> { |
| 307 | #[derive(Deserialize)] |
| 308 | struct Request { |
| 309 | lsp_id: String, |
| 310 | // Optional: for discounts/API keys |
| 311 | token: Option<String>, |
| 312 | // Pass-through of cln invoice rpc params |
| 313 | pub amount_msat: cln_rpc::primitives::AmountOrAny, |
| 314 | pub description: String, |
| 315 | pub label: String, |
| 316 | } |
| 317 | |
| 318 | let req: Request = serde_json::from_value(v).context("Failed to parse request JSON")?; |
| 319 | debug!( |
| 320 | "Handling lsps-buy-jit-channel request for peer {} with payment_size {:?} and token {:?}", |
| 321 | req.lsp_id, req.amount_msat, req.token |
| 322 | ); |
| 323 | |
| 324 | let dir = p.configuration().lightning_dir; |
| 325 | let rpc_path = Path::new(&dir).join(&p.configuration().rpc_file); |
| 326 | let mut cln_client = cln_rpc::ClnRpc::new(rpc_path.clone()).await?; |
| 327 | |
| 328 | // 1. Get LSP's opening fee menu. |
| 329 | let info_res: Lsps2GetInfoResponse = cln_client |
| 330 | .call_raw( |
| 331 | "lsps-lsps2-getinfo", |
| 332 | &ClnRpcLsps2GetinfoRequest { |
| 333 | lsp_id: req.lsp_id.clone(), |
| 334 | token: req.token, |
| 335 | }, |
| 336 | ) |
| 337 | .await?; |
| 338 | |
| 339 | // 2. Select Fee Parameters. |
| 340 | // Simple strategy for now: choose the first valid option as LSPS2 requires |
| 341 | // this to be the cheapest. Could be more sophisticated (e.g., user choice). |
| 342 | let selected_params = info_res |
| 343 | .opening_fee_params_menu |
| 344 | .iter() |
| 345 | .find(|params| { |
| 346 | // Basic validation on client side: check expiry and promise length |
| 347 | let fut_now = Utc::now() + Duration::minutes(1); // Add some extra time for network delay |
| 348 | let expiry_valid = params.valid_until > fut_now; |
| 349 | if !expiry_valid { |
| 350 | warn!("Ignoring expired fee params from LSP {:?}", params); |
| 351 | } |
| 352 | expiry_valid |
| 353 | }) |
| 354 | .cloned() // Clone the selected params |
| 355 | .ok_or_else(|| { |
| 356 | anyhow!( |
| 357 | "No valid/unexpired fee parameters offered by LSP {}", |
| 358 | req.lsp_id |
| 359 | ) |
| 360 | })?; |
nothing calls this directly
no test coverage detected